1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms, with or without
   6:  * modification, are permitted provided that the following conditions
   7:  * are met:
   8:  * 1. Redistributions of source code must retain the above copyright
   9:  *    notice, this list of conditions and the following disclaimer.
  10:  * 2. Redistributions in binary form must reproduce the above copyright
  11:  *    notice, this list of conditions and the following disclaimer in the
  12:  *    documentation and/or other materials provided with the distribution.
  13:  * 3. All advertising materials mentioning features or use of this software
  14:  *    must display the following acknowledgement:
  15:  *	This product includes software developed by the University of
  16:  *	California, Berkeley and its contributors.
  17:  * 4. Neither the name of the University nor the names of its contributors
  18:  *    may be used to endorse or promote products derived from this software
  19:  *    without specific prior written permission.
  20:  *
  21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31:  * SUCH DAMAGE.
  32:  */
  33: 
  34: #if !defined(lint) && defined(DOSCCS)
  35: static char sccsid[] = "@(#)quit.c	5.16 (Berkeley) 2/9/91";
  36: #endif
  37: 
  38: #include "rcv.h"
  39: #include <sys/stat.h>
  40: #include <sys/file.h>
  41: 
  42: /*
  43:  * Rcv -- receive mail rationally.
  44:  *
  45:  * Termination processing.
  46:  */
  47: 
  48: /*
  49:  * The "quit" command.
  50:  */
  51: quitcmd()
  52: {
  53:     /*
  54: 	 * If we are sourcing, then return 1 so execute() can handle it.
  55: 	 * Otherwise, return -1 to abort command loop.
  56: 	 */
  57:     if (sourcing)
  58:         return 1;
  59:     return -1;
  60: }
  61: 
  62: /*
  63:  * Save all of the undetermined messages at the top of "mbox"
  64:  * Save all untouched messages back in the system mailbox.
  65:  * Remove the system mailbox, if none saved there.
  66:  */
  67: 
  68: quit()
  69: {
  70:     int mcount, p, modify, autohold, anystat, holdbit, nohold;
  71:     FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf;
  72:     register struct message *mp;
  73:     register int c;
  74:     extern char tempQuit[], tempResid[];
  75:     struct stat minfo;
  76:     char *mbox;
  77: 
  78:     /*
  79: 	 * If we are read only, we can't do anything,
  80: 	 * so just return quickly.
  81: 	 */
  82:     if (readonly)
  83:         return;
  84:     /*
  85: 	 * If editing (not reading system mail box), then do the work
  86: 	 * in edstop()
  87: 	 */
  88:     if (edit) {
  89:         edstop();
  90:         return;
  91:     }
  92: 
  93:     /*
  94: 	 * See if there any messages to save in mbox.  If no, we
  95: 	 * can save copying mbox to /tmp and back.
  96: 	 *
  97: 	 * Check also to see if any files need to be preserved.
  98: 	 * Delete all untouched messages to keep them out of mbox.
  99: 	 * If all the messages are to be preserved, just exit with
 100: 	 * a message.
 101: 	 */
 102: 
 103:     fbuf = Fopen(mailname, "r");
 104:     if (fbuf == NULL)
 105:         goto newmail;
 106:     flock(fileno(fbuf), LOCK_EX);
 107:     rbuf = NULL;
 108:     if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
 109:         printf("New mail has arrived.\n");
 110:         rbuf = Fopen(tempResid, "w");
 111:         if (rbuf == NULL || fbuf == NULL)
 112:             goto newmail;
 113: #ifdef APPEND
 114:         fseek(fbuf, mailsize, 0);
 115:         while ((c = getc(fbuf)) != EOF)
 116:             (void) putc(c, rbuf);
 117: #else
 118:         p = minfo.st_size - mailsize;
 119:         while (p-- > 0) {
 120:             c = getc(fbuf);
 121:             if (c == EOF)
 122:                 goto newmail;
 123:             (void) putc(c, rbuf);
 124:         }
 125: #endif
 126:         Fclose(rbuf);
 127:         if ((rbuf = Fopen(tempResid, "r")) == NULL)
 128:             goto newmail;
 129:         rm(tempResid);
 130:     }
 131: 
 132:     /*
 133: 	 * Adjust the message flags in each message.
 134: 	 */
 135: 
 136:     anystat = 0;
 137:     autohold = value("hold") != NOSTR;
 138:     holdbit = autohold ? MPRESERVE : MBOX;
 139:     nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
 140:     if (value("keepsave") != NOSTR)
 141:         nohold &= ~MSAVED;
 142:     for (mp = &message[0]; mp < &message[msgCount]; mp++) {
 143:         if (mp->m_flag & MNEW) {
 144:             mp->m_flag &= ~MNEW;
 145:             mp->m_flag |= MSTATUS;
 146:         }
 147:         if (mp->m_flag & MSTATUS)
 148:             anystat++;
 149:         if ((mp->m_flag & MTOUCH) == 0)
 150:             mp->m_flag |= MPRESERVE;
 151:         if ((mp->m_flag & nohold) == 0)
 152:             mp->m_flag |= holdbit;
 153:     }
 154:     modify = 0;
 155:     if (Tflag != NOSTR) {
 156:         if ((readstat = Fopen(Tflag, "w")) == NULL)
 157:             Tflag = NOSTR;
 158:     }
 159:     for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
 160:         if (mp->m_flag & MBOX)
 161:             c++;
 162:         if (mp->m_flag & MPRESERVE)
 163:             p++;
 164:         if (mp->m_flag & MODIFY)
 165:             modify++;
 166:         if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
 167:             char *id;
 168: 
 169:             if ((id = hfield("article-id", mp)) != NOSTR)
 170:                 fprintf(readstat, "%s\n", id);
 171:         }
 172:     }
 173:     if (Tflag != NOSTR)
 174:         Fclose(readstat);
 175:     if (p == msgCount && !modify && !anystat) {
 176:         printf("Held %d message%s in %s\n",
 177:             p, p == 1 ? "" : "s", mailname);
 178:         Fclose(fbuf);
 179:         return;
 180:     }
 181:     if (c == 0) {
 182:         if (p != 0) {
 183:             writeback(rbuf);
 184:             Fclose(fbuf);
 185:             return;
 186:         }
 187:         goto cream;
 188:     }
 189: 
 190:     /*
 191: 	 * Create another temporary file and copy user's mbox file
 192: 	 * darin.  If there is no mbox, copy nothing.
 193: 	 * If he has specified "append" don't copy his mailbox,
 194: 	 * just copy saveable entries at the end.
 195: 	 */
 196: 
 197:     mbox = expand("&");
 198:     mcount = c;
 199:     if (value("append") == NOSTR) {
 200:         if ((obuf = Fopen(tempQuit, "w")) == NULL) {
 201:             perror(tempQuit);
 202:             Fclose(fbuf);
 203:             return;
 204:         }
 205:         if ((ibuf = Fopen(tempQuit, "r")) == NULL) {
 206:             perror(tempQuit);
 207:             rm(tempQuit);
 208:             Fclose(obuf);
 209:             Fclose(fbuf);
 210:             return;
 211:         }
 212:         rm(tempQuit);
 213:         if ((abuf = Fopen(mbox, "r")) != NULL) {
 214:             while ((c = getc(abuf)) != EOF)
 215:                 (void) putc(c, obuf);
 216:             Fclose(abuf);
 217:         }
 218:         if (ferror(obuf)) {
 219:             perror(tempQuit);
 220:             Fclose(ibuf);
 221:             Fclose(obuf);
 222:             Fclose(fbuf);
 223:             return;
 224:         }
 225:         Fclose(obuf);
 226:         close(creat(mbox, 0600));
 227:         if ((obuf = Fopen(mbox, "r+")) == NULL) {
 228:             perror(mbox);
 229:             Fclose(ibuf);
 230:             Fclose(fbuf);
 231:             return;
 232:         }
 233:     }
 234:     if (value("append") != NOSTR) {
 235:         if ((obuf = Fopen(mbox, "a")) == NULL) {
 236:             perror(mbox);
 237:             Fclose(fbuf);
 238:             return;
 239:         }
 240:         fchmod(fileno(obuf), 0600);
 241:     }
 242:     for (mp = &message[0]; mp < &message[msgCount]; mp++)
 243:         if (mp->m_flag & MBOX)
 244:             if (send(mp, obuf, saveignore, NOSTR) < 0) {
 245:                 perror(mbox);
 246:                 Fclose(ibuf);
 247:                 Fclose(obuf);
 248:                 Fclose(fbuf);
 249:                 return;
 250:             }
 251: 
 252:     /*
 253: 	 * Copy the user's old mbox contents back
 254: 	 * to the end of the stuff we just saved.
 255: 	 * If we are appending, this is unnecessary.
 256: 	 */
 257: 
 258:     if (value("append") == NOSTR) {
 259:         rewind(ibuf);
 260:         c = getc(ibuf);
 261:         while (c != EOF) {
 262:             (void) putc(c, obuf);
 263:             if (ferror(obuf))
 264:                 break;
 265:             c = getc(ibuf);
 266:         }
 267:         Fclose(ibuf);
 268:         fflush(obuf);
 269:     }
 270:     trunc(obuf);
 271:     if (ferror(obuf)) {
 272:         perror(mbox);
 273:         Fclose(obuf);
 274:         Fclose(fbuf);
 275:         return;
 276:     }
 277:     Fclose(obuf);
 278:     if (mcount == 1)
 279:         printf("Saved 1 message in mbox\n");
 280:     else
 281:         printf("Saved %d messages in mbox\n", mcount);
 282: 
 283:     /*
 284: 	 * Now we are ready to copy back preserved files to
 285: 	 * the system mailbox, if any were requested.
 286: 	 */
 287: 
 288:     if (p != 0) {
 289:         writeback(rbuf);
 290:         Fclose(fbuf);
 291:         return;
 292:     }
 293: 
 294:     /*
 295: 	 * Finally, remove his /usr/mail file.
 296: 	 * If new mail has arrived, copy it back.
 297: 	 */
 298: 
 299: cream:
 300:     if (rbuf != NULL) {
 301:         abuf = Fopen(mailname, "r+");
 302:         if (abuf == NULL)
 303:             goto newmail;
 304:         while ((c = getc(rbuf)) != EOF)
 305:             (void) putc(c, abuf);
 306:         Fclose(rbuf);
 307:         trunc(abuf);
 308:         Fclose(abuf);
 309:         alter(mailname);
 310:         Fclose(fbuf);
 311:         return;
 312:     }
 313:     demail();
 314:     Fclose(fbuf);
 315:     return;
 316: 
 317: newmail:
 318:     printf("Thou hast new mail.\n");
 319:     if (fbuf != NULL)
 320:         Fclose(fbuf);
 321: }
 322: 
 323: /*
 324:  * Preserve all the appropriate messages back in the system
 325:  * mailbox, and print a nice message indicated how many were
 326:  * saved.  On any error, just return -1.  Else return 0.
 327:  * Incorporate the any new mail that we found.
 328:  */
 329: writeback(res)
 330:     register FILE *res;
 331: {
 332:     register struct message *mp;
 333:     register int p, c;
 334:     FILE *obuf;
 335: 
 336:     p = 0;
 337:     if ((obuf = Fopen(mailname, "r+")) == NULL) {
 338:         perror(mailname);
 339:         return(-1);
 340:     }
 341: #ifndef APPEND
 342:     if (res != NULL)
 343:         while ((c = getc(res)) != EOF)
 344:             (void) putc(c, obuf);
 345: #endif
 346:     for (mp = &message[0]; mp < &message[msgCount]; mp++)
 347:         if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
 348:             p++;
 349:             if (send(mp, obuf, (struct ignoretab *)0, NOSTR) < 0) {
 350:                 perror(mailname);
 351:                 Fclose(obuf);
 352:                 return(-1);
 353:             }
 354:         }
 355: #ifdef APPEND
 356:     if (res != NULL)
 357:         while ((c = getc(res)) != EOF)
 358:             (void) putc(c, obuf);
 359: #endif
 360:     fflush(obuf);
 361:     trunc(obuf);
 362:     if (ferror(obuf)) {
 363:         perror(mailname);
 364:         Fclose(obuf);
 365:         return(-1);
 366:     }
 367:     if (res != NULL)
 368:         Fclose(res);
 369:     Fclose(obuf);
 370:     alter(mailname);
 371:     if (p == 1)
 372:         printf("Held 1 message in %s\n", mailname);
 373:     else
 374:         printf("Held %d messages in %s\n", p, mailname);
 375:     return(0);
 376: }
 377: 
 378: /*
 379:  * Terminate an editing session by attempting to write out the user's
 380:  * file from the temporary.  Save any new stuff appended to the file.
 381:  */
 382: edstop()
 383: {
 384:     register int gotcha, c;
 385:     register struct message *mp;
 386:     FILE *obuf, *ibuf, *readstat;
 387:     struct stat statb;
 388:     char tempname[30];
 389:     char *mktemp();
 390: 
 391:     if (readonly)
 392:         return;
 393:     holdsigs();
 394:     if (Tflag != NOSTR) {
 395:         if ((readstat = Fopen(Tflag, "w")) == NULL)
 396:             Tflag = NOSTR;
 397:     }
 398:     for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) {
 399:         if (mp->m_flag & MNEW) {
 400:             mp->m_flag &= ~MNEW;
 401:             mp->m_flag |= MSTATUS;
 402:         }
 403:         if (mp->m_flag & (MODIFY|MDELETED|MSTATUS))
 404:             gotcha++;
 405:         if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
 406:             char *id;
 407: 
 408:             if ((id = hfield("article-id", mp)) != NOSTR)
 409:                 fprintf(readstat, "%s\n", id);
 410:         }
 411:     }
 412:     if (Tflag != NOSTR)
 413:         Fclose(readstat);
 414:     if (!gotcha || Tflag != NOSTR)
 415:         goto done;
 416:     ibuf = NULL;
 417:     if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) {
 418:         strcpy(tempname, _PATH_TMP);
 419:         strcat(tempname, "mboxXXXXXX");
 420:         mktemp(tempname);
 421:         if ((obuf = Fopen(tempname, "w")) == NULL) {
 422:             perror(tempname);
 423:             relsesigs();
 424:             reset(0);
 425:         }
 426:         if ((ibuf = Fopen(mailname, "r")) == NULL) {
 427:             perror(mailname);
 428:             Fclose(obuf);
 429:             rm(tempname);
 430:             relsesigs();
 431:             reset(0);
 432:         }
 433:         fseek(ibuf, mailsize, 0);
 434:         while ((c = getc(ibuf)) != EOF)
 435:             (void) putc(c, obuf);
 436:         Fclose(ibuf);
 437:         Fclose(obuf);
 438:         if ((ibuf = Fopen(tempname, "r")) == NULL) {
 439:             perror(tempname);
 440:             rm(tempname);
 441:             relsesigs();
 442:             reset(0);
 443:         }
 444:         rm(tempname);
 445:     }
 446:     printf("\"%s\" ", mailname);
 447:     fflush(stdout);
 448:     if ((obuf = Fopen(mailname, "r+")) == NULL) {
 449:         perror(mailname);
 450:         relsesigs();
 451:         reset(0);
 452:     }
 453:     trunc(obuf);
 454:     c = 0;
 455:     for (mp = &message[0]; mp < &message[msgCount]; mp++) {
 456:         if ((mp->m_flag & MDELETED) != 0)
 457:             continue;
 458:         c++;
 459:         if (send(mp, obuf, (struct ignoretab *) NULL, NOSTR) < 0) {
 460:             perror(mailname);
 461:             relsesigs();
 462:             reset(0);
 463:         }
 464:     }
 465:     gotcha = (c == 0 && ibuf == NULL);
 466:     if (ibuf != NULL) {
 467:         while ((c = getc(ibuf)) != EOF)
 468:             (void) putc(c, obuf);
 469:         Fclose(ibuf);
 470:     }
 471:     fflush(obuf);
 472:     if (ferror(obuf)) {
 473:         perror(mailname);
 474:         relsesigs();
 475:         reset(0);
 476:     }
 477:     Fclose(obuf);
 478:     if (gotcha) {
 479:         rm(mailname);
 480:         printf("removed\n");
 481:     } else
 482:         printf("complete\n");
 483:     fflush(stdout);
 484: 
 485: done:
 486:     relsesigs();
 487: }

Defined functions

edstop defined in line 382; used 1 times
  • in line 89
quit defined in line 68; used 2 times
quitcmd defined in line 51; used 2 times
writeback defined in line 329; used 2 times

Defined variables

sccsid defined in line 35; never used
Last modified: 1992-10-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3297
Valid CSS Valid XHTML 1.0 Strict