288 lines
5.5 KiB
C
Executable File
288 lines
5.5 KiB
C
Executable File
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
|
/* All Rights Reserved */
|
|
|
|
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
|
/* The copyright notice above does not evidence any */
|
|
/* actual or intended publication of such source code. */
|
|
|
|
#ident "@(#)cmd4.c 1.24 95/07/19 SMI" /* from SVr4.0 1.4.2.1 */
|
|
|
|
#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);
|
|
}
|