Annotation of 41BSD/cmd/ucbmail/cmd2.c, revision 1.1.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.