|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)quit.c 5.15 (Berkeley) 6/25/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include "rcv.h" ! 25: #include <sys/stat.h> ! 26: #include <sys/file.h> ! 27: ! 28: /* ! 29: * Rcv -- receive mail rationally. ! 30: * ! 31: * Termination processing. ! 32: */ ! 33: ! 34: /* ! 35: * The "quit" command. ! 36: */ ! 37: quitcmd() ! 38: { ! 39: /* ! 40: * If we are sourcing, then return 1 so execute() can handle it. ! 41: * Otherwise, return -1 to abort command loop. ! 42: */ ! 43: if (sourcing) ! 44: return 1; ! 45: return -1; ! 46: } ! 47: ! 48: /* ! 49: * Save all of the undetermined messages at the top of "mbox" ! 50: * Save all untouched messages back in the system mailbox. ! 51: * Remove the system mailbox, if none saved there. ! 52: */ ! 53: ! 54: quit() ! 55: { ! 56: int mcount, p, modify, autohold, anystat, holdbit, nohold; ! 57: FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf; ! 58: register struct message *mp; ! 59: register int c; ! 60: extern char tempQuit[], tempResid[]; ! 61: struct stat minfo; ! 62: char *mbox; ! 63: ! 64: /* ! 65: * If we are read only, we can't do anything, ! 66: * so just return quickly. ! 67: */ ! 68: if (readonly) ! 69: return; ! 70: /* ! 71: * If editing (not reading system mail box), then do the work ! 72: * in edstop() ! 73: */ ! 74: if (edit) { ! 75: edstop(); ! 76: return; ! 77: } ! 78: ! 79: /* ! 80: * See if there any messages to save in mbox. If no, we ! 81: * can save copying mbox to /tmp and back. ! 82: * ! 83: * Check also to see if any files need to be preserved. ! 84: * Delete all untouched messages to keep them out of mbox. ! 85: * If all the messages are to be preserved, just exit with ! 86: * a message. ! 87: */ ! 88: ! 89: fbuf = Fopen(mailname, "r"); ! 90: if (fbuf == NULL) ! 91: goto newmail; ! 92: flock(fileno(fbuf), LOCK_EX); ! 93: rbuf = NULL; ! 94: if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) { ! 95: printf("New mail has arrived.\n"); ! 96: rbuf = Fopen(tempResid, "w"); ! 97: if (rbuf == NULL || fbuf == NULL) ! 98: goto newmail; ! 99: #ifdef APPEND ! 100: fseek(fbuf, mailsize, 0); ! 101: while ((c = getc(fbuf)) != EOF) ! 102: (void) putc(c, rbuf); ! 103: #else ! 104: p = minfo.st_size - mailsize; ! 105: while (p-- > 0) { ! 106: c = getc(fbuf); ! 107: if (c == EOF) ! 108: goto newmail; ! 109: (void) putc(c, rbuf); ! 110: } ! 111: #endif ! 112: Fclose(rbuf); ! 113: if ((rbuf = Fopen(tempResid, "r")) == NULL) ! 114: goto newmail; ! 115: remove(tempResid); ! 116: } ! 117: ! 118: /* ! 119: * Adjust the message flags in each message. ! 120: */ ! 121: ! 122: anystat = 0; ! 123: autohold = value("hold") != NOSTR; ! 124: holdbit = autohold ? MPRESERVE : MBOX; ! 125: nohold = MBOX|MSAVED|MDELETED|MPRESERVE; ! 126: if (value("keepsave") != NOSTR) ! 127: nohold &= ~MSAVED; ! 128: for (mp = &message[0]; mp < &message[msgCount]; mp++) { ! 129: if (mp->m_flag & MNEW) { ! 130: mp->m_flag &= ~MNEW; ! 131: mp->m_flag |= MSTATUS; ! 132: } ! 133: if (mp->m_flag & MSTATUS) ! 134: anystat++; ! 135: if ((mp->m_flag & MTOUCH) == 0) ! 136: mp->m_flag |= MPRESERVE; ! 137: if ((mp->m_flag & nohold) == 0) ! 138: mp->m_flag |= holdbit; ! 139: } ! 140: modify = 0; ! 141: if (Tflag != NOSTR) { ! 142: if ((readstat = Fopen(Tflag, "w")) == NULL) ! 143: Tflag = NOSTR; ! 144: } ! 145: for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) { ! 146: if (mp->m_flag & MBOX) ! 147: c++; ! 148: if (mp->m_flag & MPRESERVE) ! 149: p++; ! 150: if (mp->m_flag & MODIFY) ! 151: modify++; ! 152: if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) { ! 153: char *id; ! 154: ! 155: if ((id = hfield("article-id", mp)) != NOSTR) ! 156: fprintf(readstat, "%s\n", id); ! 157: } ! 158: } ! 159: if (Tflag != NOSTR) ! 160: Fclose(readstat); ! 161: if (p == msgCount && !modify && !anystat) { ! 162: printf("Held %d message%s in %s\n", ! 163: p, p == 1 ? "" : "s", mailname); ! 164: Fclose(fbuf); ! 165: return; ! 166: } ! 167: if (c == 0) { ! 168: if (p != 0) { ! 169: writeback(rbuf); ! 170: Fclose(fbuf); ! 171: return; ! 172: } ! 173: goto cream; ! 174: } ! 175: ! 176: /* ! 177: * Create another temporary file and copy user's mbox file ! 178: * darin. If there is no mbox, copy nothing. ! 179: * If he has specified "append" don't copy his mailbox, ! 180: * just copy saveable entries at the end. ! 181: */ ! 182: ! 183: mbox = expand("&"); ! 184: mcount = c; ! 185: if (value("append") == NOSTR) { ! 186: if ((obuf = Fopen(tempQuit, "w")) == NULL) { ! 187: perror(tempQuit); ! 188: Fclose(fbuf); ! 189: return; ! 190: } ! 191: if ((ibuf = Fopen(tempQuit, "r")) == NULL) { ! 192: perror(tempQuit); ! 193: remove(tempQuit); ! 194: Fclose(obuf); ! 195: Fclose(fbuf); ! 196: return; ! 197: } ! 198: remove(tempQuit); ! 199: if ((abuf = Fopen(mbox, "r")) != NULL) { ! 200: while ((c = getc(abuf)) != EOF) ! 201: (void) putc(c, obuf); ! 202: Fclose(abuf); ! 203: } ! 204: if (ferror(obuf)) { ! 205: perror(tempQuit); ! 206: Fclose(ibuf); ! 207: Fclose(obuf); ! 208: Fclose(fbuf); ! 209: return; ! 210: } ! 211: Fclose(obuf); ! 212: close(creat(mbox, 0600)); ! 213: if ((obuf = Fopen(mbox, "r+")) == NULL) { ! 214: perror(mbox); ! 215: Fclose(ibuf); ! 216: Fclose(fbuf); ! 217: return; ! 218: } ! 219: } ! 220: if (value("append") != NOSTR) { ! 221: if ((obuf = Fopen(mbox, "a")) == NULL) { ! 222: perror(mbox); ! 223: Fclose(fbuf); ! 224: return; ! 225: } ! 226: fchmod(fileno(obuf), 0600); ! 227: } ! 228: for (mp = &message[0]; mp < &message[msgCount]; mp++) ! 229: if (mp->m_flag & MBOX) ! 230: if (send(mp, obuf, saveignore, NOSTR) < 0) { ! 231: perror(mbox); ! 232: Fclose(ibuf); ! 233: Fclose(obuf); ! 234: Fclose(fbuf); ! 235: return; ! 236: } ! 237: ! 238: /* ! 239: * Copy the user's old mbox contents back ! 240: * to the end of the stuff we just saved. ! 241: * If we are appending, this is unnecessary. ! 242: */ ! 243: ! 244: if (value("append") == NOSTR) { ! 245: rewind(ibuf); ! 246: c = getc(ibuf); ! 247: while (c != EOF) { ! 248: (void) putc(c, obuf); ! 249: if (ferror(obuf)) ! 250: break; ! 251: c = getc(ibuf); ! 252: } ! 253: Fclose(ibuf); ! 254: fflush(obuf); ! 255: } ! 256: trunc(obuf); ! 257: if (ferror(obuf)) { ! 258: perror(mbox); ! 259: Fclose(obuf); ! 260: Fclose(fbuf); ! 261: return; ! 262: } ! 263: Fclose(obuf); ! 264: if (mcount == 1) ! 265: printf("Saved 1 message in mbox\n"); ! 266: else ! 267: printf("Saved %d messages in mbox\n", mcount); ! 268: ! 269: /* ! 270: * Now we are ready to copy back preserved files to ! 271: * the system mailbox, if any were requested. ! 272: */ ! 273: ! 274: if (p != 0) { ! 275: writeback(rbuf); ! 276: Fclose(fbuf); ! 277: return; ! 278: } ! 279: ! 280: /* ! 281: * Finally, remove his /usr/mail file. ! 282: * If new mail has arrived, copy it back. ! 283: */ ! 284: ! 285: cream: ! 286: if (rbuf != NULL) { ! 287: abuf = Fopen(mailname, "r+"); ! 288: if (abuf == NULL) ! 289: goto newmail; ! 290: while ((c = getc(rbuf)) != EOF) ! 291: (void) putc(c, abuf); ! 292: Fclose(rbuf); ! 293: trunc(abuf); ! 294: Fclose(abuf); ! 295: alter(mailname); ! 296: Fclose(fbuf); ! 297: return; ! 298: } ! 299: demail(); ! 300: Fclose(fbuf); ! 301: return; ! 302: ! 303: newmail: ! 304: printf("Thou hast new mail.\n"); ! 305: if (fbuf != NULL) ! 306: Fclose(fbuf); ! 307: } ! 308: ! 309: /* ! 310: * Preserve all the appropriate messages back in the system ! 311: * mailbox, and print a nice message indicated how many were ! 312: * saved. On any error, just return -1. Else return 0. ! 313: * Incorporate the any new mail that we found. ! 314: */ ! 315: writeback(res) ! 316: register FILE *res; ! 317: { ! 318: register struct message *mp; ! 319: register int p, c; ! 320: FILE *obuf; ! 321: ! 322: p = 0; ! 323: if ((obuf = Fopen(mailname, "r+")) == NULL) { ! 324: perror(mailname); ! 325: return(-1); ! 326: } ! 327: #ifndef APPEND ! 328: if (res != NULL) ! 329: while ((c = getc(res)) != EOF) ! 330: (void) putc(c, obuf); ! 331: #endif ! 332: for (mp = &message[0]; mp < &message[msgCount]; mp++) ! 333: if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) { ! 334: p++; ! 335: if (send(mp, obuf, (struct ignoretab *)0, NOSTR) < 0) { ! 336: perror(mailname); ! 337: Fclose(obuf); ! 338: return(-1); ! 339: } ! 340: } ! 341: #ifdef APPEND ! 342: if (res != NULL) ! 343: while ((c = getc(res)) != EOF) ! 344: (void) putc(c, obuf); ! 345: #endif ! 346: fflush(obuf); ! 347: trunc(obuf); ! 348: if (ferror(obuf)) { ! 349: perror(mailname); ! 350: Fclose(obuf); ! 351: return(-1); ! 352: } ! 353: if (res != NULL) ! 354: Fclose(res); ! 355: Fclose(obuf); ! 356: alter(mailname); ! 357: if (p == 1) ! 358: printf("Held 1 message in %s\n", mailname); ! 359: else ! 360: printf("Held %d messages in %s\n", p, mailname); ! 361: return(0); ! 362: } ! 363: ! 364: /* ! 365: * Terminate an editing session by attempting to write out the user's ! 366: * file from the temporary. Save any new stuff appended to the file. ! 367: */ ! 368: edstop() ! 369: { ! 370: register int gotcha, c; ! 371: register struct message *mp; ! 372: FILE *obuf, *ibuf, *readstat; ! 373: struct stat statb; ! 374: char tempname[30]; ! 375: char *mktemp(); ! 376: ! 377: if (readonly) ! 378: return; ! 379: holdsigs(); ! 380: if (Tflag != NOSTR) { ! 381: if ((readstat = Fopen(Tflag, "w")) == NULL) ! 382: Tflag = NOSTR; ! 383: } ! 384: for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) { ! 385: if (mp->m_flag & MNEW) { ! 386: mp->m_flag &= ~MNEW; ! 387: mp->m_flag |= MSTATUS; ! 388: } ! 389: if (mp->m_flag & (MODIFY|MDELETED|MSTATUS)) ! 390: gotcha++; ! 391: if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) { ! 392: char *id; ! 393: ! 394: if ((id = hfield("article-id", mp)) != NOSTR) ! 395: fprintf(readstat, "%s\n", id); ! 396: } ! 397: } ! 398: if (Tflag != NOSTR) ! 399: Fclose(readstat); ! 400: if (!gotcha || Tflag != NOSTR) ! 401: goto done; ! 402: ibuf = NULL; ! 403: if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) { ! 404: strcpy(tempname, _PATH_TMP); ! 405: strcat(tempname, "mboxXXXXXX"); ! 406: mktemp(tempname); ! 407: if ((obuf = Fopen(tempname, "w")) == NULL) { ! 408: perror(tempname); ! 409: relsesigs(); ! 410: reset(0); ! 411: } ! 412: if ((ibuf = Fopen(mailname, "r")) == NULL) { ! 413: perror(mailname); ! 414: Fclose(obuf); ! 415: remove(tempname); ! 416: relsesigs(); ! 417: reset(0); ! 418: } ! 419: fseek(ibuf, mailsize, 0); ! 420: while ((c = getc(ibuf)) != EOF) ! 421: (void) putc(c, obuf); ! 422: Fclose(ibuf); ! 423: Fclose(obuf); ! 424: if ((ibuf = Fopen(tempname, "r")) == NULL) { ! 425: perror(tempname); ! 426: remove(tempname); ! 427: relsesigs(); ! 428: reset(0); ! 429: } ! 430: remove(tempname); ! 431: } ! 432: printf("\"%s\" ", mailname); ! 433: fflush(stdout); ! 434: if ((obuf = Fopen(mailname, "r+")) == NULL) { ! 435: perror(mailname); ! 436: relsesigs(); ! 437: reset(0); ! 438: } ! 439: trunc(obuf); ! 440: c = 0; ! 441: for (mp = &message[0]; mp < &message[msgCount]; mp++) { ! 442: if ((mp->m_flag & MDELETED) != 0) ! 443: continue; ! 444: c++; ! 445: if (send(mp, obuf, (struct ignoretab *) NULL, NOSTR) < 0) { ! 446: perror(mailname); ! 447: relsesigs(); ! 448: reset(0); ! 449: } ! 450: } ! 451: gotcha = (c == 0 && ibuf == NULL); ! 452: if (ibuf != NULL) { ! 453: while ((c = getc(ibuf)) != EOF) ! 454: (void) putc(c, obuf); ! 455: Fclose(ibuf); ! 456: } ! 457: fflush(obuf); ! 458: if (ferror(obuf)) { ! 459: perror(mailname); ! 460: relsesigs(); ! 461: reset(0); ! 462: } ! 463: Fclose(obuf); ! 464: if (gotcha) { ! 465: remove(mailname); ! 466: printf("removed\n"); ! 467: } else ! 468: printf("complete\n"); ! 469: fflush(stdout); ! 470: ! 471: done: ! 472: relsesigs(); ! 473: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.