/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1995 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
* The Regents of the University of California
* All Rights Reserved
*
* University Acknowledgment- Portions of this document are derived from
* software developed by the University of California, Berkeley, and its
* contributors.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "rcv.h"
#include <locale.h>
/*
* mailx -- a modified version of a University of California at Berkeley
* mail program
*
* More commands..
*/
static char *stripquotes(char *str);
/*
* pipe messages to cmd.
*/
int
dopipe(char str[])
{
register int *ip, mesg;
register struct message *mp;
char *cp, *cmd;
int f, *msgvec, nowait=0;
void (*sigint)(int), (*sigpipe)(int);
long lc, cc, t;
register pid_t pid;
int page, s, pivec[2];
char *Shell;
FILE *pio = NULL;
extern jmp_buf pipestop;
extern void brokpipe(int);
msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
if ((cmd = stripquotes(snarf(str, &f, 0))) == NOSTR) {
if (f == -1) {
printf(gettext("pipe command error\n"));
return(1);
}
if ( (cmd = value("cmd")) == NOSTR) {
printf(gettext("\"cmd\" not set, ignored.\n"));
return(1);
}
}
if (!f) {
*msgvec = first(0, MMNORM);
if (*msgvec == NULL) {
printf(gettext("No messages to pipe.\n"));
return(1);
}
msgvec[1] = NULL;
}
if (f && getmsglist(str, msgvec, 0) < 0)
return(1);
if (*(cp=cmd+strlen(cmd)-1)=='&') {
*cp=0;
nowait++;
}
printf(gettext("Pipe to: \"%s\"\n"), cmd);
flush();
if (setjmp(pipestop))
goto err;
/* setup pipe */
if (pipe(pivec) < 0) {
perror("pipe");
return(0);
}
if ((pid = vfork()) == 0) {
close(pivec[1]); /* child */
close(0);
dup(pivec[0]);
close(pivec[0]);
if ((Shell = value("SHELL")) == NOSTR || *Shell=='\0')
Shell = SHELL;
execlp(Shell, Shell, "-c", cmd, 0);
perror(Shell);
_exit(1);
}
if (pid == (pid_t)-1) { /* error */
perror("fork");
close(pivec[0]);
close(pivec[1]);
return(0);
}
close(pivec[0]); /* parent */
pio=fdopen(pivec[1],"w");
sigint = sigset(SIGINT, SIG_IGN);
sigpipe = sigset(SIGPIPE, brokpipe);
/* send all messages to cmd */
page = (value("page")!=NOSTR);
lc = cc = 0;
for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
mesg = *ip;
touch(mesg);
mp = &message[mesg-1];
dot = mp;
if ((t = msend(mp, pio,
(value("alwaysignore") != NOSTR ||
value("pipeignore") != NOSTR)
? M_IGNORE : 0, fputs)) < 0) {
perror(cmd);
sigset(SIGPIPE, sigpipe);
sigset(SIGINT, sigint);
fclose(pio);
return(1);
}
lc += t;
cc += mp->m_size;
if (page) putc('\f', pio);
}
fflush(pio);
if (ferror(pio))
perror(cmd);
fclose(pio);
pio = NULL;
/* wait */
if (!nowait) {
while (wait(&s) != pid);
s &= 0377;
if (s != 0)
goto err;
}
printf("\"%s\" %ld/%ld\n", cmd, lc, cc);
sigset(SIGPIPE, sigpipe);
sigset(SIGINT, sigint);
return(0);
err:
printf(gettext("Pipe to \"%s\" failed\n"), cmd);
if (pio)
fclose(pio);
sigset(SIGPIPE, sigpipe);
sigset(SIGINT, sigint);
return(0);
}
/*
* Load the named message from the named file.
*/
int
loadmsg(char str[])
{
char *file;
int f, *msgvec;
register int c, lastc = '\n';
int blank;
int lines;
long ms;
FILE *ibuf;
struct message *mp;
off_t size;
msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
if ((file = snarf(str, &f, 1)) == NOSTR)
return(1);
if (f==-1)
return(1);
if (!f) {
*msgvec = first(0, MMNORM);
if (*msgvec == NULL) {
printf(gettext("No message to load into.\n"));
return(1);
}
msgvec[1] = NULL;
}
if (f && getmsglist(str, msgvec, 0) < 0)
return(1);
if (msgvec[1] != NULL) {
printf(gettext("Can only load into a single message.\n"));
return(1);
}
if ((file = expand(file)) == NOSTR)
return(1);
printf("\"%s\" ", file);
fflush(stdout);
if ((ibuf = fopen(file, "r")) == NULL) {
perror("");
return(1);
}
mp = &message[*msgvec-1];
dot = mp;
mp->m_flag |= MODIFY;
mp->m_flag &= ~MSAVED; /* should probably turn off more */
fseek(otf, (long) 0, 2);
size = fsize(otf);
mp->m_offset = size;
ms = 0L;
lines = 0;
while ((c = getc(ibuf)) != EOF) {
if (c == '\n') {
lines++;
blank = lastc == '\n';
}
lastc = c;
putc(c, otf);
if (ferror(otf))
break;
ms++;
}
if (!blank) {
putc('\n', otf);
ms++;
lines++;
}
mp->m_size = ms;
mp->m_lines = lines;
if (fferror(otf))
perror("/tmp");
fclose(ibuf);
setclen(mp);
printf(gettext("[Loaded] %d/%ld\n"), lines, ms);
return(0);
}
/*
* Display the named field.
*/
int
field(char str[])
{
register int *ip;
register struct message *mp;
register char *cp, *fld;
int f, *msgvec;
msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
if ((fld = stripquotes(snarf(str, &f, 0))) == NOSTR) {
if (f == -1)
printf(gettext("Bad field\n"));
else
printf(gettext("No field specified\n"));
return(1);
}
if (!f) {
*msgvec = first(0, MMNORM);
if (*msgvec == NULL) {
printf(gettext("No messages to display.\n"));
return(1);
}
msgvec[1] = NULL;
}
if (f && getmsglist(str, msgvec, 0) < 0)
return(1);
for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
mp = &message[*ip - 1];
dot = mp;
if ((cp = hfield(fld, mp, addone)) != NULL)
printf("%s\n", cp);
}
return(0);
}
/*
* Remove the quotes from around the string passed in (if any). Return
* the beginning of the result.
*/
static char *
stripquotes(char *str)
{
register int lastch;
if (str == NOSTR) {
return(NOSTR);
}
lastch = strlen(str)-1;
if (any(*str, "\"'") && str[lastch] == *str) {
str[lastch] = '\0';
++str;
}
return(str);
}