Annotation of 43BSDReno/usr.bin/mail/quit.c, revision 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.