1: /* 2: * Copyright (c) 1980 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: static char *sccsid = "@(#)quit.c 5.3 (Berkeley) 3/6/86"; 9: #endif not lint 10: 11: #include "rcv.h" 12: #include <sys/stat.h> 13: #include <sys/file.h> 14: 15: /* 16: * Rcv -- receive mail rationally. 17: * 18: * Termination processing. 19: */ 20: 21: /* 22: * Save all of the undetermined messages at the top of "mbox" 23: * Save all untouched messages back in the system mailbox. 24: * Remove the system mailbox, if none saved there. 25: */ 26: 27: quit() 28: { 29: int mcount, p, modify, autohold, anystat, holdbit, nohold; 30: FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf; 31: register struct message *mp; 32: register int c; 33: extern char tempQuit[], tempResid[]; 34: struct stat minfo; 35: char *id; 36: 37: /* 38: * If we are read only, we can't do anything, 39: * so just return quickly. 40: */ 41: 42: if (readonly) 43: return; 44: /* 45: * See if there any messages to save in mbox. If no, we 46: * can save copying mbox to /tmp and back. 47: * 48: * Check also to see if any files need to be preserved. 49: * Delete all untouched messages to keep them out of mbox. 50: * If all the messages are to be preserved, just exit with 51: * a message. 52: * 53: * If the luser has sent mail to himself, refuse to do 54: * anything with the mailbox, unless mail locking works. 55: */ 56: 57: fbuf = fopen(mailname, "r"); 58: if (fbuf == NULL) 59: goto newmail; 60: flock(fileno(fbuf), LOCK_EX); 61: #ifndef CANLOCK 62: if (selfsent) { 63: printf("You have new mail.\n"); 64: fclose(fbuf); 65: return; 66: } 67: #endif 68: rbuf = NULL; 69: if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) { 70: printf("New mail has arrived.\n"); 71: rbuf = fopen(tempResid, "w"); 72: if (rbuf == NULL || fbuf == NULL) 73: goto newmail; 74: #ifdef APPEND 75: fseek(fbuf, mailsize, 0); 76: while ((c = getc(fbuf)) != EOF) 77: putc(c, rbuf); 78: #else 79: p = minfo.st_size - mailsize; 80: while (p-- > 0) { 81: c = getc(fbuf); 82: if (c == EOF) 83: goto newmail; 84: putc(c, rbuf); 85: } 86: #endif 87: fclose(rbuf); 88: if ((rbuf = fopen(tempResid, "r")) == NULL) 89: goto newmail; 90: remove(tempResid); 91: } 92: 93: /* 94: * Adjust the message flags in each message. 95: */ 96: 97: anystat = 0; 98: autohold = value("hold") != NOSTR; 99: holdbit = autohold ? MPRESERVE : MBOX; 100: nohold = MBOX|MSAVED|MDELETED|MPRESERVE; 101: if (value("keepsave") != NOSTR) 102: nohold &= ~MSAVED; 103: for (mp = &message[0]; mp < &message[msgCount]; mp++) { 104: if (mp->m_flag & MNEW) { 105: mp->m_flag &= ~MNEW; 106: mp->m_flag |= MSTATUS; 107: } 108: if (mp->m_flag & MSTATUS) 109: anystat++; 110: if ((mp->m_flag & MTOUCH) == 0) 111: mp->m_flag |= MPRESERVE; 112: if ((mp->m_flag & nohold) == 0) 113: mp->m_flag |= holdbit; 114: } 115: modify = 0; 116: if (Tflag != NOSTR) { 117: if ((readstat = fopen(Tflag, "w")) == NULL) 118: Tflag = NOSTR; 119: } 120: for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) { 121: if (mp->m_flag & MBOX) 122: c++; 123: if (mp->m_flag & MPRESERVE) 124: p++; 125: if (mp->m_flag & MODIFY) 126: modify++; 127: if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) { 128: id = hfield("article-id", mp); 129: if (id != NOSTR) 130: fprintf(readstat, "%s\n", id); 131: } 132: } 133: if (Tflag != NOSTR) 134: fclose(readstat); 135: if (p == msgCount && !modify && !anystat) { 136: if (p == 1) 137: printf("Held 1 message in %s\n", mailname); 138: else 139: printf("Held %2d messages in %s\n", p, mailname); 140: fclose(fbuf); 141: return; 142: } 143: if (c == 0) { 144: if (p != 0) { 145: writeback(rbuf); 146: fclose(fbuf); 147: return; 148: } 149: goto cream; 150: } 151: 152: /* 153: * Create another temporary file and copy user's mbox file 154: * darin. If there is no mbox, copy nothing. 155: * If he has specified "append" don't copy his mailbox, 156: * just copy saveable entries at the end. 157: */ 158: 159: mcount = c; 160: if (value("append") == NOSTR) { 161: if ((obuf = fopen(tempQuit, "w")) == NULL) { 162: perror(tempQuit); 163: fclose(fbuf); 164: return; 165: } 166: if ((ibuf = fopen(tempQuit, "r")) == NULL) { 167: perror(tempQuit); 168: remove(tempQuit); 169: fclose(obuf); 170: fclose(fbuf); 171: return; 172: } 173: remove(tempQuit); 174: if ((abuf = fopen(mbox, "r")) != NULL) { 175: while ((c = getc(abuf)) != EOF) 176: putc(c, obuf); 177: fclose(abuf); 178: } 179: if (ferror(obuf)) { 180: perror(tempQuit); 181: fclose(ibuf); 182: fclose(obuf); 183: fclose(fbuf); 184: return; 185: } 186: fclose(obuf); 187: close(creat(mbox, 0600)); 188: if ((obuf = fopen(mbox, "r+")) == NULL) { 189: perror(mbox); 190: fclose(ibuf); 191: fclose(fbuf); 192: return; 193: } 194: } 195: if (value("append") != NOSTR) { 196: if ((obuf = fopen(mbox, "a")) == NULL) { 197: perror(mbox); 198: fclose(fbuf); 199: return; 200: } 201: fchmod(fileno(obuf), 0600); 202: } 203: for (mp = &message[0]; mp < &message[msgCount]; mp++) 204: if (mp->m_flag & MBOX) 205: if (send(mp, obuf, 0) < 0) { 206: perror(mbox); 207: fclose(ibuf); 208: fclose(obuf); 209: fclose(fbuf); 210: return; 211: } 212: 213: /* 214: * Copy the user's old mbox contents back 215: * to the end of the stuff we just saved. 216: * If we are appending, this is unnecessary. 217: */ 218: 219: if (value("append") == NOSTR) { 220: rewind(ibuf); 221: c = getc(ibuf); 222: while (c != EOF) { 223: putc(c, obuf); 224: if (ferror(obuf)) 225: break; 226: c = getc(ibuf); 227: } 228: fclose(ibuf); 229: fflush(obuf); 230: } 231: trunc(obuf); 232: if (ferror(obuf)) { 233: perror(mbox); 234: fclose(obuf); 235: fclose(fbuf); 236: return; 237: } 238: fclose(obuf); 239: if (mcount == 1) 240: printf("Saved 1 message in mbox\n"); 241: else 242: printf("Saved %d messages in mbox\n", mcount); 243: 244: /* 245: * Now we are ready to copy back preserved files to 246: * the system mailbox, if any were requested. 247: */ 248: 249: if (p != 0) { 250: writeback(rbuf); 251: fclose(fbuf); 252: return; 253: } 254: 255: /* 256: * Finally, remove his /usr/mail file. 257: * If new mail has arrived, copy it back. 258: */ 259: 260: cream: 261: if (rbuf != NULL) { 262: abuf = fopen(mailname, "r+"); 263: if (abuf == NULL) 264: goto newmail; 265: while ((c = getc(rbuf)) != EOF) 266: putc(c, abuf); 267: fclose(rbuf); 268: trunc(abuf); 269: fclose(abuf); 270: alter(mailname); 271: fclose(fbuf); 272: return; 273: } 274: demail(); 275: fclose(fbuf); 276: return; 277: 278: newmail: 279: printf("Thou hast new mail.\n"); 280: if (fbuf != NULL) 281: fclose(fbuf); 282: } 283: 284: /* 285: * Preserve all the appropriate messages back in the system 286: * mailbox, and print a nice message indicated how many were 287: * saved. On any error, just return -1. Else return 0. 288: * Incorporate the any new mail that we found. 289: */ 290: writeback(res) 291: register FILE *res; 292: { 293: register struct message *mp; 294: register int p, c; 295: FILE *obuf; 296: 297: p = 0; 298: if ((obuf = fopen(mailname, "r+")) == NULL) { 299: perror(mailname); 300: return(-1); 301: } 302: #ifndef APPEND 303: if (res != NULL) 304: while ((c = getc(res)) != EOF) 305: putc(c, obuf); 306: #endif 307: for (mp = &message[0]; mp < &message[msgCount]; mp++) 308: if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) { 309: p++; 310: if (send(mp, obuf, 0) < 0) { 311: perror(mailname); 312: fclose(obuf); 313: return(-1); 314: } 315: } 316: #ifdef APPEND 317: if (res != NULL) 318: while ((c = getc(res)) != EOF) 319: putc(c, obuf); 320: #endif 321: fflush(obuf); 322: trunc(obuf); 323: if (ferror(obuf)) { 324: perror(mailname); 325: fclose(obuf); 326: return(-1); 327: } 328: if (res != NULL) 329: fclose(res); 330: fclose(obuf); 331: alter(mailname); 332: if (p == 1) 333: printf("Held 1 message in %s\n", mailname); 334: else 335: printf("Held %d messages in %s\n", p, mailname); 336: return(0); 337: }