Annotation of 43BSD/ucb/Mail/aux.c, revision 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.