Annotation of researchv10no/cmd/nupas/print/edmail.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     print mail
                      3:  */
                      4: #include <stdio.h>
                      5: #include <setjmp.h>
                      6: #include <ctype.h>
                      7: #include <signal.h>
                      8: #include <regexp.h>
                      9: #include "mail.h"
                     10: #include "string.h"
                     11: #include "message.h"
                     12: #include "aux.h"
                     13: #include <sys/stat.h>
                     14: 
                     15: /* global to this file */
                     16: static int reverse=0;          /* ordering of mail messages */
                     17: static jmp_buf sjbuf;
                     18: int fflg;
                     19: int mflg;
                     20: int pflg;
                     21: int eflg;
                     22: SIG_TYP fint;                  /* what to do in case of int */
                     23: SIG_TYP fquit;                 /* what to do in case of quit */
                     24: SIG_TYP fpipe;                 /* what to do in case of sigpipe */
                     25: 
                     26: /* predeclared */
                     27: message *addr();
                     28: message *grange();
                     29: message *range();
                     30: message *research();
                     31: message *bresearch();
                     32: message *incraddr();
                     33: char *getre();
                     34: char *header();
                     35: int edmail();
                     36: char *doargs();
                     37: void dumpmail();
                     38: 
                     39: /* imported */
                     40: char *getlog();
                     41: FILE *lockopen();
                     42: FILE *lockreopen();
                     43: 
                     44: SIGRETURN
                     45: done(s)
                     46:        int s;
                     47: {
                     48:        cleanlocks();
                     49:        V();
                     50:        exit(1);
                     51: }
                     52: 
                     53: main(ac, av)
                     54:        int ac;
                     55:        char *av[];
                     56: {
                     57:        char outbuf[BUFSIZ];
                     58:        int writeable;
                     59:        string *user = s_new();
                     60:        char *mailfile;
                     61:        char *logname;
                     62: 
                     63:        /* set signals - make sure we don't override some previous setting */
                     64:        if ((fint=signal(SIGINT, SIG_IGN))!=SIG_DFL)
                     65:                signal(SIGINT, fint);
                     66:        else
                     67:                signal(SIGINT, fint = (SIG_TYP)done);
                     68:        if ((fquit=signal(SIGQUIT, SIG_IGN))!=SIG_DFL)
                     69:                signal(SIGQUIT, fquit);
                     70:        else
                     71:                signal(SIGQUIT, fquit = (SIG_TYP)done);
                     72:        if ((fpipe=signal(SIGPIPE, SIG_IGN))!=SIG_DFL)
                     73:                signal(SIGPIPE, fpipe);
                     74:        else
                     75:                signal(SIGPIPE, fpipe = (SIG_TYP)done);
                     76: 
                     77:        logname = getlog();
                     78:        if (logname == NULL) {
                     79:                printf ("mail: cannot determine login name\n");
                     80:                return 0;
                     81:        }
                     82:        s_append(user, logname);
                     83:        setbuf(stdout, outbuf);
                     84:        mailfile = doargs(ac, av, s_to_c(user));
                     85:        if (!fflg)
                     86:                writeable = P()==0;
                     87:        else
                     88:                writeable = 1;
                     89:        if (eflg) {
                     90:                int r = check_mbox(mailfile);
                     91:                V();
                     92:                return r;
                     93:        }
                     94:        if (read_mbox(mailfile, reverse)<0 || mlist == NULL) {
                     95:                printf("No mail\n");
                     96:                V();
                     97:                return 0;
                     98:        }
                     99:        printf("%d messages\n", mlast->pos);
                    100:        if (pflg)
                    101:                dumpmail();
                    102:        else{
                    103:                while (edmail(mailfile, reverse) && writeable){
                    104:                        if(!write_mbox(mailfile, reverse))
                    105:                                break;
                    106:                }
                    107:        }
                    108:        V();
                    109:        return 0;
                    110: }
                    111: 
                    112: /* parse arguments */
                    113: char *
                    114: doargs(ac, av, user)
                    115:        int ac;
                    116:        char *av[];
                    117:        char *user;
                    118: {
                    119:        int i;
                    120:        string *mailfile;
                    121:        char *cp;
                    122: 
                    123:        /* process args */
                    124:        mailfile = s_new();
                    125:        abspath(user, MAILROOT, mailfile);
                    126:        for (i = 1; i<ac; i++) {
                    127:                if (av[i][0]!='-') {
                    128:                        fprintf(stderr, "usage: mail [-mpre] [-f mbox]\n");
                    129:                        exit(1);
                    130:                }
                    131:                for (cp = av[i]+1; *cp; cp++) {
                    132:                        switch(*cp) {
                    133:                        case 'r':
                    134:                                reverse = 1;
                    135:                                break;
                    136:                        case 'm':
                    137:                                mflg = 1;
                    138:                                break;
                    139:                        case 'p':
                    140:                                pflg = 1;
                    141:                                break;
                    142:                        case 'e':
                    143:                                eflg = 1;
                    144:                                break;
                    145:                        case 'f':
                    146:                                fflg = 1;
                    147:                                if (i+1 >= ac) {
                    148:                                        fprintf(stderr,"mail: missing filename\n");
                    149:                                        exit(1);
                    150:                                }
                    151:                                s_append(s_restart(mailfile), av[++i]);
                    152:                                break;
                    153:                        default:
                    154:                                fprintf(stderr, "usage: mail [-mpre] [-f mbox]\n");
                    155:                                exit(1);
                    156:                        }
                    157:                }
                    158:        }
                    159:        return s_to_c(mailfile);
                    160: }
                    161: 
                    162: /* is the mailbox empty?  1 if yes, 0 if no */
                    163: int
                    164: check_mbox (mf)
                    165:        char *mf;
                    166: {
                    167:        int n, r;
                    168:        char mbuf[1000];
                    169:        string *line;
                    170:        FILE *fp;
                    171: 
                    172:        /* if file doesn't exist, no mail */
                    173:        if ((fp = fopen(mf, "r")) == NULL)
                    174:                return 1;
                    175: 
                    176:        /* if we can't read it, no mail */
                    177:        if (fgets(mbuf, sizeof(mbuf)-2, fp)==NULL){
                    178:                fclose(fp);
                    179:                return 1;
                    180:        }
                    181:        fclose(fp);
                    182: 
                    183:        /* it is empty iff delivery status is abnormal */
                    184:        n = strlen(mbuf);
                    185:        mbuf[n++] = '\n';
                    186:        mbuf[n++] = '\0';
                    187:        line = s_array(mbuf, n);
                    188:        r = delivery_status(s_restart(line)) != MF_NORMAL;
                    189: 
                    190:        s_free (line);
                    191:        return r;
                    192: }
                    193: 
                    194: /* mesage dump */
                    195: void
                    196: dumpmail()
                    197: {
                    198:        message *mp;
                    199: 
                    200:        for (mp=mlist; mp!=NULL; mp=mp->next) {
                    201:                m_print(mp, stdout, 1, 1);
                    202:        }
                    203: }
                    204: 
                    205: SIGRETURN
                    206: catchint(s)
                    207:        int s;
                    208: {
                    209:        signal(SIGINT, catchint);
                    210:        clearerr(stdin);
                    211:        clearerr(stdout);
                    212:        longjmp(sjbuf, 1);
                    213: }
                    214: 
                    215: notatnl(cp)
                    216:        char *cp;
                    217: {
                    218:        if (*cp=='\n') {
                    219:                fprintf(stderr, "!argument expected\n");
                    220:                return -1;
                    221:        }
                    222:        return 0;
                    223: }
                    224: 
                    225: int
                    226: atblank(cp)
                    227: char *cp;
                    228: {
                    229:        if (*cp!='\n' && *(cp-1)!=' ' && *(cp-1)!='\t') {
                    230:                fprintf(stderr, "newline or space expected\n");
                    231:                return -1;
                    232:        }
                    233:        return 0;
                    234: }
                    235: 
                    236: atnl(cp)
                    237:        char *cp;
                    238: {
                    239:        if (*cp!='\n') {
                    240:                fprintf(stderr, "!newline expected\n");
                    241:                return -1;
                    242:        }
                    243:        return 0;
                    244: }
                    245: 
                    246: zero(mp)
                    247:        message *mp;
                    248: {
                    249:        if (mp==mzero) {
                    250:                fprintf(stderr, "!message 0\n");
                    251:                return -1;
                    252:        }
                    253:        return 0;
                    254: }
                    255: 
                    256: #define s_skipwhite(s) for (; *s->ptr==' ' || *s->ptr=='\t'; s->ptr++);
                    257: 
                    258: /* ed style interface */
                    259: edmail(mailfile, reverse)
                    260:        char *mailfile;
                    261:        int reverse;
                    262: {
                    263:        message *dot;
                    264:        message *extent;
                    265:        string *cmd=s_new();
                    266:        char *cp;
                    267:        int cmdc;
                    268:        int i, abort=0, nopr, change=1;
                    269:        int del;
                    270: 
                    271:        extent = dot = mzero;
                    272:        nopr = mflg;
                    273:        for(;;) {
                    274:                extent = dot;   /* in case of interrupt */
                    275:                if (!nopr) {
                    276:                        /* advance only if we want to print next message */
                    277:                        if(dot->next!=NULL)
                    278:                                dot = dot->next;
                    279:                        else
                    280:                                nopr = 1;
                    281:                }
                    282:                if (setjmp(sjbuf)) {
                    283:                        /* come here after interrupt */
                    284:                        if (extent!=NULL)
                    285:                                dot = extent;
                    286:                        nopr = 1;
                    287:                        printf("\n");
                    288:                }
                    289:                if (fint==(SIG_TYP)done)
                    290:                        signal(SIGINT, catchint);
                    291:                if (!nopr&&dot!=mzero) {
                    292:                        /* print next message */
                    293:                        extent = dot;   /* in case of interrupt */
                    294:                        print(dot);
                    295:                        nopr = 1;
                    296:                }
                    297:                abort = 0;
                    298:                nopr = 1;
                    299:                change = 1;
                    300:                printf("?");
                    301:                fflush(stdout);
                    302:                if(s_read_line(stdin, s_restart(cmd)) == NULL) {
                    303:                        signal(SIGINT, fint);   /* bacause of the setjmp */
                    304:                        return 1;
                    305:                }
                    306:                s_restart(cmd);
                    307:                s_skipwhite(cmd);
                    308:                if (!mflg && *cmd->ptr=='\n' && dot==mlast) {
                    309:                        signal(SIGINT, fint);   /* bacause of the setjmp */
                    310:                        return 1;
                    311:                }
                    312:                extent = range(dot, cmd);
                    313:                s_skipwhite(cmd);
                    314:                del = 0;
                    315: compoundcmd:
                    316:                /* hack to catch a common mistake */
                    317:                if (strncmp(cmd->ptr, "mail", 4)==0)
                    318:                        cmdc = -1;
                    319:                else
                    320:                        cmdc = *cmd->ptr++;
                    321:                s_skipwhite(cmd);
                    322:                cp = cmd->ptr;
                    323:                for(; extent!=NULL && !abort; extent=extent->extent) {
                    324:                        switch(cmdc){
                    325:                        case 'b':
                    326:                                abort = atnl(cp)||(del&&delete(extent));
                    327:                                if (!abort)
                    328:                                        if (extent!=mzero)
                    329:                                                prheader(extent);
                    330:                                for(i=0; extent->next!=NULL&&i<9; i++){
                    331:                                        extent = extent->next;
                    332:                                        prheader(extent);
                    333:                                }
                    334:                                break;
                    335:                        case 'h':
                    336:                                abort = atnl(cp)||zero(extent)
                    337:                                        ||(del&&delete(extent))
                    338:                                        ||prheader(extent);
                    339:                                break;
                    340:                        case 'd':
                    341:                                if(*cp=='\n' || *cp==0){
                    342:                                        abort = zero(extent)||delete(extent);
                    343:                                        nopr = abort||mflg;
                    344:                                        break;
                    345:                                }
                    346:                                del = 1;
                    347:                                goto compoundcmd;
                    348:                        case 's':
                    349:                                abort = atblank(cp)||zero(extent)||store(extent, cp, 1)
                    350:                                        ||(del&&delete(extent));
                    351:                                nopr = abort||mflg||!del;
                    352:                                break;
                    353:                        case 'w':
                    354:                                abort = atblank(cp)||zero(extent)||notatnl(cp)
                    355:                                        ||store(extent, cp, 0)
                    356:                                        ||(del&&delete(extent));
                    357:                                nopr = abort||mflg||!del;
                    358:                                break;
                    359:                        case 'm':
                    360:                                abort = atblank(cp)||zero(extent)||notatnl(cp)
                    361:                                        ||remail(extent, cp, 0)
                    362:                                        ||(del&&delete(extent));
                    363:                                nopr = abort||mflg||!del;
                    364:                                break;
                    365:                        case 'M':
                    366:                                abort = atblank(cp)||zero(extent)||notatnl(cp)
                    367:                                        ||remail(extent, cp, 1)
                    368:                                        ||(del&&delete(extent));
                    369:                                nopr = abort||mflg||!del;
                    370:                                break;
                    371:                        case '\n':
                    372:                                abort = zero(extent)||print(extent);
                    373:                                break;
                    374:                        case 'p':
                    375:                                if(del){
                    376:                                        nopr = abort = atnl(cp)||zero(extent)
                    377:                                                ||(del&&delete(extent));
                    378:                                        break;
                    379:                                }
                    380:                                abort = atnl(cp)||zero(extent)||print(extent);
                    381:                                break;
                    382:                        case 'r':
                    383:                                abort = zero(extent)||atnl(cp)||reply(extent, 0)
                    384:                                        ||(del&&delete(extent));
                    385:                                nopr = abort||mflg||!del;
                    386:                                break;
                    387:                        case 'R':
                    388:                                abort = zero(extent)||atnl(cp)||reply(extent, 1)
                    389:                                        ||(del&&delete(extent));
                    390:                                nopr = abort||mflg||!del;
                    391:                                break;
                    392:                        case 'q':
                    393:                                abort=atnl(cp)
                    394:                                    ||(del&&(zero(extent)||delete(extent)));
                    395:                                if(abort)
                    396:                                        break;
                    397:                                signal(SIGINT, fint);   /* bacause of the setjmp */
                    398:                                return 1;
                    399:                        case '|':
                    400:                                abort = zero(extent)||notatnl(cp)
                    401:                                        ||pipemail(extent, cp, 0)
                    402:                                        ||(del&&delete(extent));
                    403:                                nopr = abort||mflg||!del;
                    404:                                break;
                    405:                        case '=':
                    406:                                abort = atnl(cp)||(del&&delete(extent))
                    407:                                        ||whereis(extent);
                    408:                                change = 0;
                    409:                                break;
                    410:                        case '!':
                    411:                                abort=del&&(zero(extent)||delete(extent));
                    412:                                if(abort)
                    413:                                        break;
                    414:                                escape(cp);
                    415:                                break;
                    416:                        case 'u':
                    417:                                abort = zero(extent)||atnl(cp)||undelete(extent);
                    418:                                break;
                    419:                        case 'x':
                    420:                                signal(SIGINT, fint);   /* bacause of the setjmp */
                    421:                                return 0;
                    422:                        case '?':
                    423:                                abort = atnl(cp)
                    424:                                        ||del&&(zero(extent)||delete(extent));
                    425:                                if(abort)
                    426:                                        break;
                    427:                                help();
                    428:                                nopr = abort = 1;
                    429:                                break;
                    430:                        case 'i':
                    431:                                abort = atnl(cp)
                    432:                                        ||(del&&(zero(extent)||delete(extent)));
                    433:                                if(abort)
                    434:                                        break;
                    435:                                reread_mbox(mailfile, reverse);
                    436:                                nopr = abort = 1;
                    437:                                break;
                    438:                        default:
                    439:                                printf("!unknown command (type ? for help)\n");
                    440:                                nopr = abort = 1;
                    441:                                break;
                    442:                        }
                    443:                        if (!abort&&change&&extent!=NULL)
                    444:                                dot = extent;
                    445:                }
                    446:        }
                    447: }
                    448: 
                    449: /* parse an address range */
                    450: message *
                    451: range(dot, cmd)
                    452:        message *dot;
                    453:        string *cmd;
                    454: {
                    455:        message *first, *last;
                    456: 
                    457:        s_skipwhite(cmd);
                    458: 
                    459:        /* get first address in range */
                    460:        switch(*cmd->ptr) {
                    461:        case 'g':
                    462:                cmd->ptr++;
                    463:                return grange(cmd);
                    464:        case ',':
                    465:                first = mlist;
                    466:                break;
                    467:        case '0': case '1': case '2': case '3': case '4':
                    468:        case '5': case '6': case '7': case '8': case '9':
                    469:                first = addr((message *)NULL, cmd);
                    470:                break;
                    471:        case '?':
                    472:                if (*(cmd->ptr+1)=='\n') {
                    473:                        if(dot!=NULL)
                    474:                                dot->extent = NULL;
                    475:                        return dot;
                    476:                }
                    477:        case '\\': case '/': case '+': case '-': case '$': case '.':
                    478:                first = addr(dot, cmd);
                    479:                break;
                    480:        case '\n':
                    481:                first = dot->next;
                    482:                if (first==NULL)
                    483:                        fprintf(stderr, "!address\n");
                    484:                break;
                    485:        default:
                    486:                if(dot!=NULL)
                    487:                        dot->extent = NULL;
                    488:                return dot;
                    489:        }
                    490:        if (first == NULL)
                    491:                return NULL;
                    492:        while(*cmd->ptr == ' ' || *cmd->ptr == '\t')
                    493:                cmd->ptr++;
                    494:        if (*cmd->ptr != ',') {
                    495:                first->extent = NULL;
                    496:                return first;
                    497:        }
                    498: 
                    499:        /* get second address in range */
                    500:        cmd->ptr++;
                    501:        while(*cmd->ptr == ' ' || *cmd->ptr == '\t')
                    502:                cmd->ptr++;
                    503:        switch(*cmd->ptr) {
                    504:        case '\\': case '/': case '?': case '+': case '-': case '$':
                    505:                last = addr(first, cmd);
                    506:                break;
                    507:        case '.':
                    508:                last = addr(dot, cmd);
                    509:                break;
                    510:        case '0': case '1': case '2': case '3': case '4':
                    511:        case '5': case '6': case '7': case '8': case '9':
                    512:                last = addr((message *)NULL, cmd);
                    513:                break;
                    514:        default:
                    515:                last = mlast;
                    516:                break;
                    517:        }
                    518:        if (last==NULL)
                    519:                return NULL;
                    520: 
                    521:        /* fill in the range */
                    522:        for(dot=first; dot!=last && dot!=NULL; dot=dot->next)
                    523:                dot->extent = dot->next;
                    524:        if (dot==NULL) {
                    525:                fprintf(stderr, "!addresses out of order\n");
                    526:                return NULL;
                    527:        }
                    528:        last->extent = NULL;
                    529:        return first;
                    530: }
                    531: 
                    532: /* parse a global range */
                    533: message *
                    534: grange(cmd)
                    535:        string *cmd;
                    536: {
                    537:        char *re;
                    538:        message *first, *last, *next;
                    539:        regexp *pp;
                    540: 
                    541:        if (*cmd->ptr == '/') {
                    542:                re = getre(cmd);
                    543:                if (re == NULL)
                    544:                        return NULL;
                    545:                if ((pp = regcomp(re))==NULL)
                    546:                        return NULL;
                    547:                first = NULL;
                    548:                for(next=mlist; next!=NULL; next=next->next)
                    549:                        if (regexec(pp, header(next), 0, 0)) {
                    550:                                if (first==NULL)
                    551:                                        first = last = next;
                    552:                                else {
                    553:                                        last->extent = next;
                    554:                                        last = next;
                    555:                                }
                    556:                                last->extent = NULL;
                    557:                        }
                    558:                if (first==NULL)
                    559:                        fprintf(stderr, "!match\n");
                    560:                free((char *)pp);
                    561:                return first;
                    562:        } else if (*cmd->ptr == '\\') {
                    563:                re = getre(cmd);
                    564:                if (re == NULL)
                    565:                        return NULL;
                    566:                if ((pp = regcomp(re))==NULL)
                    567:                        return NULL;
                    568:                first = NULL;
                    569:                for(next=mlist; next!=NULL; next=next->next){
                    570:                        s_to_c(next->body)[next->size-1]='\0';
                    571:                        if (regexec(pp, s_to_c(next->body), 0, 0)) {
                    572:                                if (first==NULL)
                    573:                                        first = last = next;
                    574:                                else {
                    575:                                        last->extent = next;
                    576:                                        last = next;
                    577:                                }
                    578:                                last->extent = NULL;
                    579:                        }
                    580:                }
                    581:                if (first==NULL)
                    582:                        fprintf(stderr, "!match\n");
                    583:                free((char *)pp);
                    584:                return first;
                    585:        } else {
                    586:                /* fill in the range */
                    587:                for(next=mlist; next!=NULL; next=next->next)
                    588:                        next->extent = next->next;
                    589:                mlast->extent = NULL;
                    590:                return mlist;
                    591:        }
                    592: }
                    593: 
                    594: /* parse an address */
                    595: message *
                    596: addr(base, cmd)
                    597:        message *base;          /* where to compute +/- from */
                    598:        string *cmd;
                    599: {
                    600:        int forward = -1;
                    601: 
                    602:        /* get direction */
                    603:        switch(*cmd->ptr) {
                    604:        case '+':
                    605:                forward = 1;
                    606:                cmd->ptr++;
                    607:                break;
                    608:        case '-':
                    609:                forward = 0;
                    610:                cmd->ptr++;
                    611:                break;
                    612:        }
                    613:        while(*cmd->ptr == ' ' || *cmd->ptr == '\t')
                    614:                cmd->ptr++;
                    615:        switch(*cmd->ptr) {
                    616:        case '0': case '1': case '2': case '3': case '4':
                    617:        case '5': case '6': case '7': case '8': case '9':
                    618:                base = incraddr(base, getnumb(cmd), forward);
                    619:                if (base==NULL)
                    620:                        break;
                    621:                return addr(base, cmd);
                    622:        case '?':
                    623:                forward = !forward;
                    624:        case '/':
                    625:                base = research(base, getre(cmd), forward);
                    626:                if (base==NULL) {
                    627:                        fprintf(stderr, "!search\n");
                    628:                        return NULL;
                    629:                }
                    630:                return addr(base, cmd);
                    631:        case '\\':
                    632:                base = bresearch(base, getre(cmd), forward);
                    633:                if (base==NULL) {
                    634:                        fprintf(stderr, "!search\n");
                    635:                        return NULL;
                    636:                }
                    637:                return addr(base, cmd);
                    638:        case '.':
                    639:                cmd->ptr++;
                    640:                return addr(base, cmd);;
                    641:        case '$':
                    642:                cmd->ptr++;
                    643:                return addr(mlast, cmd);
                    644:        default:
                    645:                /* default increment is 1 */
                    646:                if (forward != -1) {
                    647:                        base = incraddr(base, 1, forward);
                    648:                        return addr(base, cmd);
                    649:                }
                    650:                break;
                    651:        }
                    652:        if (base==NULL)
                    653:                fprintf(stderr, "!address\n");
                    654:        return base;
                    655: }
                    656: 
                    657: /* increment the base address by offset */
                    658: message *
                    659: incraddr(base, offset, forward)
                    660:        message *base;
                    661:        int offset;
                    662:        int forward;
                    663: {
                    664:        if (base==NULL) {
                    665:                base = mzero;
                    666:        }
                    667:        for(; offset > 0 && base != NULL; offset--)
                    668:                base = forward?(base->next):(base->prev);
                    669:        return base;
                    670: }
                    671: 
                    672: /* look for the message header after base that matches the reg exp */
                    673: message *
                    674: research(base, rp, forward)
                    675:        message *base;
                    676:        char *rp;
                    677:        int forward;
                    678: {
                    679:        regexp *pp;
                    680:        message *mp;
                    681: 
                    682:        if (rp == NULL) 
                    683:                return NULL;
                    684:        if ((pp = regcomp(rp))==NULL)
                    685:                return NULL;
                    686:        mp = base;
                    687:        base = (base==mzero)?(forward?(mp->prev):(mp->next)):base;
                    688:        do {
                    689:                mp = forward?(mp->next):(mp->prev);
                    690:                if (mp==NULL)
                    691:                        mp = forward?mlist:mlast;
                    692:                if (regexec(pp, header(mp), 0, 0)) {
                    693:                        free((char *)pp);
                    694:                        return mp;
                    695:                }
                    696:        } while (mp!=base);
                    697:        free((char *)pp);
                    698:        return NULL;
                    699: }
                    700: 
                    701: /* look for the message after base that matches the reg exp */
                    702: message *
                    703: bresearch(base, rp, forward)
                    704:        message *base;
                    705:        char *rp;
                    706:        int forward;
                    707: {
                    708:        regexp *pp;
                    709:        message *mp;
                    710: 
                    711:        if (rp == NULL) 
                    712:                return NULL;
                    713:        if ((pp = regcomp(rp))==NULL)
                    714:                return NULL;
                    715:        mp = base = (base==mzero)?mzero->next:base;
                    716:        do {
                    717:                mp = forward?(mp->next):(mp->prev);
                    718:                if (mp==NULL)
                    719:                        mp = forward?mlist:mlast;
                    720:                s_to_c(mp->body)[mp->size-1]='\0';
                    721:                if (regexec(pp, s_to_c(mp->body), 0, 0)) {
                    722:                        free((char *)pp);
                    723:                        return mp;
                    724:                }
                    725:        } while (mp!=base);
                    726:        free((char *)pp);
                    727:        return NULL;
                    728: }
                    729: 
                    730: /* get a number out of the command */
                    731: int
                    732: getnumb(cmd)
                    733:        string *cmd;
                    734: {
                    735:        int offset=0;
                    736:        while (isdigit(*cmd->ptr))
                    737:                offset = offset*10 + *cmd->ptr++ - '0';
                    738:        return offset;
                    739: }
                    740: 
                    741: /* get a regular exression out of the command */
                    742: char *
                    743: getre(cmd)
                    744:        string *cmd;
                    745: {
                    746:        static char re[80];
                    747:        char *cp=re;
                    748:        char term = *cmd->ptr++;
                    749: 
                    750:        while (*cmd->ptr!='\0' && *cmd->ptr!='\n' && *cmd->ptr!=term)
                    751:                *cp++ = *cmd->ptr++;
                    752:        if (*cmd->ptr == term)
                    753:                cmd->ptr++;
                    754:        if (cp == re) {
                    755:                if (*re == '\0') {
                    756:                        fprintf(stderr, "!no previous regular expression\n");
                    757:                        return NULL;
                    758:                }
                    759:        } else
                    760:                *cp = '\0';
                    761:        return re;
                    762: }
                    763: 
                    764: regerror(msg)  
                    765:        char *msg;
                    766: {
                    767:        fprintf(stderr, "!illegal address: %s\n", msg);
                    768: }

unix.superglobalmegacorp.com

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