X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/de9a3738c9c7dbd2b92691d29dbe91d1777fe031..f5df67b9d303ea4b226de26e833d54ed794941a3:/usr/src/usr.bin/mail/fio.c diff --git a/usr/src/usr.bin/mail/fio.c b/usr/src/usr.bin/mail/fio.c index 29df639090..a40e0a20d6 100644 --- a/usr/src/usr.bin/mail/fio.c +++ b/usr/src/usr.bin/mail/fio.c @@ -10,7 +10,7 @@ * File I/O. */ -static char *SccsId = "@(#)fio.c 1.6 %G%"; +static char *SccsId = "@(#)fio.c 2.13 %G%"; /* * Set up the input pointers while copying the mail file into @@ -20,8 +20,10 @@ static char *SccsId = "@(#)fio.c 1.6 %G%"; setptr(ibuf) FILE *ibuf; { - register int count, s, l; + register int c; register char *cp, *cp2; + register int count, l; + long s; off_t offset; char linebuf[LINESIZE]; char wbuf[LINESIZE]; @@ -33,12 +35,24 @@ setptr(ibuf) exit(1); msgCount = 0; offset = 0; - s = 0; + s = 0L; l = 0; maybe = 1; flag = MUSED|MNEW; for (;;) { - if ((count = freadline(ibuf, linebuf)) == 0) { + cp = linebuf; + c = getc(ibuf); + while (c != EOF && c != '\n') { + if (cp - linebuf >= LINESIZE - 1) { + ungetc(c, ibuf); + *cp = 0; + break; + } + *cp++ = c; + c = getc(ibuf); + } + *cp = 0; + if (cp == linebuf && c == EOF) { this.m_flag = flag; flag = MUSED|MNEW; this.m_offset = offsetof(offset); @@ -54,7 +68,11 @@ setptr(ibuf) close(mestmp); return; } - if (fputs(linebuf, otf) == NULL || putc('\n', otf) == EOF) { + count = cp - linebuf + 1; + for (cp = linebuf; *cp;) + putc(*cp++, otf); + putc('\n', otf); + if (ferror(otf)) { perror("/tmp"); exit(1); } @@ -67,7 +85,7 @@ setptr(ibuf) 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); @@ -92,7 +110,7 @@ setptr(ibuf) } } offset += count; - s += count; + s += (long) count; l++; maybe = 0; if (linebuf[0] == 0) @@ -231,7 +249,7 @@ makemessage(f) 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; } @@ -269,28 +287,74 @@ remove(name) /* * Terminate an editing session by attempting to write out the user's - * file from the temporary. + * file from the temporary. Save any new stuff appended to the file. */ - edstop() { register int gotcha, c; register struct message *mp; - FILE *obuf; + FILE *obuf, *ibuf, *readstat; + struct stat statb; + char tempname[30], *id; + int (*sigs[3])(); if (readonly) return; - for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) - if (mp->m_flag & (MODIFY|MDELETED)) { + 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++; - break; + if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) { + if ((id = hfield("article-id", mp)) != NOSTR) + fprintf(readstat, "%s\n", id); } - if (!gotcha) - return; + } + if (Tflag != NOSTR) + fclose(readstat); + if (!gotcha || Tflag != NOSTR) + goto done; + ibuf = NULL; + if (stat(editfile, &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(editfile, "r")) == NULL) { + perror(editfile); + 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\" ", editfile); flush(); if ((obuf = fopen(editfile, "w")) == NULL) { perror(editfile); + relsesigs(); reset(0); } c = 0; @@ -298,23 +362,60 @@ edstop() if ((mp->m_flag & MDELETED) != 0) continue; c++; - if (send(mp, obuf) < 0) { + if (send(mp, obuf, 0) < 0) { perror(editfile); + 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(editfile); + relsesigs(); reset(0); } - if (c == 0) { + fclose(obuf); + if (gotcha) { remove(editfile); printf("removed\n"); } else printf("complete\n"); flush(); + +done: + relsesigs(); +} + +static int sigdepth = 0; /* depth of holdsigs() */ +/* + * Hold signals SIGHUP - SIGQUIT. + */ +holdsigs() +{ + register int i; + + if (sigdepth++ == 0) + for (i = SIGHUP; i <= SIGQUIT; i++) + sighold(i); +} + +/* + * Release signals SIGHUP - SIGQUIT + */ +relsesigs() +{ + register int i; + + if (--sigdepth == 0) + for (i = SIGHUP; i <= SIGQUIT; i++) + sigrelse(i); } /* @@ -399,16 +500,19 @@ expand(name) 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); - /* sigint = signal(SIGINT, SIG_IGN); */ if (pipe(pivec) < 0) { perror("pipe"); - /* signal(SIGINT, sigint) */ return(name); } sprintf(cmdbuf, "echo %s", name); if ((pid = vfork()) == 0) { + sigchild(); Shell = value("SHELL"); if (Shell == NOSTR) Shell = SHELL; @@ -456,14 +560,29 @@ expand(name) fprintf(stderr, "\"%s\": Ambiguous\n", name); goto err; } - /* signal(SIGINT, sigint) */ return(savestr(xname)); err: - /* signal(SIGINT, sigint); */ 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.