Annotation of 41BSD/cmd/ucbmail/cmd2.c, revision 1.1

1.1     ! root        1: #
        !             2: 
        !             3: #include "rcv.h"
        !             4: #include <sys/stat.h>
        !             5: 
        !             6: /*
        !             7:  * Mail -- a mail program
        !             8:  *
        !             9:  * More user commands.
        !            10:  */
        !            11: 
        !            12: /*
        !            13:  * If any arguments were given, go to the next applicable argument
        !            14:  * following dot, otherwise, go to the next applicable message.
        !            15:  * If given as first command with no arguments, print first message.
        !            16:  */
        !            17: 
        !            18: next(msgvec)
        !            19:        int *msgvec;
        !            20: {
        !            21:        register struct message *mp;
        !            22:        register int *ip, *ip2;
        !            23:        int list[2], mdot;
        !            24: 
        !            25:        if (*msgvec != NULL) {
        !            26: 
        !            27:                /*
        !            28:                 * If some messages were supplied, find the 
        !            29:                 * first applicable one following dot using
        !            30:                 * wrap around.
        !            31:                 */
        !            32: 
        !            33:                mdot = dot - &message[0] + 1;
        !            34:                for (ip = msgvec; *ip != NULL; ip++)
        !            35:                        if (*ip > mdot)
        !            36:                                break;
        !            37:                if (*ip == NULL)
        !            38:                        ip = msgvec;
        !            39:                ip2 = ip;
        !            40:                do {
        !            41:                        if (*ip2 != NULL)
        !            42:                                ip2++;
        !            43:                        if (*ip2 == NULL)
        !            44:                                ip2 = msgvec;
        !            45:                        mp = &message[*ip2 - 1];
        !            46:                        if ((mp->m_flag & MDELETED) == 0) {
        !            47:                                dot = mp;
        !            48:                                goto hitit;
        !            49:                        }
        !            50:                } while (ip2 != ip);
        !            51:                printf("No messages applicable\n");
        !            52:                return(1);
        !            53:        }
        !            54: 
        !            55:        /*
        !            56:         * If this is the first command, select message 1.
        !            57:         * Note that this must exist for us to get here at all.
        !            58:         */
        !            59: 
        !            60:        if (!sawcom) {
        !            61:                dot = &message[0];
        !            62:                goto hitit;
        !            63:        }
        !            64: 
        !            65:        /*
        !            66:         * Just find the next good message after dot, no
        !            67:         * wraparound.
        !            68:         */
        !            69: 
        !            70:        for (mp = dot+1; mp < &message[msgCount]; mp++)
        !            71:                if ((mp->m_flag & (MDELETED|MSAVED)) == 0)
        !            72:                        break;
        !            73:        if (mp >= &message[msgCount]) {
        !            74:                printf("At EOF\n");
        !            75:                return(0);
        !            76:        }
        !            77:        dot = mp;
        !            78: hitit:
        !            79:        /*
        !            80:         * Print dot.
        !            81:         */
        !            82: 
        !            83:        list[0] = dot - &message[0] + 1;
        !            84:        list[1] = NULL;
        !            85:        return(type(list));
        !            86: }
        !            87: 
        !            88: /*
        !            89:  * Save the indicated messages at the end of the passed file name.
        !            90:  */
        !            91: 
        !            92: save(str)
        !            93:        char str[];
        !            94: {
        !            95:        register int *ip, mesg;
        !            96:        register struct message *mp;
        !            97:        char *file, *disp;
        !            98:        int f, *msgvec, lc, cc, t;
        !            99:        FILE *obuf;
        !           100:        struct stat statb;
        !           101: 
        !           102:        msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
        !           103:        if ((file = snarf(str, &f)) == NOSTR)
        !           104:                return(1);
        !           105:        if (!f) {
        !           106:                *msgvec = first(0, MMNORM);
        !           107:                if (*msgvec == NULL) {
        !           108:                        printf("No messages to save.\n");
        !           109:                        return(1);
        !           110:                }
        !           111:                msgvec[1] = NULL;
        !           112:        }
        !           113:        if (f && getmsglist(str, msgvec, 0) < 0)
        !           114:                return(1);
        !           115:        if ((file = expand(file)) == NOSTR)
        !           116:                return(1);
        !           117:        printf("\"%s\" ", file);
        !           118:        flush();
        !           119:        if (stat(file, &statb) >= 0)
        !           120:                disp = "[Appended]";
        !           121:        else
        !           122:                disp = "[New file]";
        !           123:        if ((obuf = fopen(file, "a")) == NULL) {
        !           124:                perror(NOSTR);
        !           125:                return(1);
        !           126:        }
        !           127:        cc = lc = 0;
        !           128:        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
        !           129:                mesg = *ip;
        !           130:                touch(mesg);
        !           131:                mp = &message[mesg-1];
        !           132:                if ((t = send(mp, obuf)) < 0) {
        !           133:                        perror(file);
        !           134:                        fclose(obuf);
        !           135:                        return(1);
        !           136:                }
        !           137:                lc += t;
        !           138:                cc += msize(mp);
        !           139:                mp->m_flag |= MSAVED;
        !           140:        }
        !           141:        fflush(obuf);
        !           142:        if (ferror(obuf))
        !           143:                perror(file);
        !           144:        fclose(obuf);
        !           145:        printf("%s %d/%d\n", disp, lc, cc);
        !           146:        return(0);
        !           147: }
        !           148: 
        !           149: /*
        !           150:  * Write the indicated messages at the end of the passed
        !           151:  * file name, minus header and trailing blank line.
        !           152:  */
        !           153: 
        !           154: swrite(str)
        !           155:        char str[];
        !           156: {
        !           157:        register int *ip, mesg;
        !           158:        register struct message *mp;
        !           159:        register char *file, *disp;
        !           160:        char linebuf[BUFSIZ];
        !           161:        int f, *msgvec, lc, cc, t;
        !           162:        FILE *obuf, *mesf;
        !           163:        struct stat statb;
        !           164: 
        !           165:        msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
        !           166:        if ((file = snarf(str, &f)) == NOSTR)
        !           167:                return(1);
        !           168:        if ((file = expand(file)) == NOSTR)
        !           169:                return(1);
        !           170:        if (!f) {
        !           171:                *msgvec = first(0, MMNORM);
        !           172:                if (*msgvec == NULL) {
        !           173:                        printf("No messages to write.\n");
        !           174:                        return(1);
        !           175:                }
        !           176:                msgvec[1] = NULL;
        !           177:        }
        !           178:        if (f && getmsglist(str, msgvec, 0) < 0)
        !           179:                return(1);
        !           180:        printf("\"%s\" ", file);
        !           181:        flush();
        !           182:        if (stat(file, &statb) >= 0)
        !           183:                disp = "[Appended]";
        !           184:        else
        !           185:                disp = "[New file]";
        !           186:        if ((obuf = fopen(file, "a")) == NULL) {
        !           187:                perror(NOSTR);
        !           188:                return(1);
        !           189:        }
        !           190:        cc = lc = 0;
        !           191:        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
        !           192:                mesg = *ip;
        !           193:                touch(mesg);
        !           194:                mp = &message[mesg-1];
        !           195:                mesf = setinput(mp);
        !           196:                t = mp->m_lines - 2;
        !           197:                readline(mesf, linebuf);
        !           198:                while (t-- > 0) {
        !           199:                        fgets(linebuf, BUFSIZ, mesf);
        !           200:                        fputs(linebuf, obuf);
        !           201:                        cc += strlen(linebuf);
        !           202:                }
        !           203:                lc += mp->m_lines - 2;
        !           204:                mp->m_flag |= MSAVED;
        !           205:        }
        !           206:        fflush(obuf);
        !           207:        if (ferror(obuf))
        !           208:                perror(file);
        !           209:        fclose(obuf);
        !           210:        printf("%s %d/%d\n", disp, lc, cc);
        !           211:        return(0);
        !           212: }
        !           213: 
        !           214: /*
        !           215:  * Snarf the file from the end of the command line and
        !           216:  * return a pointer to it.  If there is no file attached,
        !           217:  * just return NOSTR.  Put a null in front of the file
        !           218:  * name so that the message list processing won't see it,
        !           219:  * unless the file name is the only thing on the line, in
        !           220:  * which case, return 0 in the reference flag variable.
        !           221:  */
        !           222: 
        !           223: char *
        !           224: snarf(linebuf, flag)
        !           225:        char linebuf[];
        !           226:        int *flag;
        !           227: {
        !           228:        register char *cp;
        !           229: 
        !           230:        *flag = 1;
        !           231:        cp = strlen(linebuf) + linebuf - 1;
        !           232: 
        !           233:        /*
        !           234:         * Strip away trailing blanks.
        !           235:         */
        !           236: 
        !           237:        while (*cp == ' ' && cp > linebuf)
        !           238:                cp--;
        !           239:        *++cp = 0;
        !           240: 
        !           241:        /*
        !           242:         * Now search for the beginning of the file name.
        !           243:         */
        !           244: 
        !           245:        while (cp > linebuf && !any(*cp, "\t "))
        !           246:                cp--;
        !           247:        if (*cp == '\0') {
        !           248:                printf("No file specified.\n");
        !           249:                return(NOSTR);
        !           250:        }
        !           251:        if (any(*cp, " \t"))
        !           252:                *cp++ = 0;
        !           253:        else
        !           254:                *flag = 0;
        !           255:        return(cp);
        !           256: }
        !           257: 
        !           258: /*
        !           259:  * Delete messages.
        !           260:  */
        !           261: 
        !           262: delete(msgvec)
        !           263:        int msgvec[];
        !           264: {
        !           265:        return(delm(msgvec));
        !           266: }
        !           267: 
        !           268: /*
        !           269:  * Delete messages, then type the new dot.
        !           270:  */
        !           271: 
        !           272: deltype(msgvec)
        !           273:        int msgvec[];
        !           274: {
        !           275:        int list[2];
        !           276: 
        !           277:        if (delm(msgvec) >= 0) {
        !           278:                list[0] = dot - &message[0];
        !           279:                list[0]++;
        !           280:                touch(list[0]);
        !           281:                list[1] = NULL;
        !           282:                return(type(list));
        !           283:        }
        !           284:        else {
        !           285:                printf("No more messages\n");
        !           286:                return(0);
        !           287:        }
        !           288: }
        !           289: 
        !           290: /*
        !           291:  * Delete the indicated messages.
        !           292:  * Set dot to some nice place afterwards.
        !           293:  * Internal interface.
        !           294:  */
        !           295: 
        !           296: delm(msgvec)
        !           297:        int *msgvec;
        !           298: {
        !           299:        register struct message *mp;
        !           300:        register *ip, mesg;
        !           301:        int last;
        !           302: 
        !           303:        last = NULL;
        !           304:        for (ip = msgvec; *ip != NULL; ip++) {
        !           305:                mesg = *ip;
        !           306:                touch(mesg);
        !           307:                mp = &message[mesg-1];
        !           308:                mp->m_flag |= MDELETED;
        !           309:                mp->m_flag &= ~(MPRESERVE|MSAVED);
        !           310:                last = mesg;
        !           311:        }
        !           312:        if (last != NULL) {
        !           313:                dot = &message[last-1];
        !           314:                last = first(0, MDELETED);
        !           315:                if (last != NULL) {
        !           316:                        dot = &message[last-1];
        !           317:                        return(0);
        !           318:                }
        !           319:                else {
        !           320:                        dot = &message[0];
        !           321:                        return(-1);
        !           322:                }
        !           323:        }
        !           324: 
        !           325:        /*
        !           326:         * Following can't happen -- it keeps lint happy
        !           327:         */
        !           328: 
        !           329:        return(-1);
        !           330: }
        !           331: 
        !           332: /*
        !           333:  * Undelete the indicated messages.
        !           334:  */
        !           335: 
        !           336: undelete(msgvec)
        !           337:        int *msgvec;
        !           338: {
        !           339:        register struct message *mp;
        !           340:        register *ip, mesg;
        !           341: 
        !           342:        for (ip = msgvec; ip-msgvec < msgCount; ip++) {
        !           343:                mesg = *ip;
        !           344:                if (mesg == 0)
        !           345:                        return;
        !           346:                touch(mesg);
        !           347:                mp = &message[mesg-1];
        !           348:                dot = mp;
        !           349:                mp->m_flag &= ~MDELETED;
        !           350:        }
        !           351: }
        !           352: 
        !           353: /*
        !           354:  * Interactively dump core on "core"
        !           355:  */
        !           356: 
        !           357: core()
        !           358: {
        !           359:        register int pid;
        !           360:        int status;
        !           361: 
        !           362:        if ((pid = vfork()) == -1) {
        !           363:                perror("fork");
        !           364:                return(1);
        !           365:        }
        !           366:        if (pid == 0) {
        !           367:                abort();
        !           368:                _exit(1);
        !           369:        }
        !           370:        printf("Okie dokie");
        !           371:        fflush(stdout);
        !           372:        while (wait(&status) != pid)
        !           373:                ;
        !           374:        if (status & 0200)
        !           375:                printf(" -- Core dumped\n");
        !           376:        else
        !           377:                printf("\n");
        !           378: }

unix.superglobalmegacorp.com

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