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