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.3 09/09/81"; 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) { 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 278 writeback(res) 279 register FILE *res; 280 { 281 register struct message *mp; 282 register int p, c; 283 FILE *obuf; 284 285 p = 0; 286 if ((obuf = fopen(mailname, "w")) == NULL) { 287 perror(mailname); 288 return(-1); 289 } 290 #ifndef APPEND 291 if (res != NULL) 292 while ((c = getc(res)) != EOF) 293 putc(c, obuf); 294 #endif 295 for (mp = &message[0]; mp < &message[msgCount]; mp++) 296 if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) { 297 p++; 298 if (send(mp, obuf) < 0) { 299 perror(mailname); 300 fclose(obuf); 301 return(-1); 302 } 303 } 304 #ifdef APPEND 305 if (res != NULL) 306 while ((c = getc(res)) != EOF) 307 putc(c, obuf); 308 #endif 309 fflush(obuf); 310 if (ferror(obuf)) { 311 perror(mailname); 312 fclose(obuf); 313 return(-1); 314 } 315 if (res != NULL) 316 fclose(res); 317 fclose(obuf); 318 alter(mailname); 319 if (p == 1) 320 printf("Held 1 message in %s\n", mailname); 321 else 322 printf("Held %d messages in %s\n", p, mailname); 323 return(0); 324 } 325