don't catch SIGCONT, catch the stop signals instead,
authorEdward Wang <edward@ucbvax.Berkeley.EDU>
Mon, 16 Jan 1989 17:34:29 +0000 (09:34 -0800)
committerEdward Wang <edward@ucbvax.Berkeley.EDU>
Mon, 16 Jan 1989 17:34:29 +0000 (09:34 -0800)
cleaned up quitting of mail and signal catch in general,
could use more work

SCCS-vsn: usr.bin/mail/lex.c 5.17
SCCS-vsn: usr.bin/mail/collect.c 5.17
SCCS-vsn: usr.bin/mail/cmdtab.c 5.10
SCCS-vsn: usr.bin/mail/cmd2.c 5.11
SCCS-vsn: usr.bin/mail/quit.c 5.11
SCCS-vsn: usr.bin/mail/cmd3.c 5.18
SCCS-vsn: usr.bin/mail/main.c 5.20
SCCS-vsn: usr.bin/mail/fio.c 5.20
SCCS-vsn: usr.bin/mail/cmd1.c 5.18

usr/src/usr.bin/mail/cmd1.c
usr/src/usr.bin/mail/cmd2.c
usr/src/usr.bin/mail/cmd3.c
usr/src/usr.bin/mail/cmdtab.c
usr/src/usr.bin/mail/collect.c
usr/src/usr.bin/mail/fio.c
usr/src/usr.bin/mail/lex.c
usr/src/usr.bin/mail/main.c
usr/src/usr.bin/mail/quit.c

index 5878f61..d837963 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cmd1.c     5.17 (Berkeley) %G%";
+static char sccsid[] = "@(#)cmd1.c     5.18 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "rcv.h"
 #endif /* not lint */
 
 #include "rcv.h"
@@ -415,7 +415,7 @@ folders()
 
        if (getfold(dirname) < 0) {
                printf("No value set for \"folder\"\n");
 
        if (getfold(dirname) < 0) {
                printf("No value set for \"folder\"\n");
-               return -1;
+               return 1;
        }
        if ((cmd = value("LISTER")) == NOSTR)
                cmd = "ls";
        }
        if ((cmd = value("LISTER")) == NOSTR)
                cmd = "ls";
index 4c9bfd0..7d82365 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cmd2.c     5.10 (Berkeley) %G%";
+static char sccsid[] = "@(#)cmd2.c     5.11 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "rcv.h"
 #endif /* not lint */
 
 #include "rcv.h"
@@ -251,7 +251,8 @@ snarf(linebuf, flag)
 delete(msgvec)
        int msgvec[];
 {
 delete(msgvec)
        int msgvec[];
 {
-       return(delm(msgvec));
+       delm(msgvec);
+       return 0;
 }
 
 /*
 }
 
 /*
@@ -273,12 +274,9 @@ deltype(msgvec)
                        return(type(list));
                }
                printf("At EOF\n");
                        return(type(list));
                }
                printf("At EOF\n");
-               return(0);
-       }
-       else {
+       } else
                printf("No more messages\n");
                printf("No more messages\n");
-               return(0);
-       }
+       return(0);
 }
 
 /*
 }
 
 /*
index 93fb4a8..4b661c8 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cmd3.c     5.17 (Berkeley) %G%";
+static char sccsid[] = "@(#)cmd3.c     5.18 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "rcv.h"
 #endif /* not lint */
 
 #include "rcv.h"
@@ -41,7 +41,7 @@ shell(str)
 
        (void) strcpy(cmd, str);
        if (bangexp(cmd) < 0)
 
        (void) strcpy(cmd, str);
        if (bangexp(cmd) < 0)
-               return(-1);
+               return 1;
        if ((shell = value("SHELL")) == NOSTR)
                shell = SHELL;
        (void) run_command(shell, 0, -1, -1, "-c", cmd, NOSTR);
        if ((shell = value("SHELL")) == NOSTR)
                shell = SHELL;
        (void) run_command(shell, 0, -1, -1, "-c", cmd, NOSTR);
@@ -512,27 +512,23 @@ null(e)
 }
 
 /*
 }
 
 /*
- * Print out the current edit file, if we are editing.
- * Otherwise, print the name of the person who's mail
- * we are reading.
+ * Change to another file.  With no argument, print information about
+ * the current file.
  */
  */
-
 file(argv)
        register char **argv;
 {
 file(argv)
        register char **argv;
 {
-       register char *cp;
+       char *cp;
 
        if (argv[0] == NOSTR) {
                newfileinfo();
                return 0;
        }
        if ((cp = expand(*argv)) == NOSTR)
 
        if (argv[0] == NOSTR) {
                newfileinfo();
                return 0;
        }
        if ((cp = expand(*argv)) == NOSTR)
-               return -1;
+               return 1;
        strcpy(prevfile, mailname);
        strcpy(prevfile, mailname);
-       if (setfile(cp, **argv != '%')) {
-               perror(cp);
-               return -1;
-       }
+       if (setfile(cp, **argv != '%') < 0)
+               return 1;
        announce();
        return 0;
 }
        announce();
        return 0;
 }
index 74b21ce..d262712 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)cmdtab.c   5.9 (Berkeley) %G%";
+static char sccsid[] = "@(#)cmdtab.c   5.10 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "def.h"
 #endif /* not lint */
 
 #include "def.h"
@@ -29,7 +29,7 @@ static char sccsid[] = "@(#)cmdtab.c  5.9 (Berkeley) %G%";
 
 extern int type(), preserve(), delete(), undelete(), next(), shell(), schdir();
 extern int save(), help(), headers(), pdot(), respond(), editor();
 
 extern int type(), preserve(), delete(), undelete(), next(), shell(), schdir();
 extern int save(), help(), headers(), pdot(), respond(), editor();
-extern int edstop(), rexit(), pcmdlist(), sendmail(), from(), copycmd();
+extern int quitcmd(), rexit(), pcmdlist(), sendmail(), from(), copycmd();
 extern int messize(), psalloc(), deltype(), unset(), set(), source();
 extern int pversion(), group(), top(), core(), null(), stouch(), visual();
 extern int swrite(), dosh(), file(), echo(), Respond(), scroll(), ifcmd();
 extern int messize(), psalloc(), deltype(), unset(), set(), source();
 extern int pversion(), group(), top(), core(), null(), stouch(), visual();
 extern int swrite(), dosh(), file(), echo(), Respond(), scroll(), ifcmd();
@@ -87,7 +87,7 @@ struct cmd cmdtab[] = {
        "respond",      respond,        R|I|MSGLIST,    0,      MMNDEL,
        "edit",         editor,         I|MSGLIST,      0,      MMNORM,
        "echo",         echo,           M|RAWLIST,      0,      1000,
        "respond",      respond,        R|I|MSGLIST,    0,      MMNDEL,
        "edit",         editor,         I|MSGLIST,      0,      MMNORM,
        "echo",         echo,           M|RAWLIST,      0,      1000,
-       "quit",         edstop,         NOLIST,         0,      0,
+       "quit",         quitcmd,        NOLIST,         0,      0,
        "list",         pcmdlist,       M|NOLIST,       0,      0,
        "xit",          rexit,          M|NOLIST,       0,      0,
        "exit",         rexit,          M|NOLIST,       0,      0,
        "list",         pcmdlist,       M|NOLIST,       0,      0,
        "xit",          rexit,          M|NOLIST,       0,      0,
        "exit",         rexit,          M|NOLIST,       0,      0,
index ac1f105..2e6da16 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)collect.c  5.16 (Berkeley) %G%";
+static char sccsid[] = "@(#)collect.c  5.17 (Berkeley) %G%";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -42,44 +42,49 @@ static char sccsid[] = "@(#)collect.c       5.16 (Berkeley) %G%";
 
 static int     (*saveint)();           /* Previous SIGINT value */
 static int     (*savehup)();           /* Previous SIGHUP value */
 
 static int     (*saveint)();           /* Previous SIGINT value */
 static int     (*savehup)();           /* Previous SIGHUP value */
-static int     (*savecont)();          /* Previous SIGCONT value */
+static int     (*savetstp)();          /* Previous SIGTSTP value */
+static int     (*savettou)();          /* Previous SIGTTOU value */
+static int     (*savettin)();          /* Previous SIGTTIN value */
 static FILE    *collf;                 /* File for saving away */
 static int     hadintr;                /* Have seen one SIGINT so far */
 
 static FILE    *collf;                 /* File for saving away */
 static int     hadintr;                /* Have seen one SIGINT so far */
 
-static jmp_buf coljmp;                 /* To get back to work */
+static jmp_buf colljmp;                /* To get back to work */
+static int     colljmp_p;              /* whether to long jump */
+static jmp_buf collabort;              /* To end collection with error */
 
 FILE *
 collect(hp, printheaders)
        struct header *hp;
 {
        FILE *fbuf;
 
 FILE *
 collect(hp, printheaders)
        struct header *hp;
 {
        FILE *fbuf;
-       int lc, cc, escape, eof;
-       int collrub(), intack(), collcont();
+       int lc, cc, escape, eofcount;
+       int collint(), collhup(), collstop();
        register int c, t;
        char linebuf[LINESIZE], *cp;
        extern char tempMail[];
        char getsub;
        int omask;
 
        register int c, t;
        char linebuf[LINESIZE], *cp;
        extern char tempMail[];
        char getsub;
        int omask;
 
-       noreset++;
        collf = NULL;
        collf = NULL;
-
        /*
         * Start catching signals from here, but we're still die on interrupts
         * until we're in the main loop.
         */
        omask = sigblock(sigmask(SIGINT) | sigmask(SIGHUP));
        if ((saveint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
        /*
         * Start catching signals from here, but we're still die on interrupts
         * until we're in the main loop.
         */
        omask = sigblock(sigmask(SIGINT) | sigmask(SIGHUP));
        if ((saveint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
-               signal(SIGINT, value("ignore") != NOSTR ? intack : collrub);
+               signal(SIGINT, collint);
        if ((savehup = signal(SIGHUP, SIG_IGN)) != SIG_IGN)
        if ((savehup = signal(SIGHUP, SIG_IGN)) != SIG_IGN)
-               signal(SIGHUP, collrub);
-       savecont = signal(SIGCONT, SIG_DFL);
-       if (setjmp(coljmp)) {
+               signal(SIGHUP, collhup);
+       savetstp = signal(SIGTSTP, collstop);
+       savettou = signal(SIGTTOU, collstop);
+       savettin = signal(SIGTTIN, collstop);
+       if (setjmp(collabort) || setjmp(colljmp)) {
                remove(tempMail);
                goto err;
        }
        sigsetmask(omask & ~(sigmask(SIGINT) | sigmask(SIGHUP)));
 
                remove(tempMail);
                goto err;
        }
        sigsetmask(omask & ~(sigmask(SIGINT) | sigmask(SIGHUP)));
 
+       noreset++;
        if ((collf = fopen(tempMail, "w+")) == NULL) {
                perror(tempMail);
                goto err;
        if ((collf = fopen(tempMail, "w+")) == NULL) {
                perror(tempMail);
                goto err;
@@ -104,11 +109,10 @@ collect(hp, printheaders)
                escape = *cp;
        else
                escape = ESCAPE;
                escape = *cp;
        else
                escape = ESCAPE;
-       eof = 0;
+       eofcount = 0;
        hadintr = 0;
 
        hadintr = 0;
 
-       if (!setjmp(coljmp)) {
-               signal(SIGCONT, collcont);
+       if (!setjmp(colljmp)) {
                if (getsub)
                        grabh(hp, GSUBJECT);
        } else {
                if (getsub)
                        grabh(hp, GSUBJECT);
        } else {
@@ -128,17 +132,18 @@ cont:
                }
        }
        for (;;) {
                }
        }
        for (;;) {
-               if (readline(stdin, linebuf) < 0) {
+               colljmp_p = 1;
+               c = readline(stdin, linebuf, LINESIZE);
+               colljmp_p = 0;
+               if (c < 0) {
                        if (value("interactive") != NOSTR &&
                        if (value("interactive") != NOSTR &&
-                           value("ignoreeof") != NOSTR) {
-                               if (++eof > 35)
-                                       break;
+                           value("ignoreeof") != NOSTR && ++eofcount < 25) {
                                printf("Use \".\" to terminate letter\n");
                                continue;
                        }
                        break;
                }
                                printf("Use \".\" to terminate letter\n");
                                continue;
                        }
                        break;
                }
-               eof = 0;
+               eofcount = 0;
                hadintr = 0;
                if (linebuf[0] == '.' && linebuf[1] == '\0' &&
                    value("interactive") != NOSTR &&
                hadintr = 0;
                if (linebuf[0] == '.' && linebuf[1] == '\0' &&
                    value("interactive") != NOSTR &&
@@ -194,7 +199,7 @@ cont:
                         * Act like an interrupt happened.
                         */
                        hadintr++;
                         * Act like an interrupt happened.
                         */
                        hadintr++;
-                       collrub(SIGINT);
+                       collint(SIGINT);
                        exit(1);
                case 'h':
                        /*
                        exit(1);
                case 'h':
                        /*
@@ -260,7 +265,7 @@ cont:
                        fflush(stdout);
                        lc = 0;
                        cc = 0;
                        fflush(stdout);
                        lc = 0;
                        cc = 0;
-                       while (readline(fbuf, linebuf) >= 0) {
+                       while (readline(fbuf, linebuf, LINESIZE) >= 0) {
                                lc++;
                                if ((t = putline(collf, linebuf)) < 0) {
                                        fclose(fbuf);
                                lc++;
                                if ((t = putline(collf, linebuf)) < 0) {
                                        fclose(fbuf);
@@ -297,10 +302,6 @@ cont:
                         * standard list processing garbage.
                         * If ~f is given, we don't shift over.
                         */
                         * standard list processing garbage.
                         * If ~f is given, we don't shift over.
                         */
-                       if (!rcvmode) {
-                               printf("No messages to send from!?!\n");
-                               break;
-                       }
                        if (forward(linebuf + 2, collf, c) < 0)
                                goto err;
                        goto cont;
                        if (forward(linebuf + 2, collf, c) < 0)
                                goto err;
                        goto cont;
@@ -310,7 +311,7 @@ cont:
                                break;
                        }
                        while ((t = getc(fbuf)) != EOF)
                                break;
                        }
                        while ((t = getc(fbuf)) != EOF)
-                               putchar(t);
+                               (void) putchar(t);
                        fclose(fbuf);
                        break;
                case 'p':
                        fclose(fbuf);
                        break;
                case 'p':
@@ -322,7 +323,7 @@ cont:
                        printf("-------\nMessage contains:\n");
                        puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL);
                        while ((t = getc(collf)) != EOF)
                        printf("-------\nMessage contains:\n");
                        puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL);
                        while ((t = getc(collf)) != EOF)
-                               putchar(t);
+                               (void) putchar(t);
                        goto cont;
                case '|':
                        /*
                        goto cont;
                case '|':
                        /*
@@ -353,11 +354,14 @@ err:
 out:
        if (collf != NULL)
                rewind(collf);
 out:
        if (collf != NULL)
                rewind(collf);
+       noreset--;
+       sigblock(sigmask(SIGINT) | sigmask(SIGHUP));
        signal(SIGINT, saveint);
        signal(SIGHUP, savehup);
        signal(SIGINT, saveint);
        signal(SIGHUP, savehup);
-       signal(SIGCONT, savecont);
+       signal(SIGTSTP, savetstp);
+       signal(SIGTTOU, savettou);
+       signal(SIGTTIN, savettin);
        sigsetmask(omask);
        sigsetmask(omask);
-       noreset--;
        return collf;
 }
 
        return collf;
 }
 
@@ -395,7 +399,7 @@ exwrite(name, fp, f)
                cc++;
                if (c == '\n')
                        lc++;
                cc++;
                if (c == '\n')
                        lc++;
-               putc(c, of);
+               (void) putc(c, of);
                if (ferror(of)) {
                        perror(name);
                        fclose(of);
                if (ferror(of)) {
                        perror(name);
                        fclose(of);
@@ -416,7 +420,6 @@ mesedit(fp, c)
        FILE *fp;
 {
        int (*sigint)() = signal(SIGINT, SIG_IGN);
        FILE *fp;
 {
        int (*sigint)() = signal(SIGINT, SIG_IGN);
-       int (*sigcont)() = signal(SIGCONT, SIG_DFL);
        FILE *nf = run_editor(fp, (off_t)-1, c, 0);
 
        if (nf != NULL) {
        FILE *nf = run_editor(fp, (off_t)-1, c, 0);
 
        if (nf != NULL) {
@@ -425,7 +428,6 @@ mesedit(fp, c)
                fclose(fp);
        }
        (void) signal(SIGINT, sigint);
                fclose(fp);
        }
        (void) signal(SIGINT, sigint);
-       (void) signal(SIGCONT, sigcont);
 }
 
 /*
 }
 
 /*
@@ -440,7 +442,6 @@ mespipe(fp, cmd)
 {
        FILE *nf;
        int (*sigint)() = signal(SIGINT, SIG_IGN);
 {
        FILE *nf;
        int (*sigint)() = signal(SIGINT, SIG_IGN);
-       int (*sigcont)() = signal(SIGCONT, SIG_DFL);
        extern char tempEdit[];
 
        if ((nf = fopen(tempEdit, "w+")) == NULL) {
        extern char tempEdit[];
 
        if ((nf = fopen(tempEdit, "w+")) == NULL) {
@@ -469,7 +470,6 @@ mespipe(fp, cmd)
        (void) fclose(fp);
 out:
        (void) signal(SIGINT, sigint);
        (void) fclose(fp);
 out:
        (void) signal(SIGINT, sigint);
-       (void) signal(SIGCONT, sigcont);
 }
 
 /*
 }
 
 /*
@@ -526,41 +526,57 @@ forward(ms, fp, f)
  * Print (continue) when continued after ^Z.
  */
 /*ARGSUSED*/
  * Print (continue) when continued after ^Z.
  */
 /*ARGSUSED*/
-collcont(s)
+collstop(s)
 {
 {
+       int (*old_action)() = signal(s, SIG_DFL);
 
 
-       hadintr = 0;
-       longjmp(coljmp, 1);
+       sigsetmask(sigblock(0) & ~sigmask(s));
+       kill(0, s);
+       sigblock(sigmask(s));
+       signal(s, old_action);
+       if (colljmp_p) {
+               colljmp_p = 0;
+               hadintr = 0;
+               longjmp(colljmp, 1);
+       }
 }
 
 /*
 }
 
 /*
- * On interrupt, go here to save the partial
- * message on ~/dead.letter.
- * Then restore signals and execute the normal
- * signal routine.  We only come here if signals
- * were previously set anyway.
+ * On interrupt, come here to save the partial message in ~/dead.letter.
+ * Then jump out of the collection loop.
  */
  */
-collrub(s)
+/*ARGSUSED*/
+collint(s)
 {
 {
-
-       if (s == SIGINT && hadintr == 0) {
+       /*
+        * the control flow is subtle, because we can be called from ~q.
+        */
+       if (!hadintr) {
+               if (value("ignore") != NOSTR) {
+                       puts("@");
+                       fflush(stdout);
+                       clearerr(stdin);
+                       return;
+               }
                hadintr = 1;
                hadintr = 1;
-               longjmp(coljmp, 1);
+               longjmp(colljmp, 1);
        }
        rewind(collf);
        }
        rewind(collf);
-       if (s != SIGINT || value("nosave") == NOSTR)
+       if (value("nosave") == NOSTR)
                savedeadletter(collf);
                savedeadletter(collf);
-       fclose(collf);
-       signal(SIGINT, saveint);
-       signal(SIGHUP, savehup);
-       signal(SIGCONT, savecont);
-       if (rcvmode) {
-               if (s == SIGHUP)
-                       hangup(SIGHUP);
-               else
-                       stop(s);
-       } else
-               exit(1);
+       longjmp(collabort, 1);
+}
+
+/*ARGSUSED*/
+collhup(s)
+{
+       rewind(collf);
+       savedeadletter(collf);
+       /*
+        * Let's pretend nobody else wants to clean up,
+        * a true statement at this time.
+        */
+       exit(1);
 }
 
 savedeadletter(fp)
 }
 
 savedeadletter(fp)
@@ -575,23 +591,11 @@ savedeadletter(fp)
        cp = getdeadletter();
        c = umask(077);
        dbuf = fopen(cp, "a");
        cp = getdeadletter();
        c = umask(077);
        dbuf = fopen(cp, "a");
-       umask(c);
+       (void) umask(c);
        if (dbuf == NULL)
                return;
        while ((c = getc(fp)) != EOF)
        if (dbuf == NULL)
                return;
        while ((c = getc(fp)) != EOF)
-               putc(c, dbuf);
+               (void) putc(c, dbuf);
        fclose(dbuf);
        rewind(fp);
 }
        fclose(dbuf);
        rewind(fp);
 }
-
-/*
- * Acknowledge an interrupt signal from the tty by typing an @
- */
-/*ARGSUSED*/
-intack(s)
-{
-
-       puts("@");
-       fflush(stdout);
-       clearerr(stdin);
-}
index bcfc75b..8f428ef 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)fio.c      5.19 (Berkeley) %G%";
+static char sccsid[] = "@(#)fio.c      5.20 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "rcv.h"
 #endif /* not lint */
 
 #include "rcv.h"
@@ -72,7 +72,7 @@ setptr(ibuf)
                        return;
                }
                count = strlen(linebuf);
                        return;
                }
                count = strlen(linebuf);
-               fwrite(linebuf, sizeof *linebuf, count, otf);
+               (void) fwrite(linebuf, sizeof *linebuf, count, otf);
                if (ferror(otf)) {
                        perror("/tmp");
                        exit(1);
                if (ferror(otf)) {
                        perror("/tmp");
                        exit(1);
@@ -130,8 +130,8 @@ putline(obuf, linebuf)
        register int c;
 
        c = strlen(linebuf);
        register int c;
 
        c = strlen(linebuf);
-       fwrite(linebuf, sizeof *linebuf, c, obuf);
-       putc('\n', obuf);
+       (void) fwrite(linebuf, sizeof *linebuf, c, obuf);
+       (void) putc('\n', obuf);
        if (ferror(obuf))
                return (-1);
        return (c + 1);
        if (ferror(obuf))
                return (-1);
        return (c + 1);
@@ -191,7 +191,7 @@ makemessage(f)
        dot = message;
        size -= sizeof (struct message);
        fflush(f);
        dot = message;
        size -= sizeof (struct message);
        fflush(f);
-       lseek(fileno(f), (long) sizeof *message, 0);
+       (void) lseek(fileno(f), (long) sizeof *message, 0);
        if (read(fileno(f), (char *) message, size) != size)
                panic("Message temporary file corrupted");
        message[msgCount].m_size = 0;
        if (read(fileno(f), (char *) message, size) != size)
                panic("Message temporary file corrupted");
        message[msgCount].m_size = 0;
@@ -228,116 +228,6 @@ remove(name)
        return unlink(name);
 }
 
        return unlink(name);
 }
 
-/*
- * Terminate an editing session by attempting to write out the user's
- * file from the temporary.  Save any new stuff appended to the file.
- */
-edstop()
-{
-       register int gotcha, c;
-       register struct message *mp;
-       FILE *obuf, *ibuf, *readstat;
-       struct stat statb;
-       char tempname[30];
-       char *mktemp();
-
-       if (readonly)
-               return;
-       holdsigs();
-       if (Tflag != NOSTR) {
-               if ((readstat = fopen(Tflag, "w")) == NULL)
-                       Tflag = NOSTR;
-       }
-       for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) {
-               if (mp->m_flag & MNEW) {
-                       mp->m_flag &= ~MNEW;
-                       mp->m_flag |= MSTATUS;
-               }
-               if (mp->m_flag & (MODIFY|MDELETED|MSTATUS))
-                       gotcha++;
-               if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
-                       char *id;
-
-                       if ((id = hfield("article-id", mp)) != NOSTR)
-                               fprintf(readstat, "%s\n", id);
-               }
-       }
-       if (Tflag != NOSTR)
-               fclose(readstat);
-       if (!gotcha || Tflag != NOSTR)
-               goto done;
-       ibuf = NULL;
-       if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) {
-               strcpy(tempname, "/tmp/mboxXXXXXX");
-               mktemp(tempname);
-               if ((obuf = fopen(tempname, "w")) == NULL) {
-                       perror(tempname);
-                       relsesigs();
-                       reset(0);
-               }
-               if ((ibuf = fopen(mailname, "r")) == NULL) {
-                       perror(mailname);
-                       fclose(obuf);
-                       remove(tempname);
-                       relsesigs();
-                       reset(0);
-               }
-               fseek(ibuf, mailsize, 0);
-               while ((c = getc(ibuf)) != EOF)
-                       putc(c, obuf);
-               fclose(ibuf);
-               fclose(obuf);
-               if ((ibuf = fopen(tempname, "r")) == NULL) {
-                       perror(tempname);
-                       remove(tempname);
-                       relsesigs();
-                       reset(0);
-               }
-               remove(tempname);
-       }
-       printf("\"%s\" ", mailname);
-       fflush(stdout);
-       if ((obuf = fopen(mailname, "r+")) == NULL) {
-               perror(mailname);
-               relsesigs();
-               reset(0);
-       }
-       trunc(obuf);
-       c = 0;
-       for (mp = &message[0]; mp < &message[msgCount]; mp++) {
-               if ((mp->m_flag & MDELETED) != 0)
-                       continue;
-               c++;
-               if (send(mp, obuf, (struct ignoretab *) NULL, NOSTR) < 0) {
-                       perror(mailname);
-                       relsesigs();
-                       reset(0);
-               }
-       }
-       gotcha = (c == 0 && ibuf == NULL);
-       if (ibuf != NULL) {
-               while ((c = getc(ibuf)) != EOF)
-                       putc(c, obuf);
-               fclose(ibuf);
-       }
-       fflush(obuf);
-       if (ferror(obuf)) {
-               perror(mailname);
-               relsesigs();
-               reset(0);
-       }
-       fclose(obuf);
-       if (gotcha) {
-               remove(mailname);
-               printf("removed\n");
-       } else
-               printf("complete\n");
-       fflush(stdout);
-
-done:
-       relsesigs();
-}
-
 static int sigdepth;           /* depth of holdsigs() */
 static int omask;
 /*
 static int sigdepth;           /* depth of holdsigs() */
 static int omask;
 /*
index 64a8f05..c56951d 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)lex.c      5.16 (Berkeley) %G%";
+static char sccsid[] = "@(#)lex.c      5.17 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "rcv.h"
 #endif /* not lint */
 
 #include "rcv.h"
@@ -48,10 +48,13 @@ setfile(name, isedit)
        extern char tempMesg[];
        extern int errno;
 
        extern char tempMesg[];
        extern int errno;
 
-       if ((ibuf = fopen(name, "r")) == NULL)
+       if ((ibuf = fopen(name, "r")) == NULL) {
+               perror(name);
                return(-1);
                return(-1);
+       }
 
        if (fstat(fileno(ibuf), &stb) < 0) {
 
        if (fstat(fileno(ibuf), &stb) < 0) {
+               perror("fstat");
                fclose(ibuf);
                return (-1);
        }
                fclose(ibuf);
                return (-1);
        }
@@ -60,6 +63,7 @@ setfile(name, isedit)
        case S_IFDIR:
                fclose(ibuf);
                errno = EISDIR;
        case S_IFDIR:
                fclose(ibuf);
                errno = EISDIR;
+               perror(name);
                return (-1);
 
        case S_IFREG:
                return (-1);
 
        case S_IFREG:
@@ -68,14 +72,10 @@ setfile(name, isedit)
        default:
                fclose(ibuf);
                errno = EINVAL;
        default:
                fclose(ibuf);
                errno = EINVAL;
+               perror(name);
                return (-1);
        }
 
                return (-1);
        }
 
-       if (!edit && stb.st_size == 0) {
-               fclose(ibuf);
-               return(-1);
-       }
-
        /*
         * Looks like all will be well.  We must now relinquish our
         * hold on the current set of stuff.  Must hold signals
        /*
         * Looks like all will be well.  We must now relinquish our
         * hold on the current set of stuff.  Must hold signals
@@ -84,12 +84,8 @@ setfile(name, isedit)
         */
 
        holdsigs();
         */
 
        holdsigs();
-       if (shudclob) {
-               if (edit)
-                       edstop();
-               else
-                       quit();
-       }
+       if (shudclob)
+               quit();
 
        /*
         * Copy the messages into /tmp
 
        /*
         * Copy the messages into /tmp
@@ -127,74 +123,51 @@ setfile(name, isedit)
        return(0);
 }
 
        return(0);
 }
 
+int    *msgvec;
+int    reset_on_stop;                  /* do a reset() if stopped */
+
 /*
  * Interpret user commands one by one.  If standard input is not a tty,
  * print no prompt.
  */
 /*
  * Interpret user commands one by one.  If standard input is not a tty,
  * print no prompt.
  */
-
-int    *msgvec;
-jmp_buf        commjmp;
-
 commands()
 {
 commands()
 {
-       int eofloop, stop();
+       int eofloop = 0;
        register int n;
        char linebuf[LINESIZE];
        register int n;
        char linebuf[LINESIZE];
-       int hangup(), contin();
+       int intr(), stop(), hangup(), contin();
 
 
-       signal(SIGCONT, SIG_DFL);
-       if (rcvmode && !sourcing) {
+       if (!sourcing) {
                if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                if (signal(SIGINT, SIG_IGN) != SIG_IGN)
-                       signal(SIGINT, stop);
+                       signal(SIGINT, intr);
                if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                        signal(SIGHUP, hangup);
                if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                        signal(SIGHUP, hangup);
+               signal(SIGTSTP, stop);
+               signal(SIGTTOU, stop);
+               signal(SIGTTIN, stop);
        }
        }
+       setexit();
        for (;;) {
        for (;;) {
-               setexit();
-
                /*
                 * Print the prompt, if needed.  Clear out
                 * string space, and flush the output.
                 */
                /*
                 * Print the prompt, if needed.  Clear out
                 * string space, and flush the output.
                 */
-
-               if (!rcvmode && !sourcing)
-                       return;
-               eofloop = 0;
-top:
                if (!sourcing && value("interactive") != NOSTR) {
                if (!sourcing && value("interactive") != NOSTR) {
-                       setjmp(commjmp);
-                       signal(SIGCONT, contin);
+                       reset_on_stop = 1;
                        printf(prompt);
                }
                fflush(stdout);
                sreset();
                        printf(prompt);
                }
                fflush(stdout);
                sreset();
-
                /*
                 * Read a line of commands from the current input
                 * and handle end of file specially.
                 */
                /*
                 * Read a line of commands from the current input
                 * and handle end of file specially.
                 */
-
                n = 0;
                for (;;) {
                n = 0;
                for (;;) {
-                       if (readline(input, &linebuf[n]) < 0) {
-                               if (n != 0)
-                                       break;
-                               if (loading)
-                                       return;
-                               if (sourcing) {
-                                       unstack();
-                                       goto more;
-                               }
-                               if (value("interactive") != NOSTR &&
-                                   value("ignoreeof") != NOSTR) {
-                                       if (++eofloop < 25) {
-                                               printf("Use \"quit\" to quit.\n");
-                                               goto top;
-                                       }
-                               }
-                               if (edit)
-                                       edstop();
-                               return;
+                       if (readline(input, &linebuf[n], LINESIZE - n) < 0) {
+                               if (n == 0)
+                                       n = -1;
+                               break;
                        }
                        if ((n = strlen(linebuf)) == 0)
                                break;
                        }
                        if ((n = strlen(linebuf)) == 0)
                                break;
@@ -203,20 +176,36 @@ top:
                                break;
                        linebuf[n++] = ' ';
                }
                                break;
                        linebuf[n++] = ' ';
                }
-               signal(SIGCONT, SIG_DFL);
+               reset_on_stop = 0;
+               if (n < 0) {
+                               /* eof */
+                       if (loading)
+                               break;
+                       if (sourcing) {
+                               unstack();
+                               continue;
+                       }
+                       if (value("interactive") != NOSTR &&
+                           value("ignoreeof") != NOSTR &&
+                           ++eofloop < 25) {
+                               printf("Use \"quit\" to quit.\n");
+                               continue;
+                       }
+                       break;
+               }
+               eofloop = 0;
                if (execute(linebuf, 0))
                if (execute(linebuf, 0))
-                       return;
-more:          ;
+                       break;
        }
 }
 
 /*
        }
 }
 
 /*
- * Execute a single command.  If the command executed
- * is "quit," then return non-zero so that the caller
- * will know to return back to main, if he cares.
+ * Execute a single command.
+ * Command functions return 0 for success, 1 for error, and -1
+ * for abort.  A 1 or -1 aborts a load or source.  A -1 aborts
+ * the interactive command loop.
  * Contxt is non-zero if called while composing mail.
  */
  * Contxt is non-zero if called while composing mail.
  */
-
 execute(linebuf, contxt)
        char linebuf[];
 {
 execute(linebuf, contxt)
        char linebuf[];
 {
@@ -226,7 +215,7 @@ execute(linebuf, contxt)
        register char *cp, *cp2;
        register int c;
        int muvec[2];
        register char *cp, *cp2;
        register int c;
        int muvec[2];
-       int edstop(), e;
+       int e = 1;
 
        /*
         * Strip the white space away from the beginning
 
        /*
         * Strip the white space away from the beginning
@@ -242,8 +231,7 @@ execute(linebuf, contxt)
        if (*cp == '!') {
                if (sourcing) {
                        printf("Can't \"!\" while sourcing\n");
        if (*cp == '!') {
                if (sourcing) {
                        printf("Can't \"!\" while sourcing\n");
-                       unstack();
-                       return(0);
+                       goto out;
                }
                shell(cp+1);
                return(0);
                }
                shell(cp+1);
                return(0);
@@ -266,11 +254,7 @@ execute(linebuf, contxt)
        com = lex(word);
        if (com == NONE) {
                printf("Unknown command: \"%s\"\n", word);
        com = lex(word);
        if (com == NONE) {
                printf("Unknown command: \"%s\"\n", word);
-               if (loading)
-                       return(1);
-               if (sourcing)
-                       unstack();
-               return(0);
+               goto out;
        }
 
        /*
        }
 
        /*
@@ -282,23 +266,6 @@ execute(linebuf, contxt)
                if (cond == CRCV && !rcvmode || cond == CSEND && rcvmode)
                        return(0);
 
                if (cond == CRCV && !rcvmode || cond == CSEND && rcvmode)
                        return(0);
 
-       /*
-        * Special case so that quit causes a return to
-        * main, who will call the quit code directly.
-        * If we are in a source file, just unstack.
-        */
-
-       if (com->c_func == edstop && sourcing) {
-               if (loading)
-                       return(1);
-               unstack();
-               return(0);
-       }
-       if (!edit && com->c_func == edstop) {
-               signal(SIGINT, SIG_IGN);
-               return(1);
-       }
-
        /*
         * Process the arguments to the command, depending
         * on the type he expects.  Default to an error.
        /*
         * Process the arguments to the command, depending
         * on the type he expects.  Default to an error.
@@ -309,34 +276,22 @@ execute(linebuf, contxt)
        if (!rcvmode && (com->c_argtype & M) == 0) {
                printf("May not execute \"%s\" while sending\n",
                    com->c_name);
        if (!rcvmode && (com->c_argtype & M) == 0) {
                printf("May not execute \"%s\" while sending\n",
                    com->c_name);
-               if (loading)
-                       return(1);
-               if (sourcing)
-                       unstack();
-               return(0);
+               goto out;
        }
        if (sourcing && com->c_argtype & I) {
                printf("May not execute \"%s\" while sourcing\n",
                    com->c_name);
        }
        if (sourcing && com->c_argtype & I) {
                printf("May not execute \"%s\" while sourcing\n",
                    com->c_name);
-               if (loading)
-                       return(1);
-               unstack();
-               return(0);
+               goto out;
        }
        if (readonly && com->c_argtype & W) {
                printf("May not execute \"%s\" -- message file is read only\n",
                   com->c_name);
        }
        if (readonly && com->c_argtype & W) {
                printf("May not execute \"%s\" -- message file is read only\n",
                   com->c_name);
-               if (loading)
-                       return(1);
-               if (sourcing)
-                       unstack();
-               return(0);
+               goto out;
        }
        if (contxt && com->c_argtype & R) {
                printf("Cannot recursively invoke \"%s\"\n", com->c_name);
        }
        if (contxt && com->c_argtype & R) {
                printf("Cannot recursively invoke \"%s\"\n", com->c_name);
-               return(0);
+               goto out;
        }
        }
-       e = 1;
        switch (com->c_argtype & ~(F|P|I|M|T|W|R)) {
        case MSGLIST:
                /*
        switch (com->c_argtype & ~(F|P|I|M|T|W|R)) {
        case MSGLIST:
                /*
@@ -345,7 +300,7 @@ execute(linebuf, contxt)
                 */
                if (msgvec == 0) {
                        printf("Illegal use of \"message list\"\n");
                 */
                if (msgvec == 0) {
                        printf("Illegal use of \"message list\"\n");
-                       return(-1);
+                       break;
                }
                if ((c = getmsglist(cp, msgvec, com->c_msgflag)) < 0)
                        break;
                }
                if ((c = getmsglist(cp, msgvec, com->c_msgflag)) < 0)
                        break;
@@ -368,7 +323,7 @@ execute(linebuf, contxt)
                 */
                if (msgvec == 0) {
                        printf("Illegal use of \"message list\"\n");
                 */
                if (msgvec == 0) {
                        printf("Illegal use of \"message list\"\n");
-                       return(-1);
+                       break;
                }
                if (getmsglist(cp, msgvec, com->c_msgflag) < 0)
                        break;
                }
                if (getmsglist(cp, msgvec, com->c_msgflag) < 0)
                        break;
@@ -417,17 +372,20 @@ execute(linebuf, contxt)
                panic("Unknown argtype");
        }
 
                panic("Unknown argtype");
        }
 
+out:
        /*
         * Exit the current source file on
         * error.
         */
        /*
         * Exit the current source file on
         * error.
         */
-
-       if (e && loading)
-               return(1);
-       if (e && sourcing)
-               unstack();
-       if (com->c_func == edstop)
-               return(1);
+       if (e) {
+               if (e < 0)
+                       return 1;
+               if (loading)
+                       return 1;
+               if (sourcing)
+                       unstack();
+               return 0;
+       }
        if (value("autoprint") != NOSTR && com->c_argtype & P)
                if ((dot->m_flag & MDELETED) == 0) {
                        muvec[0] = dot - &message[0] + 1;
        if (value("autoprint") != NOSTR && com->c_argtype & P)
                if ((dot->m_flag & MDELETED) == 0) {
                        muvec[0] = dot - &message[0] + 1;
@@ -439,27 +397,6 @@ execute(linebuf, contxt)
        return(0);
 }
 
        return(0);
 }
 
-/*
- * When we wake up after ^Z, reprint the prompt.
- */
-/*ARGSUSED*/
-contin(s)
-{
-
-       longjmp(commjmp, 1);
-}
-
-/*
- * Branch here on hangup signal and simulate "exit".
- */
-/*ARGSUSED*/
-hangup(s)
-{
-
-       /* nothing to do? */
-       exit(0);
-}
-
 /*
  * Set the size of the message vector used to construct argument
  * lists to message list functions.
 /*
  * Set the size of the message vector used to construct argument
  * lists to message list functions.
@@ -542,13 +479,13 @@ xclose(iop)
        if (iop != pipef)
                fclose(iop);
        else {
        if (iop != pipef)
                fclose(iop);
        else {
-               pclose(pipef);
+               Pclose(pipef);
                pipef = NULL;
        }
 }
 
 /*ARGSUSED*/
                pipef = NULL;
        }
 }
 
 /*ARGSUSED*/
-stop(s)
+intr(s)
 {
 
        noreset = 0;
 {
 
        noreset = 0;
@@ -571,6 +508,34 @@ stop(s)
        reset(0);
 }
 
        reset(0);
 }
 
+/*
+ * When we wake up after ^Z, reprint the prompt.
+ */
+stop(s)
+{
+       int (*old_action)() = signal(s, SIG_DFL);
+
+       sigsetmask(sigblock(0) & ~sigmask(s));
+       kill(0, s);
+       sigblock(sigmask(s));
+       signal(s, old_action);
+       if (reset_on_stop) {
+               reset_on_stop = 0;
+               reset(0);
+       }
+}
+
+/*
+ * Branch here on hangup signal and simulate "exit".
+ */
+/*ARGSUSED*/
+hangup(s)
+{
+
+       /* nothing to do? */
+       exit(1);
+}
+
 /*
  * Announce the presence of the current Mail version,
  * give the message count, and print a header listing.
 /*
  * Announce the presence of the current Mail version,
  * give the message count, and print a header listing.
index fa89893..5db1a9c 100644 (file)
@@ -22,7 +22,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     5.19 (Berkeley) %G%";
+static char sccsid[] = "@(#)main.c     5.20 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "rcv.h"
 #endif /* not lint */
 
 #include "rcv.h"
@@ -44,6 +44,7 @@ main(argc, argv)
        char *subject;
        char *ef;
        char nosrc = 0;
        char *subject;
        char *ef;
        char nosrc = 0;
+       char isedit = 0;
        int hdrstop(), (*prevint)();
        int sigchild();
        extern int getopt(), optind, opterr;
        int hdrstop(), (*prevint)();
        int sigchild();
        extern int getopt(), optind, opterr;
@@ -209,16 +210,13 @@ Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
         * the system mailbox, and open up the right stuff.
         */
        if (ef != NOSTR)
         * the system mailbox, and open up the right stuff.
         */
        if (ef != NOSTR)
-               edit++;
+               isedit++;
        else
                ef = "%";
        else
                ef = "%";
-       if ((ef = expand(ef)) == NOSTR)
+       if ((ef = expand(ef)) == NOSTR || setfile(ef, isedit) < 0)
                exit(1);                /* error already reported */
                exit(1);                /* error already reported */
-       if (setfile(ef, edit) < 0) {
-               if (edit)
-                       perror(ef);
-               else
-                       fprintf(stderr, "No mail for %s\n", myname);
+       if (!edit && msgCount == 0) {
+               fprintf(stderr, "No mail for %s\n", myname);
                exit(1);
        }
        if (setjmp(hdrjmp) == 0) {
                exit(1);
        }
        if (setjmp(hdrjmp) == 0) {
@@ -233,18 +231,11 @@ Usage: mail [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
                fflush(stdout);
                signal(SIGINT, prevint);
        }
                fflush(stdout);
                signal(SIGINT, prevint);
        }
-       if (!edit && msgCount == 0) {
-               printf("No mail\n");
-               fflush(stdout);
-               exit(0);
-       }
        commands();
        commands();
-       if (!edit) {
-               signal(SIGHUP, SIG_IGN);
-               signal(SIGINT, SIG_IGN);
-               signal(SIGQUIT, SIG_IGN);
-               quit();
-       }
+       signal(SIGHUP, SIG_IGN);
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       quit();
        exit(0);
 }
 
        exit(0);
 }
 
index 09044f0..a4b1ee2 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)quit.c     5.10 (Berkeley) %G%";
+static char sccsid[] = "@(#)quit.c     5.11 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "rcv.h"
 #endif /* not lint */
 
 #include "rcv.h"
@@ -29,6 +29,20 @@ static char sccsid[] = "@(#)quit.c   5.10 (Berkeley) %G%";
  * Termination processing.
  */
 
  * Termination processing.
  */
 
+/*
+ * The "quit" command.
+ */
+quitcmd()
+{
+       /*
+        * If we are sourcing, then return 1 so execute() can handle it.
+        * Otherwise, return -1 to abort command loop.
+        */
+       if (sourcing)
+               return 1;
+       return -1;
+}
+
 /*
  * Save all of the undetermined messages at the top of "mbox"
  * Save all untouched messages back in the system mailbox.
 /*
  * Save all of the undetermined messages at the top of "mbox"
  * Save all untouched messages back in the system mailbox.
@@ -49,9 +63,17 @@ quit()
         * If we are read only, we can't do anything,
         * so just return quickly.
         */
         * If we are read only, we can't do anything,
         * so just return quickly.
         */
-
        if (readonly)
                return;
        if (readonly)
                return;
+       /*
+        * If editing (not reading system mail box), then do the work
+        * in edstop()
+        */
+       if (edit) {
+               edstop();
+               return;
+       }
+
        /*
         * See if there any messages to save in mbox.  If no, we
         * can save copying mbox to /tmp and back.
        /*
         * See if there any messages to save in mbox.  If no, we
         * can save copying mbox to /tmp and back.
@@ -75,14 +97,14 @@ quit()
 #ifdef APPEND
                fseek(fbuf, mailsize, 0);
                while ((c = getc(fbuf)) != EOF)
 #ifdef APPEND
                fseek(fbuf, mailsize, 0);
                while ((c = getc(fbuf)) != EOF)
-                       putc(c, rbuf);
+                       (void) putc(c, rbuf);
 #else
                p = minfo.st_size - mailsize;
                while (p-- > 0) {
                        c = getc(fbuf);
                        if (c == EOF)
                                goto newmail;
 #else
                p = minfo.st_size - mailsize;
                while (p-- > 0) {
                        c = getc(fbuf);
                        if (c == EOF)
                                goto newmail;
-                       putc(c, rbuf);
+                       (void) putc(c, rbuf);
                }
 #endif
                fclose(rbuf);
                }
 #endif
                fclose(rbuf);
@@ -174,7 +196,7 @@ quit()
                remove(tempQuit);
                if ((abuf = fopen(mbox, "r")) != NULL) {
                        while ((c = getc(abuf)) != EOF)
                remove(tempQuit);
                if ((abuf = fopen(mbox, "r")) != NULL) {
                        while ((c = getc(abuf)) != EOF)
-                               putc(c, obuf);
+                               (void) putc(c, obuf);
                        fclose(abuf);
                }
                if (ferror(obuf)) {
                        fclose(abuf);
                }
                if (ferror(obuf)) {
@@ -221,7 +243,7 @@ quit()
                rewind(ibuf);
                c = getc(ibuf);
                while (c != EOF) {
                rewind(ibuf);
                c = getc(ibuf);
                while (c != EOF) {
-                       putc(c, obuf);
+                       (void) putc(c, obuf);
                        if (ferror(obuf))
                                break;
                        c = getc(ibuf);
                        if (ferror(obuf))
                                break;
                        c = getc(ibuf);
@@ -264,7 +286,7 @@ cream:
                if (abuf == NULL)
                        goto newmail;
                while ((c = getc(rbuf)) != EOF)
                if (abuf == NULL)
                        goto newmail;
                while ((c = getc(rbuf)) != EOF)
-                       putc(c, abuf);
+                       (void) putc(c, abuf);
                fclose(rbuf);
                trunc(abuf);
                fclose(abuf);
                fclose(rbuf);
                trunc(abuf);
                fclose(abuf);
@@ -303,7 +325,7 @@ writeback(res)
 #ifndef APPEND
        if (res != NULL)
                while ((c = getc(res)) != EOF)
 #ifndef APPEND
        if (res != NULL)
                while ((c = getc(res)) != EOF)
-                       putc(c, obuf);
+                       (void) putc(c, obuf);
 #endif
        for (mp = &message[0]; mp < &message[msgCount]; mp++)
                if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
 #endif
        for (mp = &message[0]; mp < &message[msgCount]; mp++)
                if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
@@ -317,7 +339,7 @@ writeback(res)
 #ifdef APPEND
        if (res != NULL)
                while ((c = getc(res)) != EOF)
 #ifdef APPEND
        if (res != NULL)
                while ((c = getc(res)) != EOF)
-                       putc(c, obuf);
+                       (void) putc(c, obuf);
 #endif
        fflush(obuf);
        trunc(obuf);
 #endif
        fflush(obuf);
        trunc(obuf);
@@ -336,3 +358,113 @@ writeback(res)
                printf("Held %d messages in %s\n", p, mailname);
        return(0);
 }
                printf("Held %d messages in %s\n", p, mailname);
        return(0);
 }
+
+/*
+ * Terminate an editing session by attempting to write out the user's
+ * file from the temporary.  Save any new stuff appended to the file.
+ */
+edstop()
+{
+       register int gotcha, c;
+       register struct message *mp;
+       FILE *obuf, *ibuf, *readstat;
+       struct stat statb;
+       char tempname[30];
+       char *mktemp();
+
+       if (readonly)
+               return;
+       holdsigs();
+       if (Tflag != NOSTR) {
+               if ((readstat = fopen(Tflag, "w")) == NULL)
+                       Tflag = NOSTR;
+       }
+       for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) {
+               if (mp->m_flag & MNEW) {
+                       mp->m_flag &= ~MNEW;
+                       mp->m_flag |= MSTATUS;
+               }
+               if (mp->m_flag & (MODIFY|MDELETED|MSTATUS))
+                       gotcha++;
+               if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
+                       char *id;
+
+                       if ((id = hfield("article-id", mp)) != NOSTR)
+                               fprintf(readstat, "%s\n", id);
+               }
+       }
+       if (Tflag != NOSTR)
+               fclose(readstat);
+       if (!gotcha || Tflag != NOSTR)
+               goto done;
+       ibuf = NULL;
+       if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) {
+               strcpy(tempname, "/tmp/mboxXXXXXX");
+               mktemp(tempname);
+               if ((obuf = fopen(tempname, "w")) == NULL) {
+                       perror(tempname);
+                       relsesigs();
+                       reset(0);
+               }
+               if ((ibuf = fopen(mailname, "r")) == NULL) {
+                       perror(mailname);
+                       fclose(obuf);
+                       remove(tempname);
+                       relsesigs();
+                       reset(0);
+               }
+               fseek(ibuf, mailsize, 0);
+               while ((c = getc(ibuf)) != EOF)
+                       (void) putc(c, obuf);
+               fclose(ibuf);
+               fclose(obuf);
+               if ((ibuf = fopen(tempname, "r")) == NULL) {
+                       perror(tempname);
+                       remove(tempname);
+                       relsesigs();
+                       reset(0);
+               }
+               remove(tempname);
+       }
+       printf("\"%s\" ", mailname);
+       fflush(stdout);
+       if ((obuf = fopen(mailname, "r+")) == NULL) {
+               perror(mailname);
+               relsesigs();
+               reset(0);
+       }
+       trunc(obuf);
+       c = 0;
+       for (mp = &message[0]; mp < &message[msgCount]; mp++) {
+               if ((mp->m_flag & MDELETED) != 0)
+                       continue;
+               c++;
+               if (send(mp, obuf, (struct ignoretab *) NULL, NOSTR) < 0) {
+                       perror(mailname);
+                       relsesigs();
+                       reset(0);
+               }
+       }
+       gotcha = (c == 0 && ibuf == NULL);
+       if (ibuf != NULL) {
+               while ((c = getc(ibuf)) != EOF)
+                       (void) putc(c, obuf);
+               fclose(ibuf);
+       }
+       fflush(obuf);
+       if (ferror(obuf)) {
+               perror(mailname);
+               relsesigs();
+               reset(0);
+       }
+       fclose(obuf);
+       if (gotcha) {
+               remove(mailname);
+               printf("removed\n");
+       } else
+               printf("complete\n");
+       fflush(stdout);
+
+done:
+       relsesigs();
+}