Annotation of 43BSD/ucb/Mail/aux.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char *sccsid = "@(#)aux.c       5.4 (Berkeley) 1/13/86";
                      9: #endif not lint
                     10: 
                     11: #include "rcv.h"
                     12: #include <sys/stat.h>
                     13: #include <ctype.h>
                     14: 
                     15: /*
                     16:  * Mail -- a mail program
                     17:  *
                     18:  * Auxiliary functions.
                     19:  */
                     20: 
                     21: /*
                     22:  * Return a pointer to a dynamic copy of the argument.
                     23:  */
                     24: 
                     25: char *
                     26: savestr(str)
                     27:        char *str;
                     28: {
                     29:        register char *cp, *cp2, *top;
                     30: 
                     31:        for (cp = str; *cp; cp++)
                     32:                ;
                     33:        top = salloc(cp-str + 1);
                     34:        if (top == NOSTR)
                     35:                return(NOSTR);
                     36:        for (cp = str, cp2 = top; *cp; cp++)
                     37:                *cp2++ = *cp;
                     38:        *cp2 = 0;
                     39:        return(top);
                     40: }
                     41: 
                     42: /*
                     43:  * Copy the name from the passed header line into the passed
                     44:  * name buffer.  Null pad the name buffer.
                     45:  */
                     46: 
                     47: copyname(linebuf, nbuf)
                     48:        char *linebuf, *nbuf;
                     49: {
                     50:        register char *cp, *cp2;
                     51: 
                     52:        for (cp = linebuf + 5, cp2 = nbuf; *cp != ' ' && cp2-nbuf < 8; cp++)
                     53:                *cp2++ = *cp;
                     54:        while (cp2-nbuf < 8)
                     55:                *cp2++ = 0;
                     56: }
                     57: 
                     58: /*
                     59:  * Announce a fatal error and die.
                     60:  */
                     61: 
                     62: panic(str)
                     63:        char *str;
                     64: {
                     65:        prs("panic: ");
                     66:        prs(str);
                     67:        prs("\n");
                     68:        exit(1);
                     69: }
                     70: 
                     71: /*
                     72:  * Catch stdio errors and report them more nicely.
                     73:  */
                     74: 
                     75: _error(str)
                     76:        char *str;
                     77: {
                     78:        prs("Stdio Error: ");
                     79:        prs(str);
                     80:        prs("\n");
                     81:        abort();
                     82: }
                     83: 
                     84: /*
                     85:  * Print a string on diagnostic output.
                     86:  */
                     87: 
                     88: prs(str)
                     89:        char *str;
                     90: {
                     91:        register char *s;
                     92: 
                     93:        for (s = str; *s; s++)
                     94:                ;
                     95:        write(2, str, s-str);
                     96: }
                     97: 
                     98: /*
                     99:  * Touch the named message by setting its MTOUCH flag.
                    100:  * Touched messages have the effect of not being sent
                    101:  * back to the system mailbox on exit.
                    102:  */
                    103: 
                    104: touch(mesg)
                    105: {
                    106:        register struct message *mp;
                    107: 
                    108:        if (mesg < 1 || mesg > msgCount)
                    109:                return;
                    110:        mp = &message[mesg-1];
                    111:        mp->m_flag |= MTOUCH;
                    112:        if ((mp->m_flag & MREAD) == 0)
                    113:                mp->m_flag |= MREAD|MSTATUS;
                    114: }
                    115: 
                    116: /*
                    117:  * Test to see if the passed file name is a directory.
                    118:  * Return true if it is.
                    119:  */
                    120: 
                    121: isdir(name)
                    122:        char name[];
                    123: {
                    124:        struct stat sbuf;
                    125: 
                    126:        if (stat(name, &sbuf) < 0)
                    127:                return(0);
                    128:        return((sbuf.st_mode & S_IFMT) == S_IFDIR);
                    129: }
                    130: 
                    131: /*
                    132:  * Count the number of arguments in the given string raw list.
                    133:  */
                    134: 
                    135: argcount(argv)
                    136:        char **argv;
                    137: {
                    138:        register char **ap;
                    139: 
                    140:        for (ap = argv; *ap != NOSTR; ap++)
                    141:                ;       
                    142:        return(ap-argv);
                    143: }
                    144: 
                    145: /*
                    146:  * Given a file address, determine the
                    147:  * block number it represents.
                    148:  */
                    149: 
                    150: blockof(off)
                    151:        off_t off;
                    152: {
                    153:        off_t a;
                    154: 
                    155:        a = off >> 9;
                    156:        a &= 077777;
                    157:        return((int) a);
                    158: }
                    159: 
                    160: /*
                    161:  * Take a file address, and determine
                    162:  * its offset in the current block.
                    163:  */
                    164: 
                    165: offsetof(off)
                    166:        off_t off;
                    167: {
                    168:        off_t a;
                    169: 
                    170:        a = off & 0777;
                    171:        return((int) a);
                    172: }
                    173: 
                    174: /*
                    175:  * Return the desired header line from the passed message
                    176:  * pointer (or NOSTR if the desired header field is not available).
                    177:  */
                    178: 
                    179: char *
                    180: hfield(field, mp)
                    181:        char field[];
                    182:        struct message *mp;
                    183: {
                    184:        register FILE *ibuf;
                    185:        char linebuf[LINESIZE];
                    186:        register int lc;
                    187: 
                    188:        ibuf = setinput(mp);
                    189:        if ((lc = mp->m_lines) <= 0)
                    190:                return(NOSTR);
                    191:        if (readline(ibuf, linebuf) < 0)
                    192:                return(NOSTR);
                    193:        lc--;
                    194:        do {
                    195:                lc = gethfield(ibuf, linebuf, lc);
                    196:                if (lc == -1)
                    197:                        return(NOSTR);
                    198:                if (ishfield(linebuf, field))
                    199:                        return(savestr(hcontents(linebuf)));
                    200:        } while (lc > 0);
                    201:        return(NOSTR);
                    202: }
                    203: 
                    204: /*
                    205:  * Return the next header field found in the given message.
                    206:  * Return > 0 if something found, <= 0 elsewise.
                    207:  * Must deal with \ continuations & other such fraud.
                    208:  */
                    209: 
                    210: gethfield(f, linebuf, rem)
                    211:        register FILE *f;
                    212:        char linebuf[];
                    213:        register int rem;
                    214: {
                    215:        char line2[LINESIZE];
                    216:        long loc;
                    217:        register char *cp, *cp2;
                    218:        register int c;
                    219: 
                    220: 
                    221:        for (;;) {
                    222:                if (rem <= 0)
                    223:                        return(-1);
                    224:                if (readline(f, linebuf) < 0)
                    225:                        return(-1);
                    226:                rem--;
                    227:                if (strlen(linebuf) == 0)
                    228:                        return(-1);
                    229:                if (isspace(linebuf[0]))
                    230:                        continue;
                    231:                if (linebuf[0] == '>')
                    232:                        continue;
                    233:                cp = index(linebuf, ':');
                    234:                if (cp == NOSTR)
                    235:                        continue;
                    236:                for (cp2 = linebuf; cp2 < cp; cp2++)
                    237:                        if (isdigit(*cp2))
                    238:                                continue;
                    239:                
                    240:                /*
                    241:                 * I guess we got a headline.
                    242:                 * Handle wraparounding
                    243:                 */
                    244:                
                    245:                for (;;) {
                    246:                        if (rem <= 0)
                    247:                                break;
                    248: #ifdef CANTELL
                    249:                        loc = ftell(f);
                    250:                        if (readline(f, line2) < 0)
                    251:                                break;
                    252:                        rem--;
                    253:                        if (!isspace(line2[0])) {
                    254:                                fseek(f, loc, 0);
                    255:                                rem++;
                    256:                                break;
                    257:                        }
                    258: #else
                    259:                        c = getc(f);
                    260:                        ungetc(c, f);
                    261:                        if (!isspace(c) || c == '\n')
                    262:                                break;
                    263:                        if (readline(f, line2) < 0)
                    264:                                break;
                    265:                        rem--;
                    266: #endif
                    267:                        cp2 = line2;
                    268:                        for (cp2 = line2; *cp2 != 0 && isspace(*cp2); cp2++)
                    269:                                ;
                    270:                        if (strlen(linebuf) + strlen(cp2) >= LINESIZE-2)
                    271:                                break;
                    272:                        cp = &linebuf[strlen(linebuf)];
                    273:                        while (cp > linebuf &&
                    274:                            (isspace(cp[-1]) || cp[-1] == '\\'))
                    275:                                cp--;
                    276:                        *cp++ = ' ';
                    277:                        for (cp2 = line2; *cp2 != 0 && isspace(*cp2); cp2++)
                    278:                                ;
                    279:                        strcpy(cp, cp2);
                    280:                }
                    281:                if ((c = strlen(linebuf)) > 0) {
                    282:                        cp = &linebuf[c-1];
                    283:                        while (cp > linebuf && isspace(*cp))
                    284:                                cp--;
                    285:                        *++cp = 0;
                    286:                }
                    287:                return(rem);
                    288:        }
                    289:        /* NOTREACHED */
                    290: }
                    291: 
                    292: /*
                    293:  * Check whether the passed line is a header line of
                    294:  * the desired breed.
                    295:  */
                    296: 
                    297: ishfield(linebuf, field)
                    298:        char linebuf[], field[];
                    299: {
                    300:        register char *cp;
                    301:        register int c;
                    302: 
                    303:        if ((cp = index(linebuf, ':')) == NOSTR)
                    304:                return(0);
                    305:        if (cp == linebuf)
                    306:                return(0);
                    307:        cp--;
                    308:        while (cp > linebuf && isspace(*cp))
                    309:                cp--;
                    310:        c = *++cp;
                    311:        *cp = 0;
                    312:        if (icequal(linebuf ,field)) {
                    313:                *cp = c;
                    314:                return(1);
                    315:        }
                    316:        *cp = c;
                    317:        return(0);
                    318: }
                    319: 
                    320: /*
                    321:  * Extract the non label information from the given header field
                    322:  * and return it.
                    323:  */
                    324: 
                    325: char *
                    326: hcontents(hfield)
                    327:        char hfield[];
                    328: {
                    329:        register char *cp;
                    330: 
                    331:        if ((cp = index(hfield, ':')) == NOSTR)
                    332:                return(NOSTR);
                    333:        cp++;
                    334:        while (*cp && isspace(*cp))
                    335:                cp++;
                    336:        return(cp);
                    337: }
                    338: 
                    339: /*
                    340:  * Compare two strings, ignoring case.
                    341:  */
                    342: 
                    343: icequal(s1, s2)
                    344:        register char *s1, *s2;
                    345: {
                    346: 
                    347:        while (raise(*s1++) == raise(*s2))
                    348:                if (*s2++ == 0)
                    349:                        return(1);
                    350:        return(0);
                    351: }
                    352: 
                    353: /*
                    354:  * Copy a string, lowercasing it as we go.
                    355:  */
                    356: istrcpy(dest, src)
                    357:        char *dest, *src;
                    358: {
                    359:        register char *cp, *cp2;
                    360: 
                    361:        cp2 = dest;
                    362:        cp = src;
                    363:        do {
                    364:                *cp2++ = little(*cp);
                    365:        } while (*cp++ != 0);
                    366: }
                    367: 
                    368: /*
                    369:  * The following code deals with input stacking to do source
                    370:  * commands.  All but the current file pointer are saved on
                    371:  * the stack.
                    372:  */
                    373: 
                    374: static int     ssp = -1;               /* Top of file stack */
                    375: struct sstack {
                    376:        FILE    *s_file;                /* File we were in. */
                    377:        int     s_cond;                 /* Saved state of conditionals */
                    378:        int     s_loading;              /* Loading .mailrc, etc. */
                    379: } sstack[NOFILE];
                    380: 
                    381: /*
                    382:  * Pushdown current input file and switch to a new one.
                    383:  * Set the global flag "sourcing" so that others will realize
                    384:  * that they are no longer reading from a tty (in all probability).
                    385:  */
                    386: 
                    387: source(name)
                    388:        char name[];
                    389: {
                    390:        register FILE *fi;
                    391:        register char *cp;
                    392: 
                    393:        if ((cp = expand(name)) == NOSTR)
                    394:                return(1);
                    395:        if ((fi = fopen(cp, "r")) == NULL) {
                    396:                perror(cp);
                    397:                return(1);
                    398:        }
                    399:        if (ssp >= NOFILE - 2) {
                    400:                printf("Too much \"sourcing\" going on.\n");
                    401:                fclose(fi);
                    402:                return(1);
                    403:        }
                    404:        sstack[++ssp].s_file = input;
                    405:        sstack[ssp].s_cond = cond;
                    406:        sstack[ssp].s_loading = loading;
                    407:        loading = 0;
                    408:        cond = CANY;
                    409:        input = fi;
                    410:        sourcing++;
                    411:        return(0);
                    412: }
                    413: 
                    414: /*
                    415:  * Source a file, but do nothing if the file cannot be opened.
                    416:  */
                    417: 
                    418: source1(name)
                    419:        char name[];
                    420: {
                    421:        register int f;
                    422: 
                    423:        if ((f = open(name, 0)) < 0)
                    424:                return(0);
                    425:        close(f);
                    426:        source(name);
                    427: }
                    428: 
                    429: /*
                    430:  * Pop the current input back to the previous level.
                    431:  * Update the "sourcing" flag as appropriate.
                    432:  */
                    433: 
                    434: unstack()
                    435: {
                    436:        if (ssp < 0) {
                    437:                printf("\"Source\" stack over-pop.\n");
                    438:                sourcing = 0;
                    439:                return(1);
                    440:        }
                    441:        fclose(input);
                    442:        if (cond != CANY)
                    443:                printf("Unmatched \"if\"\n");
                    444:        cond = sstack[ssp].s_cond;
                    445:        loading = sstack[ssp].s_loading;
                    446:        input = sstack[ssp--].s_file;
                    447:        if (ssp < 0)
                    448:                sourcing = loading;
                    449:        return(0);
                    450: }
                    451: 
                    452: /*
                    453:  * Touch the indicated file.
                    454:  * This is nifty for the shell.
                    455:  * If we have the utime() system call, this is better served
                    456:  * by using that, since it will work for empty files.
                    457:  * On non-utime systems, we must sleep a second, then read.
                    458:  */
                    459: 
                    460: alter(name)
                    461:        char name[];
                    462: {
                    463: #ifdef UTIME
                    464:        struct stat statb;
                    465:        long time();
                    466:        time_t time_p[2];
                    467: #else
                    468:        register int pid, f;
                    469:        char w;
                    470: #endif UTIME
                    471: 
                    472: #ifdef UTIME
                    473:        if (stat(name, &statb) < 0)
                    474:                return;
                    475:        time_p[0] = time((long *) 0) + 1;
                    476:        time_p[1] = statb.st_mtime;
                    477:        utime(name, time_p);
                    478: #else
                    479:        sleep(1);
                    480:        if ((f = open(name, 0)) < 0)
                    481:                return;
                    482:        read(f, &w, 1);
                    483:        exit(0);
                    484: #endif
                    485: }
                    486: 
                    487: /*
                    488:  * Examine the passed line buffer and
                    489:  * return true if it is all blanks and tabs.
                    490:  */
                    491: 
                    492: blankline(linebuf)
                    493:        char linebuf[];
                    494: {
                    495:        register char *cp;
                    496: 
                    497:        for (cp = linebuf; *cp; cp++)
                    498:                if (*cp != ' ' && *cp != '\t')
                    499:                        return(0);
                    500:        return(1);
                    501: }
                    502: 
                    503: /*
                    504:  * Get sender's name from this message.  If the message has
                    505:  * a bunch of arpanet stuff in it, we may have to skin the name
                    506:  * before returning it.
                    507:  */
                    508: char *
                    509: nameof(mp, reptype)
                    510:        register struct message *mp;
                    511: {
                    512:        register char *cp, *cp2;
                    513: 
                    514:        cp = skin(name1(mp, reptype));
                    515:        if (reptype != 0 || charcount(cp, '!') < 2)
                    516:                return(cp);
                    517:        cp2 = rindex(cp, '!');
                    518:        cp2--;
                    519:        while (cp2 > cp && *cp2 != '!')
                    520:                cp2--;
                    521:        if (*cp2 == '!')
                    522:                return(cp2 + 1);
                    523:        return(cp);
                    524: }
                    525: 
                    526: /*
                    527:  * Skin an arpa net address according to the RFC 822 interpretation
                    528:  * of "host-phrase."
                    529:  */
                    530: char *
                    531: skin(name)
                    532:        char *name;
                    533: {
                    534:        register int c;
                    535:        register char *cp, *cp2;
                    536:        char *bufend;
                    537:        int gotlt, lastsp;
                    538:        char nbuf[BUFSIZ];
                    539:        int nesting;
                    540: 
                    541:        if (name == NOSTR)
                    542:                return(NOSTR);
                    543:        if (index(name, '(') == NOSTR && index(name, '<') == NOSTR
                    544:        && index(name, ' ') == NOSTR)
                    545:                return(name);
                    546:        gotlt = 0;
                    547:        lastsp = 0;
                    548:        bufend = nbuf;
                    549:        for (cp = name, cp2 = bufend; c = *cp++; ) {
                    550:                switch (c) {
                    551:                case '(':
                    552:                        /*
                    553:                         * Start of a "comment".
                    554:                         * Ignore it.
                    555:                         */
                    556:                        nesting = 1;
                    557:                        while ((c = *cp) != 0) {
                    558:                                cp++;
                    559:                                switch (c) {
                    560:                                case '\\':
                    561:                                        if (*cp == 0)
                    562:                                                goto outcm;
                    563:                                        cp++;
                    564:                                        break;
                    565:                                case '(':
                    566:                                        nesting++;
                    567:                                        break;
                    568: 
                    569:                                case ')':
                    570:                                        --nesting;
                    571:                                        break;
                    572:                                }
                    573: 
                    574:                                if (nesting <= 0)
                    575:                                        break;
                    576:                        }
                    577:                outcm:
                    578:                        lastsp = 0;
                    579:                        break;
                    580: 
                    581:                case '"':
                    582:                        /*
                    583:                         * Start of a "quoted-string".
                    584:                         * Copy it in its entirety.
                    585:                         */
                    586:                        while ((c = *cp) != 0) {
                    587:                                cp++;
                    588:                                switch (c) {
                    589:                                case '\\':
                    590:                                        if ((c = *cp) == 0)
                    591:                                                goto outqs;
                    592:                                        cp++;
                    593:                                        break;
                    594:                                case '"':
                    595:                                        goto outqs;
                    596:                                }
                    597:                                *cp2++ = c;
                    598:                        }
                    599:                outqs:
                    600:                        lastsp = 0;
                    601:                        break;
                    602: 
                    603:                case ' ':
                    604:                        if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ')
                    605:                                cp += 3, *cp2++ = '@';
                    606:                        else
                    607:                        if (cp[0] == '@' && cp[1] == ' ')
                    608:                                cp += 2, *cp2++ = '@';
                    609:                        else
                    610:                                lastsp = 1;
                    611:                        break;
                    612: 
                    613:                case '<':
                    614:                        cp2 = bufend;
                    615:                        gotlt++;
                    616:                        lastsp = 0;
                    617:                        break;
                    618: 
                    619:                case '>':
                    620:                        if (gotlt) {
                    621:                                gotlt = 0;
                    622:                                while (*cp != ',' && *cp != 0)
                    623:                                        cp++;
                    624:                                if (*cp == 0 )
                    625:                                        goto done;
                    626:                                *cp2++ = ',';
                    627:                                *cp2++ = ' ';
                    628:                                bufend = cp2;
                    629:                                break;
                    630:                        }
                    631: 
                    632:                        /* Fall into . . . */
                    633: 
                    634:                default:
                    635:                        if (lastsp) {
                    636:                                lastsp = 0;
                    637:                                *cp2++ = ' ';
                    638:                        }
                    639:                        *cp2++ = c;
                    640:                        break;
                    641:                }
                    642:        }
                    643: done:
                    644:        *cp2 = 0;
                    645: 
                    646:        return(savestr(nbuf));
                    647: }
                    648: 
                    649: /*
                    650:  * Fetch the sender's name from the passed message.
                    651:  * Reptype can be
                    652:  *     0 -- get sender's name for display purposes
                    653:  *     1 -- get sender's name for reply
                    654:  *     2 -- get sender's name for Reply
                    655:  */
                    656: 
                    657: char *
                    658: name1(mp, reptype)
                    659:        register struct message *mp;
                    660: {
                    661:        char namebuf[LINESIZE];
                    662:        char linebuf[LINESIZE];
                    663:        register char *cp, *cp2;
                    664:        register FILE *ibuf;
                    665:        int first = 1;
                    666: 
                    667:        if ((cp = hfield("from", mp)) != NOSTR)
                    668:                return(cp);
                    669:        if (reptype == 0 && (cp = hfield("sender", mp)) != NOSTR)
                    670:                return(cp);
                    671:        ibuf = setinput(mp);
                    672:        copy("", namebuf);
                    673:        if (readline(ibuf, linebuf) <= 0)
                    674:                return(savestr(namebuf));
                    675: newname:
                    676:        for (cp = linebuf; *cp != ' '; cp++)
                    677:                ;
                    678:        while (any(*cp, " \t"))
                    679:                cp++;
                    680:        for (cp2 = &namebuf[strlen(namebuf)]; *cp && !any(*cp, " \t") &&
                    681:            cp2-namebuf < LINESIZE-1; *cp2++ = *cp++)
                    682:                ;
                    683:        *cp2 = '\0';
                    684:        if (readline(ibuf, linebuf) <= 0)
                    685:                return(savestr(namebuf));
                    686:        if ((cp = index(linebuf, 'F')) == NULL)
                    687:                return(savestr(namebuf));
                    688:        if (strncmp(cp, "From", 4) != 0)
                    689:                return(savestr(namebuf));
                    690:        while ((cp = index(cp, 'r')) != NULL) {
                    691:                if (strncmp(cp, "remote", 6) == 0) {
                    692:                        if ((cp = index(cp, 'f')) == NULL)
                    693:                                break;
                    694:                        if (strncmp(cp, "from", 4) != 0)
                    695:                                break;
                    696:                        if ((cp = index(cp, ' ')) == NULL)
                    697:                                break;
                    698:                        cp++;
                    699:                        if (first) {
                    700:                                copy(cp, namebuf);
                    701:                                first = 0;
                    702:                        } else
                    703:                                strcpy(rindex(namebuf, '!')+1, cp);
                    704:                        strcat(namebuf, "!");
                    705:                        goto newname;
                    706:                }
                    707:                cp++;
                    708:        }
                    709:        return(savestr(namebuf));
                    710: }
                    711: 
                    712: /*
                    713:  * Count the occurances of c in str
                    714:  */
                    715: charcount(str, c)
                    716:        char *str;
                    717: {
                    718:        register char *cp;
                    719:        register int i;
                    720: 
                    721:        for (i = 0, cp = str; *cp; cp++)
                    722:                if (*cp == c)
                    723:                        i++;
                    724:        return(i);
                    725: }
                    726: 
                    727: /*
                    728:  * Find the rightmost pointer to an instance of the
                    729:  * character in the string and return it.
                    730:  */
                    731: char *
                    732: rindex(str, c)
                    733:        char str[];
                    734:        register int c;
                    735: {
                    736:        register char *cp, *cp2;
                    737: 
                    738:        for (cp = str, cp2 = NOSTR; *cp; cp++)
                    739:                if (c == *cp)
                    740:                        cp2 = cp;
                    741:        return(cp2);
                    742: }
                    743: 
                    744: /*
                    745:  * See if the string is a number.
                    746:  */
                    747: 
                    748: numeric(str)
                    749:        char str[];
                    750: {
                    751:        register char *cp = str;
                    752: 
                    753:        while (*cp)
                    754:                if (!isdigit(*cp++))
                    755:                        return(0);
                    756:        return(1);
                    757: }
                    758: 
                    759: /*
                    760:  * Are any of the characters in the two strings the same?
                    761:  */
                    762: 
                    763: anyof(s1, s2)
                    764:        register char *s1, *s2;
                    765: {
                    766:        register int c;
                    767: 
                    768:        while (c = *s1++)
                    769:                if (any(c, s2))
                    770:                        return(1);
                    771:        return(0);
                    772: }
                    773: 
                    774: /*
                    775:  * Determine the leftmost index of the character
                    776:  * in the string.
                    777:  */
                    778: 
                    779: char *
                    780: index(str, ch)
                    781:        char *str;
                    782: {
                    783:        register char *cp;
                    784:        register int c;
                    785: 
                    786:        for (c = ch, cp = str; *cp; cp++)
                    787:                if (*cp == c)
                    788:                        return(cp);
                    789:        return(NOSTR);
                    790: }
                    791: 
                    792: /*
                    793:  * See if the given header field is supposed to be ignored.
                    794:  */
                    795: isign(field)
                    796:        char *field;
                    797: {
                    798:        char realfld[BUFSIZ];
                    799: 
                    800:        /*
                    801:         * Lower-case the string, so that "Status" and "status"
                    802:         * will hash to the same place.
                    803:         */
                    804:        istrcpy(realfld, field);
                    805: 
                    806:        if (nretained > 0)
                    807:                return (!member(realfld, retain));
                    808:        else
                    809:                return (member(realfld, ignore));
                    810: }
                    811: 
                    812: member(realfield, table)
                    813:        register char *realfield;
                    814:        register struct ignore **table;
                    815: {
                    816:        register struct ignore *igp;
                    817: 
                    818:        for (igp = table[hash(realfield)]; igp != 0; igp = igp->i_link)
                    819:                if (equal(igp->i_field, realfield))
                    820:                        return (1);
                    821: 
                    822:        return (0);
                    823: }

unix.superglobalmegacorp.com

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