written by Kurt Shoens; added Berkeley specific header
[unix-history] / usr / src / usr.bin / mail / cmd3.c
index 674dfdb..51a4973 100644 (file)
@@ -1,7 +1,22 @@
-#
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#ifdef notdef
+static char sccsid[] = "@(#)cmd3.c     5.5 (Berkeley) %G%";
+#endif /* notdef */
 
 #include "rcv.h"
 #include <sys/stat.h>
 
 #include "rcv.h"
 #include <sys/stat.h>
+#include <sys/wait.h>
 
 /*
  * Mail -- a mail program
 
 /*
  * Mail -- a mail program
@@ -9,8 +24,6 @@
  * Still more user commands.
  */
 
  * Still more user commands.
  */
 
-static char *SccsId = "@(#)cmd3.c      2.3 %G%";
-
 /*
  * Process a shell escape by saving signals, ignoring signals,
  * and forking a sh -c
 /*
  * Process a shell escape by saving signals, ignoring signals,
  * and forking a sh -c
@@ -19,7 +32,8 @@ static char *SccsId = "@(#)cmd3.c     2.3 %G%";
 shell(str)
        char *str;
 {
 shell(str)
        char *str;
 {
-       int (*sig[2])(), stat[1];
+       int (*sigint)(), (*sigquit)();
+       union wait stat;
        register int t;
        char *Shell;
        char cmd[BUFSIZ];
        register int t;
        char *Shell;
        char cmd[BUFSIZ];
@@ -29,23 +43,24 @@ shell(str)
                return(-1);
        if ((Shell = value("SHELL")) == NOSTR)
                Shell = SHELL;
                return(-1);
        if ((Shell = value("SHELL")) == NOSTR)
                Shell = SHELL;
-       for (t = 2; t < 4; t++)
-               sig[t-2] = sigset(t, SIG_IGN);
+       sigint = signal(SIGINT, SIG_IGN);
+       sigquit = signal(SIGQUIT, SIG_IGN);
        t = vfork();
        if (t == 0) {
        t = vfork();
        if (t == 0) {
-               for (t = 2; t < 4; t++)
-                       if (sig[t-2] != SIG_IGN)
-                               sigsys(t, SIG_DFL);
-               execl(Shell, Shell, "-c", cmd, 0);
+               if (sigint != SIG_IGN)
+                       signal(SIGINT, SIG_DFL);
+               if (sigquit != SIG_IGN)
+                       signal(SIGQUIT, SIG_DFL);
+               execl(Shell, Shell, "-c", cmd, (char *)0);
                perror(Shell);
                _exit(1);
        }
                perror(Shell);
                _exit(1);
        }
-       while (wait(stat) != t)
+       while (wait(&stat) != t)
                ;
        if (t == -1)
                perror("fork");
                ;
        if (t == -1)
                perror("fork");
-       for (t = 2; t < 4; t++)
-               sigset(t, sig[t-2]);
+       signal(SIGINT, sigint);
+       signal(SIGQUIT, sigquit);
        printf("!\n");
        return(0);
 }
        printf("!\n");
        return(0);
 }
@@ -54,31 +69,35 @@ shell(str)
  * Fork an interactive shell.
  */
 
  * Fork an interactive shell.
  */
 
+/*ARGSUSED*/
 dosh(str)
        char *str;
 {
 dosh(str)
        char *str;
 {
-       int (*sig[2])(), stat[1];
+       int (*sigint)(), (*sigquit)();
+       union wait stat;
        register int t;
        char *Shell;
        register int t;
        char *Shell;
+
        if ((Shell = value("SHELL")) == NOSTR)
                Shell = SHELL;
        if ((Shell = value("SHELL")) == NOSTR)
                Shell = SHELL;
-       for (t = 2; t < 4; t++)
-               sig[t-2] = sigset(t, SIG_IGN);
+       sigint = signal(SIGINT, SIG_IGN);
+       sigquit = signal(SIGQUIT, SIG_IGN);
        t = vfork();
        if (t == 0) {
        t = vfork();
        if (t == 0) {
-               for (t = 2; t < 4; t++)
-                       if (sig[t-2] != SIG_IGN)
-                               sigsys(t, SIG_DFL);
-               execl(Shell, Shell, 0);
+               if (sigint != SIG_IGN)
+                       signal(SIGINT, SIG_DFL);
+               if (sigquit != SIG_IGN)
+                       signal(SIGQUIT, SIG_DFL);
+               execl(Shell, Shell, (char *)0);
                perror(Shell);
                _exit(1);
        }
                perror(Shell);
                _exit(1);
        }
-       while (wait(stat) != t)
+       while (wait(&stat) != t)
                ;
        if (t == -1)
                perror("fork");
                ;
        if (t == -1)
                perror("fork");
-       for (t = 2; t < 4; t++)
-               sigsys(t, sig[t-2]);
+       signal(SIGINT, sigint);
+       signal(SIGQUIT, sigquit);
        putchar('\n');
        return(0);
 }
        putchar('\n');
        return(0);
 }
@@ -147,7 +166,7 @@ help()
        register FILE *f;
 
        if ((f = fopen(HELPFILE, "r")) == NULL) {
        register FILE *f;
 
        if ((f = fopen(HELPFILE, "r")) == NULL) {
-               printf("No help just now.\n");
+               perror(HELPFILE);
                return(1);
        }
        while ((c = getc(f)) != EOF)
                return(1);
        }
        while ((c = getc(f)) != EOF)
@@ -179,19 +198,28 @@ schdir(str)
        return(0);
 }
 
        return(0);
 }
 
+respond(msgvec)
+       int *msgvec;
+{
+       if (value("Replyall") == NOSTR)
+               return (_respond(msgvec));
+       else
+               return (_Respond(msgvec));
+}
+
 /*
  * Reply to a list of messages.  Extract each name from the
  * message header and send them off to mail1()
  */
 
 /*
  * Reply to a list of messages.  Extract each name from the
  * message header and send them off to mail1()
  */
 
-respond(msgvec)
+_respond(msgvec)
        int *msgvec;
 {
        struct message *mp;
        int *msgvec;
 {
        struct message *mp;
-       char *cp, buf[2 * LINESIZE], *rcv, *replyto, **ap;
+       char *cp, *rcv, *replyto;
+       char buf[2 * LINESIZE], **ap;
        struct name *np;
        struct header head;
        struct name *np;
        struct header head;
-       char *netmap();
 
        if (msgvec[1] != 0) {
                printf("Sorry, can't reply to multiple messages at once\n");
 
        if (msgvec[1] != 0) {
                printf("Sorry, can't reply to multiple messages at once\n");
@@ -199,27 +227,32 @@ respond(msgvec)
        }
        mp = &message[msgvec[0] - 1];
        dot = mp;
        }
        mp = &message[msgvec[0] - 1];
        dot = mp;
-       rcv = nameof(mp, 1);
+       rcv = NOSTR;
+       cp = skin(nameof(mp, 1));
+       if (cp != NOSTR)
+           rcv = cp;
+       cp = skin(hfield("from", mp));
+       if (cp != NOSTR)
+           rcv = cp;
        replyto = skin(hfield("reply-to", mp));
        strcpy(buf, "");
        if (replyto != NOSTR)
                strcpy(buf, replyto);
        else {
        replyto = skin(hfield("reply-to", mp));
        strcpy(buf, "");
        if (replyto != NOSTR)
                strcpy(buf, replyto);
        else {
-               cp = hfield("to", mp);
+               cp = skin(hfield("to", mp));
                if (cp != NOSTR)
                        strcpy(buf, cp);
        }
        np = elide(extract(buf, GTO));
                if (cp != NOSTR)
                        strcpy(buf, cp);
        }
        np = elide(extract(buf, GTO));
-       /* rcv = rename(rcv); */
        mapf(np, rcv);
        /*
         * Delete my name from the reply list,
         * and with it, all my alternate names.
         */
        mapf(np, rcv);
        /*
         * Delete my name from the reply list,
         * and with it, all my alternate names.
         */
-       np = delname(np, myname);
-       if (altnames != 0)
+       np = delname(np, myname, icequal);
+       if (altnames)
                for (ap = altnames; *ap; ap++)
                for (ap = altnames; *ap; ap++)
-                       np = delname(np, *ap);
+                       np = delname(np, *ap, icequal);
        head.h_seq = 1;
        cp = detract(np, 0);
        if (cp != NOSTR && replyto == NOSTR) {
        head.h_seq = 1;
        cp = detract(np, 0);
        if (cp != NOSTR && replyto == NOSTR) {
@@ -242,14 +275,14 @@ respond(msgvec)
        head.h_subject = reedit(head.h_subject);
        head.h_cc = NOSTR;
        if (replyto == NOSTR) {
        head.h_subject = reedit(head.h_subject);
        head.h_cc = NOSTR;
        if (replyto == NOSTR) {
-               cp = hfield("cc", mp);
+               cp = skin(hfield("cc", mp));
                if (cp != NOSTR) {
                        np = elide(extract(cp, GCC));
                        mapf(np, rcv);
                if (cp != NOSTR) {
                        np = elide(extract(cp, GCC));
                        mapf(np, rcv);
-                       np = delname(np, myname);
+                       np = delname(np, myname, icequal);
                        if (altnames != 0)
                                for (ap = altnames; *ap; ap++)
                        if (altnames != 0)
                                for (ap = altnames; *ap; ap++)
-                                       np = delname(np, *ap);
+                                       np = delname(np, *ap, icequal);
                        head.h_cc = detract(np, 0);
                }
        }
                        head.h_cc = detract(np, 0);
                }
        }
@@ -277,7 +310,7 @@ reedit(subj)
        if (icequal(sbuf, "re:"))
                return(subj);
        newsubj = salloc(strlen(subj) + 6);
        if (icequal(sbuf, "re:"))
                return(subj);
        newsubj = salloc(strlen(subj) + 6);
-       sprintf(newsubj, "Re:  %s", subj);
+       sprintf(newsubj, "Re: %s", subj);
        return(newsubj);
 }
 
        return(newsubj);
 }
 
@@ -306,6 +339,22 @@ preserve(msgvec)
        return(0);
 }
 
        return(0);
 }
 
+/*
+ * Mark all given messages as unread.
+ */
+unread(msgvec)
+       int     msgvec[];
+{
+       register int *ip;
+
+       for (ip = msgvec; *ip != NULL; ip++) {
+               dot = &message[*ip-1];
+               dot->m_flag &= ~(MREAD|MTOUCH);
+               dot->m_flag |= MSTATUS;
+       }
+       return(0);
+}
+
 /*
  * Print the size of each message.
  */
 /*
  * Print the size of each message.
  */
@@ -319,7 +368,7 @@ messize(msgvec)
        for (ip = msgvec; *ip != NULL; ip++) {
                mesg = *ip;
                mp = &message[mesg-1];
        for (ip = msgvec; *ip != NULL; ip++) {
                mesg = *ip;
                mp = &message[mesg-1];
-               printf("%d: %d\n", mesg, msize(mp));
+               printf("%d: %d/%ld\n", mesg, mp->m_lines, mp->m_size);
        }
        return(0);
 }
        }
        return(0);
 }
@@ -333,7 +382,10 @@ rexit(e)
 {
        if (sourcing)
                return(1);
 {
        if (sourcing)
                return(1);
+       if (Tflag != NOSTR)
+               close(creat(Tflag, 0600));
        exit(e);
        exit(e);
+       /*NOTREACHED*/
 }
 
 /*
 }
 
 /*
@@ -392,7 +444,6 @@ unset(arglist)
        char **arglist;
 {
        register struct var *vp, *vp2;
        char **arglist;
 {
        register struct var *vp, *vp2;
-       register char *cp;
        int errs, h;
        char **ap;
 
        int errs, h;
        char **ap;
 
@@ -410,7 +461,7 @@ unset(arglist)
                        variables[h] = variables[h]->v_link;
                        vfree(vp2->v_name);
                        vfree(vp2->v_value);
                        variables[h] = variables[h]->v_link;
                        vfree(vp2->v_name);
                        vfree(vp2->v_value);
-                       cfree(vp2);
+                       cfree((char *)vp2);
                        continue;
                }
                for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
                        continue;
                }
                for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
@@ -418,7 +469,7 @@ unset(arglist)
                vp->v_link = vp2->v_link;
                vfree(vp2->v_name);
                vfree(vp2->v_value);
                vp->v_link = vp2->v_link;
                vfree(vp2->v_name);
                vfree(vp2->v_value);
-               cfree(vp2);
+               cfree((char *) vp2);
        }
        return(errs);
 }
        }
        return(errs);
 }
@@ -494,7 +545,7 @@ sort(list)
                ;
        if (ap-list < 2)
                return;
                ;
        if (ap-list < 2)
                return;
-       qsort(list, ap-list, sizeof *list, diction);
+       qsort((char *)list, ap-list, sizeof *list, diction);
 }
 
 /*
 }
 
 /*
@@ -512,9 +563,10 @@ diction(a, b)
  * The do nothing command for comments.
  */
 
  * The do nothing command for comments.
  */
 
+/*ARGSUSED*/
 null(e)
 {
 null(e)
 {
-       return(0);
+       return 0;
 }
 
 /*
 }
 
 /*
@@ -527,7 +579,7 @@ file(argv)
        char **argv;
 {
        register char *cp;
        char **argv;
 {
        register char *cp;
-       char fname[BUFSIZ];
+       int edit;
 
        if (argv[0] == NOSTR) {
                newfileinfo();
 
        if (argv[0] == NOSTR) {
                newfileinfo();
@@ -544,10 +596,15 @@ file(argv)
         *      string -- reads the given file
         */
 
         *      string -- reads the given file
         */
 
-       cp = getfilename(argv[0]);
+       cp = getfilename(argv[0], &edit);
        if (cp == NOSTR)
                return(-1);
        if (cp == NOSTR)
                return(-1);
-       return(setfile(cp, 1));
+       if (setfile(cp, edit)) {
+               perror(cp);
+               return(-1);
+       }
+       announce(0);
+       return 0;
 }
 
 /*
 }
 
 /*
@@ -564,15 +621,22 @@ file(argv)
 char   prevfile[PATHSIZE];
 
 char *
 char   prevfile[PATHSIZE];
 
 char *
-getfilename(name)
+getfilename(name, aedit)
        char *name;
        char *name;
+       int *aedit;
 {
        register char *cp;
        char savename[BUFSIZ];
        char oldmailname[BUFSIZ];
 
 {
        register char *cp;
        char savename[BUFSIZ];
        char oldmailname[BUFSIZ];
 
+       /*
+        * Assume we will be in "edit file" mode, until
+        * proven wrong.
+        */
+       *aedit = 1;
        switch (*name) {
        case '%':
        switch (*name) {
        case '%':
+               *aedit = 0;
                strcpy(prevfile, mailname);
                if (name[1] != 0) {
                        strcpy(savename, myname);
                strcpy(prevfile, mailname);
                if (name[1] != 0) {
                        strcpy(savename, myname);
@@ -634,24 +698,36 @@ echo(argv)
        return(0);
 }
 
        return(0);
 }
 
+Respond(msgvec)
+       int *msgvec;
+{
+       if (value("Replyall") == NOSTR)
+               return (_Respond(msgvec));
+       else
+               return (_respond(msgvec));
+}
+
 /*
  * Reply to a series of messages by simply mailing to the senders
  * and not messing around with the To: and Cc: lists as in normal
  * reply.
  */
 
 /*
  * Reply to a series of messages by simply mailing to the senders
  * and not messing around with the To: and Cc: lists as in normal
  * reply.
  */
 
-Respond(msgvec)
+_Respond(msgvec)
        int msgvec[];
 {
        struct header head;
        struct message *mp;
        register int s, *ap;
        int msgvec[];
 {
        struct header head;
        struct message *mp;
        register int s, *ap;
-       register char *cp, *subject;
+       register char *cp, *cp2, *subject;
 
        for (s = 0, ap = msgvec; *ap != 0; ap++) {
                mp = &message[*ap - 1];
                dot = mp;
 
        for (s = 0, ap = msgvec; *ap != 0; ap++) {
                mp = &message[*ap - 1];
                dot = mp;
-               s += strlen(nameof(mp, 2)) + 1;
+               if ((cp = skin(hfield("from", mp))) != NOSTR)
+                   s+= strlen(cp) + 1;
+               else
+                   s += strlen(skin(nameof(mp, 2))) + 1;
        }
        if (s == 0)
                return(0);
        }
        if (s == 0)
                return(0);
@@ -659,7 +735,9 @@ Respond(msgvec)
        head.h_to = cp;
        for (ap = msgvec; *ap != 0; ap++) {
                mp = &message[*ap - 1];
        head.h_to = cp;
        for (ap = msgvec; *ap != 0; ap++) {
                mp = &message[*ap - 1];
-               cp = copy(nameof(mp, 2), cp);
+               if ((cp2 = skin(hfield("from", mp))) == NOSTR)
+                   cp2 = skin(nameof(mp, 2));
+               cp = copy(cp2, cp);
                *cp++ = ' ';
        }
        *--cp = 0;
                *cp++ = ' ';
        }
        *--cp = 0;
@@ -773,9 +851,9 @@ alternates(namelist)
        }
        if (altnames != 0)
                cfree((char *) altnames);
        }
        if (altnames != 0)
                cfree((char *) altnames);
-       altnames = (char **) calloc(c, sizeof (char *));
+       altnames = (char **) calloc((unsigned) c, sizeof (char *));
        for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) {
        for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) {
-               cp = (char *) calloc(strlen(*ap) + 1, sizeof (char));
+               cp = (char *) calloc((unsigned) strlen(*ap) + 1, sizeof (char));
                strcpy(cp, *ap);
                *ap2 = cp;
        }
                strcpy(cp, *ap);
                *ap2 = cp;
        }