Modified delname() to use passed function to comapre name strings.
[unix-history] / usr / src / usr.bin / mail / cmd3.c
index 85b8cb3..3f1d112 100644 (file)
@@ -9,7 +9,7 @@
  * Still more user commands.
  */
 
  * Still more user commands.
  */
 
-static char *SccsId = "@(#)cmd3.c      1.3 %G%";
+static char *SccsId = "@(#)cmd3.c      2.9 %G%";
 
 /*
  * Process a shell escape by saving signals, ignoring signals,
 
 /*
  * Process a shell escape by saving signals, ignoring signals,
@@ -30,12 +30,13 @@ shell(str)
        if ((Shell = value("SHELL")) == NOSTR)
                Shell = SHELL;
        for (t = 2; t < 4; t++)
        if ((Shell = value("SHELL")) == NOSTR)
                Shell = SHELL;
        for (t = 2; t < 4; t++)
-               sig[t-2] = signal(t, SIG_IGN);
+               sig[t-2] = sigset(t, SIG_IGN);
        t = vfork();
        if (t == 0) {
        t = vfork();
        if (t == 0) {
+               sigchild();
                for (t = 2; t < 4; t++)
                        if (sig[t-2] != SIG_IGN)
                for (t = 2; t < 4; t++)
                        if (sig[t-2] != SIG_IGN)
-                               signal(t, SIG_DFL);
+                               sigsys(t, SIG_DFL);
                execl(Shell, Shell, "-c", cmd, 0);
                perror(Shell);
                _exit(1);
                execl(Shell, Shell, "-c", cmd, 0);
                perror(Shell);
                _exit(1);
@@ -45,7 +46,7 @@ shell(str)
        if (t == -1)
                perror("fork");
        for (t = 2; t < 4; t++)
        if (t == -1)
                perror("fork");
        for (t = 2; t < 4; t++)
-               signal(t, sig[t-2]);
+               sigset(t, sig[t-2]);
        printf("!\n");
        return(0);
 }
        printf("!\n");
        return(0);
 }
@@ -63,12 +64,13 @@ dosh(str)
        if ((Shell = value("SHELL")) == NOSTR)
                Shell = SHELL;
        for (t = 2; t < 4; t++)
        if ((Shell = value("SHELL")) == NOSTR)
                Shell = SHELL;
        for (t = 2; t < 4; t++)
-               sig[t-2] = signal(t, SIG_IGN);
+               sig[t-2] = sigset(t, SIG_IGN);
        t = vfork();
        if (t == 0) {
        t = vfork();
        if (t == 0) {
+               sigchild();
                for (t = 2; t < 4; t++)
                        if (sig[t-2] != SIG_IGN)
                for (t = 2; t < 4; t++)
                        if (sig[t-2] != SIG_IGN)
-                               signal(t, SIG_DFL);
+                               sigsys(t, SIG_DFL);
                execl(Shell, Shell, 0);
                perror(Shell);
                _exit(1);
                execl(Shell, Shell, 0);
                perror(Shell);
                _exit(1);
@@ -78,7 +80,7 @@ dosh(str)
        if (t == -1)
                perror("fork");
        for (t = 2; t < 4; t++)
        if (t == -1)
                perror("fork");
        for (t = 2; t < 4; t++)
-               signal(t, sig[t-2]);
+               sigsys(t, sig[t-2]);
        putchar('\n');
        return(0);
 }
        putchar('\n');
        return(0);
 }
@@ -188,7 +190,7 @@ respond(msgvec)
        int *msgvec;
 {
        struct message *mp;
        int *msgvec;
 {
        struct message *mp;
-       char *cp, buf[2 * LINESIZE], *rcv;
+       char *cp, buf[2 * LINESIZE], *rcv, *replyto, **ap;
        struct name *np;
        struct header head;
        char *netmap();
        struct name *np;
        struct header head;
        char *netmap();
@@ -199,41 +201,88 @@ respond(msgvec)
        }
        mp = &message[msgvec[0] - 1];
        dot = mp;
        }
        mp = &message[msgvec[0] - 1];
        dot = mp;
-       rcv = nameof(mp);
+       rcv = nameof(mp, 1);
+       replyto = skin(hfield("reply-to", mp));
        strcpy(buf, "");
        strcpy(buf, "");
-       cp = hfield("to", mp);
-       if (cp != NOSTR)
-               strcpy(buf, cp);
+       if (replyto != NOSTR)
+               strcpy(buf, replyto);
+       else {
+               cp = hfield("to", mp);
+               if (cp != NOSTR)
+                       strcpy(buf, cp);
+       }
        np = elide(extract(buf, GTO));
        /* rcv = rename(rcv); */
        mapf(np, rcv);
        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.
+        */
        np = delname(np, myname);
        np = delname(np, myname);
+       if (altnames != 0)
+               for (ap = altnames; *ap; ap++)
+                       np = delname(np, *ap);
        head.h_seq = 1;
        cp = detract(np, 0);
        head.h_seq = 1;
        cp = detract(np, 0);
-       if (cp != NOSTR) {
+       if (cp != NOSTR && replyto == NOSTR) {
                strcpy(buf, cp);
                strcat(buf, " ");
                strcat(buf, rcv);
        }
                strcpy(buf, cp);
                strcat(buf, " ");
                strcat(buf, rcv);
        }
-       else
-               strcpy(buf, rcv);
+       else {
+               if (cp == NOSTR && replyto != NOSTR)
+                       printf("Empty reply-to field -- replying to author\n");
+               if (cp == NOSTR)
+                       strcpy(buf, rcv);
+               else
+                       strcpy(buf, cp);
+       }
        head.h_to = buf;
        head.h_subject = hfield("subject", mp);
        if (head.h_subject == NOSTR)
                head.h_subject = hfield("subj", mp);
        head.h_to = buf;
        head.h_subject = hfield("subject", mp);
        if (head.h_subject == NOSTR)
                head.h_subject = hfield("subj", mp);
+       head.h_subject = reedit(head.h_subject);
        head.h_cc = NOSTR;
        head.h_cc = NOSTR;
-       cp = hfield("cc", mp);
-       if (cp != NOSTR) {
-               np = elide(extract(cp, GCC));
-               mapf(np, rcv);
-               np = delname(np, myname);
-               head.h_cc = detract(np, 0);
+       if (replyto == NOSTR) {
+               cp = hfield("cc", mp);
+               if (cp != NOSTR) {
+                       np = elide(extract(cp, GCC));
+                       mapf(np, rcv);
+                       np = delname(np, myname);
+                       if (altnames != 0)
+                               for (ap = altnames; *ap; ap++)
+                                       np = delname(np, *ap);
+                       head.h_cc = detract(np, 0);
+               }
        }
        head.h_bcc = NOSTR;
        mail1(&head);
        return(0);
 }
 
        }
        head.h_bcc = NOSTR;
        mail1(&head);
        return(0);
 }
 
+/*
+ * Modify the subject we are replying to to begin with Re: if
+ * it does not already.
+ */
+
+char *
+reedit(subj)
+       char *subj;
+{
+       char sbuf[10];
+       register char *newsubj;
+
+       if (subj == NOSTR)
+               return(NOSTR);
+       strncpy(sbuf, subj, 3);
+       sbuf[3] = 0;
+       if (icequal(sbuf, "re:"))
+               return(subj);
+       newsubj = salloc(strlen(subj) + 6);
+       sprintf(newsubj, "Re:  %s", subj);
+       return(newsubj);
+}
+
 /*
  * Preserve the named messages, so that they will be sent
  * back to the system mailbox.
 /*
  * Preserve the named messages, so that they will be sent
  * back to the system mailbox.
@@ -253,6 +302,7 @@ preserve(msgvec)
                mesg = *ip;
                mp = &message[mesg-1];
                mp->m_flag |= MPRESERVE;
                mesg = *ip;
                mp = &message[mesg-1];
                mp->m_flag |= MPRESERVE;
+               mp->m_flag &= ~MBOX;
                dot = mp;
        }
        return(0);
                dot = mp;
        }
        return(0);
@@ -271,7 +321,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: %ld\n", mesg, mp->m_size);
        }
        return(0);
 }
        }
        return(0);
 }
@@ -285,6 +335,8 @@ rexit(e)
 {
        if (sourcing)
                return(1);
 {
        if (sourcing)
                return(1);
+       if (Tflag != NOSTR)
+               close(creat(Tflag, 0600));
        exit(e);
 }
 
        exit(e);
 }
 
@@ -480,14 +532,10 @@ file(argv)
 {
        register char *cp;
        char fname[BUFSIZ];
 {
        register char *cp;
        char fname[BUFSIZ];
+       int edit;
 
        if (argv[0] == NOSTR) {
 
        if (argv[0] == NOSTR) {
-               if (edit)
-                       printf("Reading \"%s\"", editfile);
-               else
-                       printf("Reading %s's mail",
-                           rindex(mailname, '/') + 1);
-               printf("; %d message(s)\n", msgCount);
+               newfileinfo();
                return(0);
        }
 
                return(0);
        }
 
@@ -497,13 +545,18 @@ file(argv)
         *      # -- gets the previous file
         *      % -- gets the invoker's post office box
         *      %user -- gets someone else's post office box
         *      # -- gets the previous file
         *      % -- gets the invoker's post office box
         *      %user -- gets someone else's post office box
+        *      & -- gets invoker's mbox file
         *      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);
+       }
+       newfileinfo();
 }
 
 /*
 }
 
 /*
@@ -513,17 +566,70 @@ file(argv)
  *     % -- for my system mail box
  *     %user -- for user's system mail box
  *     # -- for previous file
  *     % -- for my system mail box
  *     %user -- for user's system mail box
  *     # -- for previous file
+ *     & -- get's invoker's mbox file
  *     file name -- for any other file
  */
 
  *     file name -- for any other file
  */
 
+char   prevfile[PATHSIZE];
+
 char *
 char *
-getfilename(name)
+getfilename(name, aedit)
        char *name;
        char *name;
+       int *aedit;
 {
        register char *cp;
 {
        register char *cp;
+       char savename[BUFSIZ];
+       char oldmailname[BUFSIZ];
 
 
-       cp = expand(name);
-       return(cp);
+       /*
+        * Assume we will be in "edit file" mode, until
+        * proven wrong.
+        */
+       *aedit = 1;
+       switch (*name) {
+       case '%':
+               *aedit = 0;
+               strcpy(prevfile, mailname);
+               if (name[1] != 0) {
+                       strcpy(savename, myname);
+                       strcpy(oldmailname, mailname);
+                       strncpy(myname, name+1, PATHSIZE-1);
+                       myname[PATHSIZE-1] = 0;
+                       findmail();
+                       cp = savestr(mailname);
+                       strcpy(myname, savename);
+                       strcpy(mailname, oldmailname);
+                       return(cp);
+               }
+               strcpy(oldmailname, mailname);
+               findmail();
+               cp = savestr(mailname);
+               strcpy(mailname, oldmailname);
+               return(cp);
+
+       case '#':
+               if (name[1] != 0)
+                       goto regular;
+               if (prevfile[0] == 0) {
+                       printf("No previous file\n");
+                       return(NOSTR);
+               }
+               cp = savestr(prevfile);
+               strcpy(prevfile, mailname);
+               return(cp);
+
+       case '&':
+               strcpy(prevfile, mailname);
+               if (name[1] == 0)
+                       return(mbox);
+               /* Fall into . . . */
+
+       default:
+regular:
+               strcpy(prevfile, mailname);
+               cp = expand(name);
+               return(cp);
+       }
 }
 
 /*
 }
 
 /*
@@ -539,7 +645,7 @@ echo(argv)
        for (ap = argv; *ap != NOSTR; ap++) {
                cp = *ap;
                if ((cp = expand(cp)) != NOSTR)
        for (ap = argv; *ap != NOSTR; ap++) {
                cp = *ap;
                if ((cp = expand(cp)) != NOSTR)
-                       printf("%s\n", cp);
+                       printf("%s ", cp);
        }
        return(0);
 }
        }
        return(0);
 }
@@ -561,7 +667,7 @@ Respond(msgvec)
        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)) + 1;
+               s += strlen(nameof(mp, 2)) + 1;
        }
        if (s == 0)
                return(0);
        }
        if (s == 0)
                return(0);
@@ -569,7 +675,7 @@ 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), cp);
+               cp = copy(nameof(mp, 2), cp);
                *cp++ = ' ';
        }
        *--cp = 0;
                *cp++ = ' ';
        }
        *--cp = 0;
@@ -578,7 +684,7 @@ Respond(msgvec)
        head.h_seq = 0;
        if (subject == NOSTR)
                subject = hfield("subj", mp);
        head.h_seq = 0;
        if (subject == NOSTR)
                subject = hfield("subj", mp);
-       head.h_subject = subject;
+       head.h_subject = reedit(subject);
        if (subject != NOSTR)
                head.h_seq++;
        head.h_cc = NOSTR;
        if (subject != NOSTR)
                head.h_seq++;
        head.h_cc = NOSTR;
@@ -586,3 +692,109 @@ Respond(msgvec)
        mail1(&head);
        return(0);
 }
        mail1(&head);
        return(0);
 }
+
+/*
+ * Conditional commands.  These allow one to parameterize one's
+ * .mailrc and do some things if sending, others if receiving.
+ */
+
+ifcmd(argv)
+       char **argv;
+{
+       register char *cp;
+
+       if (cond != CANY) {
+               printf("Illegal nested \"if\"\n");
+               return(1);
+       }
+       cond = CANY;
+       cp = argv[0];
+       switch (*cp) {
+       case 'r': case 'R':
+               cond = CRCV;
+               break;
+
+       case 's': case 'S':
+               cond = CSEND;
+               break;
+
+       default:
+               printf("Unrecognized if-keyword: \"%s\"\n", cp);
+               return(1);
+       }
+       return(0);
+}
+
+/*
+ * Implement 'else'.  This is pretty simple -- we just
+ * flip over the conditional flag.
+ */
+
+elsecmd()
+{
+
+       switch (cond) {
+       case CANY:
+               printf("\"Else\" without matching \"if\"\n");
+               return(1);
+
+       case CSEND:
+               cond = CRCV;
+               break;
+
+       case CRCV:
+               cond = CSEND;
+               break;
+
+       default:
+               printf("Mail's idea of conditions is screwed up\n");
+               cond = CANY;
+               break;
+       }
+       return(0);
+}
+
+/*
+ * End of if statement.  Just set cond back to anything.
+ */
+
+endifcmd()
+{
+
+       if (cond == CANY) {
+               printf("\"Endif\" without matching \"if\"\n");
+               return(1);
+       }
+       cond = CANY;
+       return(0);
+}
+
+/*
+ * Set the list of alternate names.
+ */
+alternates(namelist)
+       char **namelist;
+{
+       register int c;
+       register char **ap, **ap2, *cp;
+
+       c = argcount(namelist) + 1;
+       if (c == 1) {
+               if (altnames == 0)
+                       return(0);
+               for (ap = altnames; *ap; ap++)
+                       printf("%s ", *ap);
+               printf("\n");
+               return(0);
+       }
+       if (altnames != 0)
+               cfree((char *) altnames);
+       altnames = (char **) calloc(c, sizeof (char *));
+       for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) {
+               cp = (char *) calloc(strlen(*ap) + 1, sizeof (char));
+               strcpy(cp, *ap);
+               *ap2 = cp;
+       }
+       *ap2 = 0;
+       return(0);
+}