document distributed with 4.3BSD
[unix-history] / usr / src / usr.bin / mail / fio.c
index 3a92c27..c195eab 100644 (file)
@@ -1,4 +1,12 @@
-#
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char *sccsid = "@(#)fio.c       5.3 (Berkeley) %G%";
+#endif not lint
 
 #include "rcv.h"
 #include <sys/stat.h>
 
 #include "rcv.h"
 #include <sys/stat.h>
@@ -10,8 +18,6 @@
  * File I/O.
  */
 
  * File I/O.
  */
 
-static char *SccsId = "@(#)fio.c       1.11 %G%";
-
 /*
  * Set up the input pointers while copying the mail file into
  * /tmp.
 /*
  * Set up the input pointers while copying the mail file into
  * /tmp.
@@ -22,7 +28,8 @@ setptr(ibuf)
 {
        register int c;
        register char *cp, *cp2;
 {
        register int c;
        register char *cp, *cp2;
-       register int count, s, l;
+       register int count, l;
+       long s;
        off_t offset;
        char linebuf[LINESIZE];
        char wbuf[LINESIZE];
        off_t offset;
        char linebuf[LINESIZE];
        char wbuf[LINESIZE];
@@ -34,24 +41,12 @@ setptr(ibuf)
                exit(1);
        msgCount = 0;
        offset = 0;
                exit(1);
        msgCount = 0;
        offset = 0;
-       s = 0;
+       s = 0L;
        l = 0;
        maybe = 1;
        flag = MUSED|MNEW;
        for (;;) {
        l = 0;
        maybe = 1;
        flag = MUSED|MNEW;
        for (;;) {
-               cp = linebuf;
-               c = getc(ibuf);
-               while (c != EOF && c != '\n') {
-                       if (cp - linebuf >= BUFSIZ - 1) {
-                               ungetc(c, ibuf);
-                               *cp = 0;
-                               break;
-                       }
-                       *cp++ = c;
-                       c = getc(ibuf);
-               }
-               *cp = 0;
-               if (cp == linebuf && c == EOF) {
+               if (fgets(linebuf, LINESIZE, ibuf) == NULL) {
                        this.m_flag = flag;
                        flag = MUSED|MNEW;
                        this.m_offset = offsetof(offset);
                        this.m_flag = flag;
                        flag = MUSED|MNEW;
                        this.m_offset = offsetof(offset);
@@ -67,10 +62,11 @@ setptr(ibuf)
                        close(mestmp);
                        return;
                }
                        close(mestmp);
                        return;
                }
-               count = cp - linebuf + 1;
-               for (cp = linebuf; *cp;)
-                       putc(*cp++, otf);
-               putc('\n', otf);
+               count = strlen(linebuf);
+               fputs(linebuf, otf);
+               cp = linebuf + (count - 1);
+               if (*cp == '\n')
+                       *cp = 0;
                if (ferror(otf)) {
                        perror("/tmp");
                        exit(1);
                if (ferror(otf)) {
                        perror("/tmp");
                        exit(1);
@@ -84,7 +80,7 @@ setptr(ibuf)
                        this.m_offset = offsetof(offset);
                        this.m_size = s;
                        this.m_lines = l;
                        this.m_offset = offsetof(offset);
                        this.m_size = s;
                        this.m_lines = l;
-                       s = 0;
+                       s = 0L;
                        l = 0;
                        if (append(&this, mestmp)) {
                                perror(tempSet);
                        l = 0;
                        if (append(&this, mestmp)) {
                                perror(tempSet);
@@ -93,14 +89,10 @@ setptr(ibuf)
                }
                if (linebuf[0] == 0)
                        inhead = 0;
                }
                if (linebuf[0] == 0)
                        inhead = 0;
-               if (inhead && index(linebuf, ':')) {
-                       cp = linebuf;
-                       cp2 = wbuf;
-                       while (isalpha(*cp))
-                               *cp2++ = *cp++;
-                       *cp2 = 0;
-                       if (icequal(wbuf, "status")) {
-                               cp = index(linebuf, ':');
+               if (inhead && (cp = index(linebuf, ':'))) {
+                       *cp = 0;
+                       if (icequal(linebuf, "status")) {
+                               ++cp;
                                if (index(cp, 'R'))
                                        flag |= MREAD;
                                if (index(cp, 'O'))
                                if (index(cp, 'R'))
                                        flag |= MREAD;
                                if (index(cp, 'O'))
@@ -109,7 +101,7 @@ setptr(ibuf)
                        }
                }
                offset += count;
                        }
                }
                offset += count;
-               s += count;
+               s += (long) count;
                l++;
                maybe = 0;
                if (linebuf[0] == 0)
                l++;
                maybe = 0;
                if (linebuf[0] == 0)
@@ -137,38 +129,6 @@ putline(obuf, linebuf)
        return(c+1);
 }
 
        return(c+1);
 }
 
-/*
- * Quickly read a line from the specified input into the line
- * buffer; return characters read.
- */
-
-freadline(ibuf, linebuf)
-       register FILE *ibuf;
-       register char *linebuf;
-{
-       register int c;
-       register char *cp;
-
-       c = getc(ibuf);
-       cp = linebuf;
-       while (c != '\n' && c != EOF) {
-               if (c == 0) {
-                       c = getc(ibuf);
-                       continue;
-               }
-               if (cp - linebuf >= BUFSIZ-1) {
-                       *cp = 0;
-                       return(cp - linebuf + 1);
-               }
-               *cp++ = c;
-               c = getc(ibuf);
-       }
-       if (c == EOF && cp == linebuf)
-               return(0);
-       *cp = 0;
-       return(cp - linebuf + 1);
-}
-
 /*
  * Read up a line from the specified input into the line
  * buffer.  Return the number of characters read.  Do not
 /*
  * Read up a line from the specified input into the line
  * buffer.  Return the number of characters read.  Do not
@@ -179,23 +139,15 @@ readline(ibuf, linebuf)
        FILE *ibuf;
        char *linebuf;
 {
        FILE *ibuf;
        char *linebuf;
 {
-       register char *cp;
-       register int c;
+       register int n;
 
 
-       do {
-               clearerr(ibuf);
-               c = getc(ibuf);
-               for (cp = linebuf; c != '\n' && c != EOF; c = getc(ibuf)) {
-                       if (c == 0)
-                               continue;
-                       if (cp - linebuf < LINESIZE-2)
-                               *cp++ = c;
-               }
-       } while (ferror(ibuf) && ibuf == stdin);
-       *cp = 0;
-       if (c == EOF && cp == linebuf)
+       clearerr(ibuf);
+       if (fgets(linebuf, LINESIZE, ibuf) == NULL)
                return(0);
                return(0);
-       return(cp - linebuf + 1);
+       n = strlen(linebuf);
+       if (n >= 1 && linebuf[n-1] == '\n')
+               linebuf[n-1] = '\0';
+       return(n);
 }
 
 /*
 }
 
 /*
@@ -248,7 +200,7 @@ makemessage(f)
                m->m_lines = (m+1)->m_lines;
                m->m_flag = (m+1)->m_flag;
        }
                m->m_lines = (m+1)->m_lines;
                m->m_flag = (m+1)->m_flag;
        }
-       message[msgCount].m_size = 0;
+       message[msgCount].m_size = 0L;
        message[msgCount].m_lines = 0;
 }
 
        message[msgCount].m_lines = 0;
 }
 
@@ -292,25 +244,33 @@ edstop()
 {
        register int gotcha, c;
        register struct message *mp;
 {
        register int gotcha, c;
        register struct message *mp;
-       FILE *obuf, *ibuf;
+       FILE *obuf, *ibuf, *readstat;
        struct stat statb;
        struct stat statb;
-       char tempname[30];
+       char tempname[30], *id;
        int (*sigs[3])();
 
        if (readonly)
                return;
        holdsigs();
        int (*sigs[3])();
 
        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;
                }
        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)) {
+               if (mp->m_flag & (MODIFY|MDELETED|MSTATUS))
                        gotcha++;
                        gotcha++;
-                       break;
+               if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
+                       if ((id = hfield("article-id", mp)) != NOSTR)
+                               fprintf(readstat, "%s\n", id);
                }
        }
                }
        }
-       if (!gotcha)
+       if (Tflag != NOSTR)
+               fclose(readstat);
+       if (!gotcha || Tflag != NOSTR)
                goto done;
        ibuf = NULL;
        if (stat(editfile, &statb) >= 0 && statb.st_size > mailsize) {
                goto done;
        ibuf = NULL;
        if (stat(editfile, &statb) >= 0 && statb.st_size > mailsize) {
@@ -328,6 +288,7 @@ edstop()
                        relsesigs();
                        reset(0);
                }
                        relsesigs();
                        reset(0);
                }
+               fseek(ibuf, mailsize, 0);
                while ((c = getc(ibuf)) != EOF)
                        putc(c, obuf);
                fclose(ibuf);
                while ((c = getc(ibuf)) != EOF)
                        putc(c, obuf);
                fclose(ibuf);
@@ -341,18 +302,19 @@ edstop()
                remove(tempname);
        }
        printf("\"%s\" ", editfile);
                remove(tempname);
        }
        printf("\"%s\" ", editfile);
-       flush();
-       if ((obuf = fopen(editfile, "w")) == NULL) {
+       fflush(stdout);
+       if ((obuf = fopen(editfile, "r+")) == NULL) {
                perror(editfile);
                relsesigs();
                reset(0);
        }
                perror(editfile);
                relsesigs();
                reset(0);
        }
+       trunc(obuf);
        c = 0;
        for (mp = &message[0]; mp < &message[msgCount]; mp++) {
                if ((mp->m_flag & MDELETED) != 0)
                        continue;
                c++;
        c = 0;
        for (mp = &message[0]; mp < &message[msgCount]; mp++) {
                if ((mp->m_flag & MDELETED) != 0)
                        continue;
                c++;
-               if (send(mp, obuf) < 0) {
+               if (send(mp, obuf, 0) < 0) {
                        perror(editfile);
                        relsesigs();
                        reset(0);
                        perror(editfile);
                        relsesigs();
                        reset(0);
@@ -377,12 +339,14 @@ edstop()
        }
        else
                printf("complete\n");
        }
        else
                printf("complete\n");
-       flush();
+       fflush(stdout);
 
 done:
        relsesigs();
 }
 
 
 done:
        relsesigs();
 }
 
+static int sigdepth = 0;               /* depth of holdsigs() */
+static int omask = 0;
 /*
  * Hold signals SIGHUP - SIGQUIT.
  */
 /*
  * Hold signals SIGHUP - SIGQUIT.
  */
@@ -390,8 +354,8 @@ holdsigs()
 {
        register int i;
 
 {
        register int i;
 
-       for (i = SIGHUP; i <= SIGQUIT; i++)
-               sighold(i);
+       if (sigdepth++ == 0)
+               omask = sigblock(sigmask(SIGHUP)|sigmask(SIGINT)|sigmask(SIGQUIT));
 }
 
 /*
 }
 
 /*
@@ -401,21 +365,8 @@ relsesigs()
 {
        register int i;
 
 {
        register int i;
 
-       for (i = SIGHUP; i <= SIGQUIT; i++)
-               sigrelse(i);
-}
-
-/*
- * Empty the output buffer.
- */
-
-clrbuf(buf)
-       register FILE *buf;
-{
-
-       buf = stdout;
-       buf->_ptr = buf->_base;
-       buf->_cnt = BUFSIZ;
+       if (--sigdepth == 0)
+               sigsetmask(omask);
 }
 
 /*
 }
 
 /*
@@ -442,16 +393,6 @@ opentemp(file)
        return(f);
 }
 
        return(f);
 }
 
-/*
- * Flush the standard output.
- */
-
-flush()
-{
-       fflush(stdout);
-       fflush(stderr);
-}
-
 /*
  * Determine the size of the file possessed by
  * the passed buffer.
 /*
  * Determine the size of the file possessed by
  * the passed buffer.
@@ -487,6 +428,10 @@ expand(name)
        int s, pivec[2], (*sigint)();
        struct stat sbuf;
 
        int s, pivec[2], (*sigint)();
        struct stat sbuf;
 
+       if (name[0] == '+' && getfold(cmdbuf) >= 0) {
+               sprintf(xname, "%s/%s", cmdbuf, name + 1);
+               return(expand(savestr(xname)));
+       }
        if (!anyof(name, "~{[*?$`'\"\\"))
                return(name);
        if (pipe(pivec) < 0) {
        if (!anyof(name, "~{[*?$`'\"\\"))
                return(name);
        if (pipe(pivec) < 0) {
@@ -495,6 +440,7 @@ expand(name)
        }
        sprintf(cmdbuf, "echo %s", name);
        if ((pid = vfork()) == 0) {
        }
        sprintf(cmdbuf, "echo %s", name);
        if ((pid = vfork()) == 0) {
+               sigchild();
                Shell = value("SHELL");
                if (Shell == NOSTR)
                        Shell = SHELL;
                Shell = value("SHELL");
                if (Shell == NOSTR)
                        Shell = SHELL;
@@ -548,6 +494,23 @@ err:
        return(NOSTR);
 }
 
        return(NOSTR);
 }
 
+/*
+ * Determine the current folder directory name.
+ */
+getfold(name)
+       char *name;
+{
+       char *folder;
+
+       if ((folder = value("folder")) == NOSTR)
+               return(-1);
+       if (*folder == '/')
+               strcpy(name, folder);
+       else
+               sprintf(name, "%s/%s", homedir, folder);
+       return(0);
+}
+
 /*
  * A nicer version of Fdopen, which allows us to fclose
  * without losing the open file.
 /*
  * A nicer version of Fdopen, which allows us to fclose
  * without losing the open file.