# 2.11BSD#431 - /usr/src/ucb/Mail/quit.c

##### Functions

    edstop            X
    quit              X
    quitcmd           X
    writeback         X

       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

- in /usr/src/ucb/Mail/lex.c line 110
- in /usr/src/ucb/Mail/main.c line 245

quitcmd defined in line 51; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 48, 106

writeback defined in line 329; used 2 times

- in line 183, 289

#### 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: 1242 |