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