Annotation of 43BSDReno/usr.bin/mail/quit.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.