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