Wait3 becomes wait2 if pdp11 is defined, stays wait3 if vax is defined.
[unix-history] / usr / src / usr.bin / mail / collect.c
index d3f9223..080518f 100644 (file)
@@ -7,7 +7,7 @@
  * ~ escapes.
  */
 
  * ~ escapes.
  */
 
-static char *SccsId = "@(#)collect.c   1.1 %G%";
+static char *SccsId = "@(#)collect.c   2.11 %G%";
 
 #include "rcv.h"
 #include <sys/stat.h>
 
 #include "rcv.h"
 #include <sys/stat.h>
@@ -26,10 +26,13 @@ static char *SccsId = "@(#)collect.c        1.1 %G%";
  */
 
 static int     (*savesig)();           /* Previous SIGINT value */
  */
 
 static int     (*savesig)();           /* Previous SIGINT value */
+static int     (*savehup)();           /* Previous SIGHUP value */
+# ifdef VMUNIX
+static int     (*savecont)();          /* Previous SIGCONT value */
+# endif VMUNIX
 static FILE    *newi;                  /* File for saving away */
 static FILE    *newo;                  /* Output side of same */
 static int     hf;                     /* Ignore interrups */
 static FILE    *newi;                  /* File for saving away */
 static FILE    *newo;                  /* Output side of same */
 static int     hf;                     /* Ignore interrups */
-static int     nofault;                /* Soft signal if set */
 static int     hadintr;                /* Have seen one SIGINT so far */
 
 static jmp_buf coljmp;                 /* To get back to work */
 static int     hadintr;                /* Have seen one SIGINT so far */
 
 static jmp_buf coljmp;                 /* To get back to work */
@@ -39,22 +42,30 @@ collect(hp)
        struct header *hp;
 {
        FILE *ibuf, *fbuf, *obuf;
        struct header *hp;
 {
        FILE *ibuf, *fbuf, *obuf;
-       int lc, cc, escape, collrub(), intack(), stopdot;
+       int lc, cc, escape, collrub(), intack(), collhup, collcont(), eof;
        register int c, t;
        char linebuf[LINESIZE], *cp;
        extern char tempMail[];
        register int c, t;
        char linebuf[LINESIZE], *cp;
        extern char tempMail[];
+       int notify();
+       extern collintsig(), collhupsig();
 
        noreset++;
 
        noreset++;
-       stopdot = (value("dot") != NOSTR) && intty;
        ibuf = obuf = NULL;
        if (value("ignore") != NOSTR)
                hf = 1;
        else
                hf = 0;
        ibuf = obuf = NULL;
        if (value("ignore") != NOSTR)
                hf = 1;
        else
                hf = 0;
-       nofault = 1;
        hadintr = 0;
        hadintr = 0;
-       if ((savesig = signal(SIGINT, SIG_IGN)) != SIG_IGN)
-               signal(SIGINT, hf ? intack : collrub);
+# ifdef VMUNIX
+       if ((savesig = sigset(SIGINT, SIG_IGN)) != SIG_IGN)
+               sigset(SIGINT, hf ? intack : collrub), sighold(SIGINT);
+       if ((savehup = sigset(SIGHUP, SIG_IGN)) != SIG_IGN)
+               sigset(SIGHUP, collrub), sighold(SIGHUP);
+       savecont = sigset(SIGCONT, collcont);
+# else VMUNIX
+       savesig = signal(SIGINT, SIG_IGN);
+       savehup = signal(SIGHUP, SIG_IGN);
+# endif VMUNIX
        newi = NULL;
        newo = NULL;
        if ((obuf = fopen(tempMail, "w")) == NULL) {
        newi = NULL;
        newo = NULL;
        if ((obuf = fopen(tempMail, "w")) == NULL) {
@@ -90,23 +101,40 @@ collect(hp)
        escape = ESCAPE;
        if ((cp = value("escape")) != NOSTR)
                escape = *cp;
        escape = ESCAPE;
        if ((cp = value("escape")) != NOSTR)
                escape = *cp;
+       eof = 0;
        for (;;) {
                setjmp(coljmp);
        for (;;) {
                setjmp(coljmp);
-               nofault = 0;
+# ifdef VMUNIX
+               sigrelse(SIGINT);
+               sigrelse(SIGHUP);
+# else VMUNIX
+               if (savesig != SIG_IGN)
+                       signal(SIGINT, hf ? intack : collintsig);
+               if (savehup != SIG_IGN)
+                       signal(SIGHUP, collhupsig);
+# endif VMUNIX
                flush();
                flush();
-               if (readline(stdin, linebuf) <= 0)
+               if (readline(stdin, linebuf) <= 0) {
+                       if (intty && value("ignoreeof") != NOSTR) {
+                               if (++eof > 35)
+                                       break;
+                               printf("Use \".\" to terminate letter\n",
+                                   escape);
+                               continue;
+                       }
                        break;
                        break;
+               }
+               eof = 0;
                hadintr = 0;
                hadintr = 0;
-               if (stopdot && equal(".", linebuf))
+               if (intty && equal(".", linebuf) &&
+                   (value("dot") != NOSTR || value("ignoreeof") != NOSTR))
                        break;
                        break;
-               if (linebuf[0] != escape ||
-                   (!intty && value("henry") == NOSTR)) {
+               if (linebuf[0] != escape || rflag != NOSTR) {
                        if ((t = putline(obuf, linebuf)) < 0)
                                goto err;
                        continue;
                }
                c = linebuf[1];
                        if ((t = putline(obuf, linebuf)) < 0)
                                goto err;
                        continue;
                }
                c = linebuf[1];
-               nofault= 0;
                switch (c) {
                default:
                        /*
                switch (c) {
                default:
                        /*
@@ -146,15 +174,15 @@ collect(hp)
                         * Escape to command mode, but be nice!
                         */
 
                         * Escape to command mode, but be nice!
                         */
 
-                       nofault = 0;
-                       execute(&linebuf[2]);
+                       execute(&linebuf[2], 1);
+                       printf("(continue)\n");
                        break;
 
                case '.':
                        /*
                         * Simulate end of file on input.
                         */
                        break;
 
                case '.':
                        /*
                         * Simulate end of file on input.
                         */
-                       goto eof;
+                       goto eofl;
 
                case 'q':
                case 'Q':
 
                case 'q':
                case 'Q':
@@ -163,7 +191,6 @@ collect(hp)
                         * Act like an interrupt happened.
                         */
 
                         * Act like an interrupt happened.
                         */
 
-                       nofault = 0;
                        hadintr++;
                        collrub(SIGINT);
                        exit(1);
                        hadintr++;
                        collrub(SIGINT);
                        exit(1);
@@ -304,7 +331,6 @@ collect(hp)
                        break;
 
                case '?':
                        break;
 
                case '?':
-                       nofault = 0;
                        if ((fbuf = fopen(THELPFILE, "r")) == NULL) {
                                printf("No help just now.\n");
                                break;
                        if ((fbuf = fopen(THELPFILE, "r")) == NULL) {
                                printf("No help just now.\n");
                                break;
@@ -325,7 +351,6 @@ collect(hp)
 
                        fflush(obuf);
                        rewind(ibuf);
 
                        fflush(obuf);
                        rewind(ibuf);
-                       nofault = 0;
                        printf("-------\nMessage contains:\n");
                        puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL);
                        t = getc(ibuf);
                        printf("-------\nMessage contains:\n");
                        puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL);
                        t = getc(ibuf);
@@ -367,10 +392,14 @@ collect(hp)
                        break;
                }
        }
                        break;
                }
        }
-eof:
+eofl:
        fclose(obuf);
        rewind(ibuf);
        fclose(obuf);
        rewind(ibuf);
-       signal(SIGINT, savesig);
+       sigset(SIGINT, savesig);
+       sigset(SIGHUP, savehup);
+# ifdef VMUNIX
+       sigset(SIGCONT, savecont);
+# endif VMUNIX
        noreset = 0;
        return(ibuf);
 
        noreset = 0;
        return(ibuf);
 
@@ -379,7 +408,11 @@ err:
                fclose(ibuf);
        if (obuf != NULL)
                fclose(obuf);
                fclose(ibuf);
        if (obuf != NULL)
                fclose(obuf);
-       signal(SIGINT, savesig);
+       sigset(SIGINT, savesig);
+       sigset(SIGHUP, savehup);
+# ifdef VMUNIX
+       sigset(SIGCONT, savecont);
+# endif VMUNIX
        noreset = 0;
        return(NULL);
 }
        noreset = 0;
        return(NULL);
 }
@@ -392,8 +425,8 @@ psig(n)
 {
        register (*wassig)();
 
 {
        register (*wassig)();
 
-       wassig = signal(n, SIG_IGN);
-       signal(n, wassig);
+       wassig = sigset(n, SIG_IGN);
+       sigset(n, wassig);
        return((int) wassig);
 }
 
        return((int) wassig);
 }
 
@@ -415,7 +448,7 @@ exwrite(name, ibuf, f)
                printf("\"%s\" ", name);
                fflush(stdout);
        }
                printf("\"%s\" ", name);
                fflush(stdout);
        }
-       if (stat(name, &junk) >= 0) {
+       if (stat(name, &junk) >= 0 && (junk.st_mode & S_IFMT) == S_IFREG) {
                if (!f)
                        fprintf(stderr, "%s: ", name);
                fprintf(stderr, "File exists\n", name);
                if (!f)
                        fprintf(stderr, "%s: ", name);
                fprintf(stderr, "File exists\n", name);
@@ -459,12 +492,15 @@ mesedit(ibuf, obuf, c)
        int pid, s;
        FILE *fbuf;
        register int t;
        int pid, s;
        FILE *fbuf;
        register int t;
-       int (*sig)();
+       int (*sig)(), (*scont)(), foonly();
        struct stat sbuf;
        extern char tempMail[], tempEdit[];
        register char *edit;
 
        struct stat sbuf;
        extern char tempMail[], tempEdit[];
        register char *edit;
 
-       sig = signal(SIGINT, SIG_IGN);
+       sig = sigset(SIGINT, SIG_IGN);
+# ifdef VMUNIX
+       scont = sigset(SIGCONT, foonly);
+# endif VMUNIX
        if (stat(tempEdit, &sbuf) >= 0) {
                printf("%s: file exists\n", tempEdit);
                goto out;
        if (stat(tempEdit, &sbuf) >= 0) {
                printf("%s: file exists\n", tempEdit);
                goto out;
@@ -492,8 +528,9 @@ mesedit(ibuf, obuf, c)
                edit = c == 'e' ? EDITOR : VISUAL;
        pid = vfork();
        if (pid == 0) {
                edit = c == 'e' ? EDITOR : VISUAL;
        pid = vfork();
        if (pid == 0) {
+               sigchild();
                if (sig != SIG_IGN)
                if (sig != SIG_IGN)
-                       signal(SIGINT, SIG_DFL);
+                       sigsys(SIGINT, SIG_DFL);
                execl(edit, edit, tempEdit, 0);
                perror(edit);
                _exit(1);
                execl(edit, edit, tempEdit, 0);
                perror(edit);
                _exit(1);
@@ -505,7 +542,7 @@ mesedit(ibuf, obuf, c)
        }
        while (wait(&s) != pid)
                ;
        }
        while (wait(&s) != pid)
                ;
-       if (s != 0) {
+       if ((s & 0377) != 0) {
                printf("Fatal error in \"%s\"\n", edit);
                remove(tempEdit);
                goto out;
                printf("Fatal error in \"%s\"\n", edit);
                remove(tempEdit);
                goto out;
@@ -534,11 +571,21 @@ mesedit(ibuf, obuf, c)
 fix:
        perror(tempEdit);
 out:
 fix:
        perror(tempEdit);
 out:
-       signal(SIGINT, sig);
+# ifdef VMUNIX
+       sigset(SIGCONT, scont);
+# endif VMUNIX
+       sigset(SIGINT, sig);
        newi = ibuf;
        return(obuf);
 }
 
        newi = ibuf;
        return(obuf);
 }
 
+/*
+ * Currently, Berkeley virtual VAX/UNIX will not let you change the
+ * disposition of SIGCONT, except to trap it somewhere new.
+ * Hence, sigset(SIGCONT, foonly) is used to ignore continue signals.
+ */
+foonly() {}
+
 /*
  * Pipe the message through the command.
  * Old message is on stdin of command;
 /*
  * Pipe the message through the command.
  * Old message is on stdin of command;
@@ -568,7 +615,7 @@ mespipe(ibuf, obuf, cmd)
                return(obuf);
        }
        remove(tempEdit);
                return(obuf);
        }
        remove(tempEdit);
-       savesig = signal(SIGINT, SIG_IGN);
+       savesig = sigset(SIGINT, SIG_IGN);
        fflush(obuf);
        rewind(ibuf);
        if ((Shell = value("SHELL")) == NULL)
        fflush(obuf);
        rewind(ibuf);
        if ((Shell = value("SHELL")) == NULL)
@@ -583,6 +630,7 @@ mespipe(ibuf, obuf, cmd)
                 * stdout = new message.
                 */
 
                 * stdout = new message.
                 */
 
+               sigchild();
                close(0);
                dup(fileno(ibuf));
                close(1);
                close(0);
                dup(fileno(ibuf));
                close(1);
@@ -611,13 +659,13 @@ mespipe(ibuf, obuf, cmd)
        newi = ni;
        fclose(ibuf);
        fclose(obuf);
        newi = ni;
        fclose(ibuf);
        fclose(obuf);
-       signal(SIGINT, savesig);
+       sigset(SIGINT, savesig);
        return(no);
 
 err:
        fclose(no);
        fclose(ni);
        return(no);
 
 err:
        fclose(no);
        fclose(ni);
-       signal(SIGINT, savesig);
+       sigset(SIGINT, savesig);
        return(obuf);
 }
 
        return(obuf);
 }
 
@@ -629,7 +677,6 @@ err:
  * the message temporary.  The flag argument is 'm' if we
  * should shift over and 'f' if not.
  */
  * the message temporary.  The flag argument is 'm' if we
  * should shift over and 'f' if not.
  */
-
 forward(ms, obuf, f)
        char ms[];
        FILE *obuf;
 forward(ms, obuf, f)
        char ms[];
        FILE *obuf;
@@ -660,7 +707,7 @@ forward(ms, obuf, f)
                                return(-1);
                        }
                } else
                                return(-1);
                        }
                } else
-                       if (send(&message[*ip-1], obuf) < 0) {
+                       if (send(&message[*ip-1], obuf, 0) < 0) {
                                perror(tempMail);
                                return(-1);
                        }
                                perror(tempMail);
                                return(-1);
                        }
@@ -712,46 +759,55 @@ transmit(mailp, obuf)
        return(n);
 }
 
        return(n);
 }
 
+/*
+ * Print (continue) when continued after ^Z.
+ */
+collcont(s)
+{
+
+       printf("(continue)\n");
+       fflush(stdout);
+}
+
 /*
  * On interrupt, go here to save the partial
 /*
  * On interrupt, go here to save the partial
- * message on #/dead.letter.
+ * message on ~/dead.letter.
  * Then restore signals and execute the normal
  * signal routine.  We only come here if signals
  * were previously set anyway.
  */
 
  * Then restore signals and execute the normal
  * signal routine.  We only come here if signals
  * were previously set anyway.
  */
 
+# ifndef VMUNIX
+collintsig()
+{
+       signal(SIGINT, SIG_IGN);
+       collrub(SIGINT);
+}
+
+collhupsig()
+{
+       signal(SIGHUP, SIG_IGN);
+       collrub(SIGHUP);
+}
+# endif VMUNIX
+
 collrub(s)
 {
        register FILE *dbuf;
        register int c;
 
 collrub(s)
 {
        register FILE *dbuf;
        register int c;
 
-#ifdef V7
-       signal(s, SIG_IGN);
-#else
-       signal(SIGINT, SIG_IGN);
-#endif
-       if (nofault) {
-#ifdef V7
-               signal(s, collrub);
-#else
-               signal(SIGINT, collrub);
-#endif
-               return;
-       }
-       if (hadintr == 0) {
+       if (s == SIGINT && hadintr == 0) {
                hadintr++;
                clrbuf(stdout);
                printf("\n(Interrupt -- one more to kill letter)\n");
                hadintr++;
                clrbuf(stdout);
                printf("\n(Interrupt -- one more to kill letter)\n");
-#ifdef V7
-               signal(s, collrub);
-#else
-               signal(SIGINT, collrub);
-#endif
+# ifdef VMUNIX
+               sigrelse(s);
+# endif VMUNIX
                longjmp(coljmp, 1);
        }
        fclose(newo);
        rewind(newi);
                longjmp(coljmp, 1);
        }
        fclose(newo);
        rewind(newi);
-       if (value("nosave") != NOSTR || fsize(newi) == 0)
+       if (s == SIGINT && value("nosave") != NOSTR || fsize(newi) == 0)
                goto done;
        if ((dbuf = fopen(deadletter, "w")) == NULL)
                goto done;
                goto done;
        if ((dbuf = fopen(deadletter, "w")) == NULL)
                goto done;
@@ -762,9 +818,17 @@ collrub(s)
 
 done:
        fclose(newi);
 
 done:
        fclose(newi);
-       signal(SIGINT, savesig);
-       if (rcvmode)
-               stop();
+       sigset(SIGINT, savesig);
+       sigset(SIGHUP, savehup);
+# ifdef VMUNIX
+       sigset(SIGCONT, savecont);
+# endif VMUNIX
+       if (rcvmode) {
+               if (s == SIGHUP)
+                       hangup(SIGHUP);
+               else
+                       stop(s);
+       }
        else
                exit(1);
 }
        else
                exit(1);
 }
@@ -776,11 +840,9 @@ done:
 intack(s)
 {
        
 intack(s)
 {
        
-       signal(SIGINT, SIG_IGN);
        puts("@");
        fflush(stdout);
        clearerr(stdin);
        puts("@");
        fflush(stdout);
        clearerr(stdin);
-       signal(SIGINT, intack);
 }
 
 /*
 }
 
 /*