Annotation of 3BSD/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|MSAVED)) == 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;
                     98:        int f, *msgvec, lc, cc, t;
                     99:        FILE *obuf;
                    100: 
                    101:        msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
                    102:        if ((file = snarf(str, &f)) == NOSTR)
                    103:                return(1);
                    104:        if (!f) {
                    105:                *msgvec = first(0, MMNORM);
                    106:                if (*msgvec == NULL) {
                    107:                        printf("No messages to save.\n");
                    108:                        return(1);
                    109:                }
                    110:                msgvec[1] = NULL;
                    111:        }
                    112:        if (f && getmsglist(str, msgvec, 0) < 0)
                    113:                return(1);
                    114:        if ((file = expand(file)) == NOSTR)
                    115:                return(1);
                    116:        printf("\"%s\" ", file);
                    117:        flush();
                    118:        if ((obuf = fopen(file, "a")) == NULL) {
                    119:                perror(NOSTR);
                    120:                return(1);
                    121:        }
                    122:        cc = lc = 0;
                    123:        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
                    124:                mesg = *ip;
                    125:                touch(mesg);
                    126:                mp = &message[mesg-1];
                    127:                if ((t = send(mp, obuf)) < 0) {
                    128:                        perror(file);
                    129:                        fclose(obuf);
                    130:                        return(1);
                    131:                }
                    132:                lc += t;
                    133:                cc += msize(mp);
                    134:                mp->m_flag |= MSAVED;
                    135:        }
                    136:        fflush(obuf);
                    137:        if (ferror(obuf))
                    138:                perror(file);
                    139:        fclose(obuf);
                    140:        printf("%d/%d\n", lc, cc);
                    141:        return(0);
                    142: }
                    143: 
                    144: /*
                    145:  * Write the indicated messages at the end of the passed
                    146:  * file name, minus header and trailing blank line.
                    147:  */
                    148: 
                    149: swrite(str)
                    150:        char str[];
                    151: {
                    152:        register int *ip, mesg;
                    153:        register struct message *mp;
                    154:        register char *file;
                    155:        char linebuf[BUFSIZ];
                    156:        int f, *msgvec, lc, cc, t;
                    157:        FILE *obuf, *mesf;
                    158: 
                    159:        msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
                    160:        if ((file = snarf(str, &f)) == NOSTR)
                    161:                return(1);
                    162:        if ((file = expand(file)) == NOSTR)
                    163:                return(1);
                    164:        if (!f) {
                    165:                *msgvec = first(0, MMNORM);
                    166:                if (*msgvec == NULL) {
                    167:                        printf("No messages to write.\n");
                    168:                        return(1);
                    169:                }
                    170:                msgvec[1] = NULL;
                    171:        }
                    172:        if (f && getmsglist(str, msgvec, 0) < 0)
                    173:                return(1);
                    174:        printf("\"%s\" ", file);
                    175:        flush();
                    176:        if ((obuf = fopen(file, "a")) == NULL) {
                    177:                perror(NOSTR);
                    178:                return(1);
                    179:        }
                    180:        cc = lc = 0;
                    181:        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
                    182:                mesg = *ip;
                    183:                touch(mesg);
                    184:                mp = &message[mesg-1];
                    185:                mesf = setinput(mp);
                    186:                t = mp->m_lines - 2;
                    187:                readline(mesf, linebuf);
                    188:                while (t-- > 0) {
                    189:                        fgets(linebuf, BUFSIZ, mesf);
                    190:                        fputs(linebuf, obuf);
                    191:                        cc += strlen(linebuf);
                    192:                }
                    193:                lc += mp->m_lines - 2;
                    194:                mp->m_flag |= MSAVED;
                    195:        }
                    196:        fflush(obuf);
                    197:        if (ferror(obuf))
                    198:                perror(file);
                    199:        fclose(obuf);
                    200:        printf("%d/%d\n", lc, cc);
                    201:        return(0);
                    202: }
                    203: 
                    204: /*
                    205:  * Snarf the file from the end of the command line and
                    206:  * return a pointer to it.  If there is no file attached,
                    207:  * just return NOSTR.  Put a null in front of the file
                    208:  * name so that the message list processing won't see it,
                    209:  * unless the file name is the only thing on the line, in
                    210:  * which case, return 0 in the reference flag variable.
                    211:  */
                    212: 
                    213: char *
                    214: snarf(linebuf, flag)
                    215:        char linebuf[];
                    216:        int *flag;
                    217: {
                    218:        register char *cp;
                    219: 
                    220:        *flag = 1;
                    221:        cp = strlen(linebuf) + linebuf - 1;
                    222: 
                    223:        /*
                    224:         * Strip away trailing blanks.
                    225:         */
                    226: 
                    227:        while (*cp == ' ' && cp > linebuf)
                    228:                cp--;
                    229:        *++cp = 0;
                    230: 
                    231:        /*
                    232:         * Now search for the beginning of the file name.
                    233:         */
                    234: 
                    235:        while (cp > linebuf && !any(*cp, "\t "))
                    236:                cp--;
                    237:        if (*cp == '\0') {
                    238:                printf("No file specified.\n");
                    239:                return(NOSTR);
                    240:        }
                    241:        if (any(*cp, " \t"))
                    242:                *cp++ = 0;
                    243:        else
                    244:                *flag = 0;
                    245:        return(cp);
                    246: }
                    247: 
                    248: /*
                    249:  * Delete messages.
                    250:  */
                    251: 
                    252: delete(msgvec)
                    253:        int msgvec[];
                    254: {
                    255:        return(delm(msgvec));
                    256: }
                    257: 
                    258: /*
                    259:  * Delete messages, then type the new dot.
                    260:  */
                    261: 
                    262: deltype(msgvec)
                    263:        int msgvec[];
                    264: {
                    265:        int list[2];
                    266: 
                    267:        if (delm(msgvec) >= 0) {
                    268:                list[0] = dot - &message[0];
                    269:                list[0]++;
                    270:                touch(list[0]);
                    271:                list[1] = NULL;
                    272:                return(type(list));
                    273:        }
                    274:        else {
                    275:                printf("No more messages\n");
                    276:                return(0);
                    277:        }
                    278: }
                    279: 
                    280: /*
                    281:  * Delete the indicated messages.
                    282:  * Set dot to some nice place afterwards.
                    283:  * Internal interface.
                    284:  */
                    285: 
                    286: delm(msgvec)
                    287:        int *msgvec;
                    288: {
                    289:        register struct message *mp;
                    290:        register *ip, mesg;
                    291:        int last;
                    292: 
                    293:        last = NULL;
                    294:        for (ip = msgvec; *ip != NULL; ip++) {
                    295:                mesg = *ip;
                    296:                touch(mesg);
                    297:                mp = &message[mesg-1];
                    298:                mp->m_flag |= MDELETED;
                    299:                mp->m_flag &= ~(MPRESERVE|MSAVED);
                    300:                last = mesg;
                    301:        }
                    302:        if (last != NULL) {
                    303:                dot = &message[last-1];
                    304:                last = first(0, MDELETED);
                    305:                if (last != NULL) {
                    306:                        dot = &message[last-1];
                    307:                        return(0);
                    308:                }
                    309:                else {
                    310:                        dot = &message[0];
                    311:                        return(-1);
                    312:                }
                    313:        }
                    314: 
                    315:        /*
                    316:         * Following can't happen -- it keeps lint happy
                    317:         */
                    318: 
                    319:        return(-1);
                    320: }
                    321: 
                    322: /*
                    323:  * Undelete the indicated messages.
                    324:  */
                    325: 
                    326: undelete(msgvec)
                    327:        int *msgvec;
                    328: {
                    329:        register struct message *mp;
                    330:        register *ip, mesg;
                    331: 
                    332:        for (ip = msgvec; ip-msgvec < msgCount; ip++) {
                    333:                mesg = *ip;
                    334:                if (mesg == 0)
                    335:                        return;
                    336:                touch(mesg);
                    337:                mp = &message[mesg-1];
                    338:                dot = mp;
                    339:                mp->m_flag &= ~MDELETED;
                    340:        }
                    341: }
                    342: 
                    343: /*
                    344:  * Interactively dump core on "core"
                    345:  */
                    346: 
                    347: core()
                    348: {
                    349:        register int pid;
                    350:        int status;
                    351: 
                    352:        if ((pid = vfork()) == -1) {
                    353:                perror("fork");
                    354:                return(1);
                    355:        }
                    356:        if (pid == 0) {
                    357:                abort();
                    358:                _exit(1);
                    359:        }
                    360:        printf("Okie dokie");
                    361:        fflush(stdout);
                    362:        while (wait(&status) != pid)
                    363:                ;
                    364:        if (status & 0200)
                    365:                printf(" -- Core dumped\n");
                    366:        else
                    367:                printf("\n");
                    368: }

unix.superglobalmegacorp.com

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