Annotation of 43BSDReno/usr.sbin/sendmail/src/util.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Eric P. Allman
        !             3:  * Copyright (c) 1988 Regents of the University of California.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms are permitted provided
        !             7:  * that: (1) source distributions retain this entire copyright notice and
        !             8:  * comment, and (2) distributions including binaries display the following
        !             9:  * acknowledgement:  ``This product includes software developed by the
        !            10:  * University of California, Berkeley and its contributors'' in the
        !            11:  * documentation or other materials provided with the distribution and in
        !            12:  * all advertising materials mentioning features or use of this software.
        !            13:  * Neither the name of the University nor the names of its contributors may
        !            14:  * be used to endorse or promote products derived from this software without
        !            15:  * specific prior written permission.
        !            16:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            19:  */
        !            20: 
        !            21: #ifndef lint
        !            22: static char sccsid[] = "@(#)util.c     5.18 (Berkeley) 6/1/90";
        !            23: #endif /* not lint */
        !            24: 
        !            25: # include <stdio.h>
        !            26: # include <sys/types.h>
        !            27: # include <sys/stat.h>
        !            28: # include <sysexits.h>
        !            29: # include <errno.h>
        !            30: # include "sendmail.h"
        !            31: 
        !            32: /*
        !            33: **  STRIPQUOTES -- Strip quotes & quote bits from a string.
        !            34: **
        !            35: **     Runs through a string and strips off unquoted quote
        !            36: **     characters and quote bits.  This is done in place.
        !            37: **
        !            38: **     Parameters:
        !            39: **             s -- the string to strip.
        !            40: **             qf -- if set, remove actual `` " '' characters
        !            41: **                     as well as the quote bits.
        !            42: **
        !            43: **     Returns:
        !            44: **             none.
        !            45: **
        !            46: **     Side Effects:
        !            47: **             none.
        !            48: **
        !            49: **     Called By:
        !            50: **             deliver
        !            51: */
        !            52: 
        !            53: stripquotes(s, qf)
        !            54:        char *s;
        !            55:        bool qf;
        !            56: {
        !            57:        register char *p;
        !            58:        register char *q;
        !            59:        register char c;
        !            60: 
        !            61:        if (s == NULL)
        !            62:                return;
        !            63: 
        !            64:        for (p = q = s; (c = *p++) != '\0'; )
        !            65:        {
        !            66:                if (c != '"' || !qf)
        !            67:                        *q++ = c & 0177;
        !            68:        }
        !            69:        *q = '\0';
        !            70: }
        !            71: /*
        !            72: **  QSTRLEN -- give me the string length assuming 0200 bits add a char
        !            73: **
        !            74: **     Parameters:
        !            75: **             s -- the string to measure.
        !            76: **
        !            77: **     Reurns:
        !            78: **             The length of s, including space for backslash escapes.
        !            79: **
        !            80: **     Side Effects:
        !            81: **             none.
        !            82: */
        !            83: 
        !            84: qstrlen(s)
        !            85:        register char *s;
        !            86: {
        !            87:        register int l = 0;
        !            88:        register char c;
        !            89: 
        !            90:        while ((c = *s++) != '\0')
        !            91:        {
        !            92:                if (bitset(0200, c))
        !            93:                        l++;
        !            94:                l++;
        !            95:        }
        !            96:        return (l);
        !            97: }
        !            98: /*
        !            99: **  CAPITALIZE -- return a copy of a string, properly capitalized.
        !           100: **
        !           101: **     Parameters:
        !           102: **             s -- the string to capitalize.
        !           103: **
        !           104: **     Returns:
        !           105: **             a pointer to a properly capitalized string.
        !           106: **
        !           107: **     Side Effects:
        !           108: **             none.
        !           109: */
        !           110: 
        !           111: char *
        !           112: capitalize(s)
        !           113:        register char *s;
        !           114: {
        !           115:        static char buf[50];
        !           116:        register char *p;
        !           117: 
        !           118:        p = buf;
        !           119: 
        !           120:        for (;;)
        !           121:        {
        !           122:                while (!isalpha(*s) && *s != '\0')
        !           123:                        *p++ = *s++;
        !           124:                if (*s == '\0')
        !           125:                        break;
        !           126:                *p++ = toupper(*s);
        !           127:                s++;
        !           128:                while (isalpha(*s))
        !           129:                        *p++ = *s++;
        !           130:        }
        !           131: 
        !           132:        *p = '\0';
        !           133:        return (buf);
        !           134: }
        !           135: /*
        !           136: **  XALLOC -- Allocate memory and bitch wildly on failure.
        !           137: **
        !           138: **     THIS IS A CLUDGE.  This should be made to give a proper
        !           139: **     error -- but after all, what can we do?
        !           140: **
        !           141: **     Parameters:
        !           142: **             sz -- size of area to allocate.
        !           143: **
        !           144: **     Returns:
        !           145: **             pointer to data region.
        !           146: **
        !           147: **     Side Effects:
        !           148: **             Memory is allocated.
        !           149: */
        !           150: 
        !           151: char *
        !           152: xalloc(sz)
        !           153:        register int sz;
        !           154: {
        !           155:        register char *p;
        !           156:        extern char *malloc();
        !           157: 
        !           158:        p = malloc((unsigned) sz);
        !           159:        if (p == NULL)
        !           160:        {
        !           161:                syserr("Out of memory!!");
        !           162:                abort();
        !           163:                /* exit(EX_UNAVAILABLE); */
        !           164:        }
        !           165:        return (p);
        !           166: }
        !           167: /*
        !           168: **  COPYPLIST -- copy list of pointers.
        !           169: **
        !           170: **     This routine is the equivalent of newstr for lists of
        !           171: **     pointers.
        !           172: **
        !           173: **     Parameters:
        !           174: **             list -- list of pointers to copy.
        !           175: **                     Must be NULL terminated.
        !           176: **             copycont -- if TRUE, copy the contents of the vector
        !           177: **                     (which must be a string) also.
        !           178: **
        !           179: **     Returns:
        !           180: **             a copy of 'list'.
        !           181: **
        !           182: **     Side Effects:
        !           183: **             none.
        !           184: */
        !           185: 
        !           186: char **
        !           187: copyplist(list, copycont)
        !           188:        char **list;
        !           189:        bool copycont;
        !           190: {
        !           191:        register char **vp;
        !           192:        register char **newvp;
        !           193: 
        !           194:        for (vp = list; *vp != NULL; vp++)
        !           195:                continue;
        !           196: 
        !           197:        vp++;
        !           198: 
        !           199:        newvp = (char **) xalloc((int) (vp - list) * sizeof *vp);
        !           200:        bcopy((char *) list, (char *) newvp, (int) (vp - list) * sizeof *vp);
        !           201: 
        !           202:        if (copycont)
        !           203:        {
        !           204:                for (vp = newvp; *vp != NULL; vp++)
        !           205:                        *vp = newstr(*vp);
        !           206:        }
        !           207: 
        !           208:        return (newvp);
        !           209: }
        !           210: /*
        !           211: **  PRINTAV -- print argument vector.
        !           212: **
        !           213: **     Parameters:
        !           214: **             av -- argument vector.
        !           215: **
        !           216: **     Returns:
        !           217: **             none.
        !           218: **
        !           219: **     Side Effects:
        !           220: **             prints av.
        !           221: */
        !           222: 
        !           223: printav(av)
        !           224:        register char **av;
        !           225: {
        !           226:        while (*av != NULL)
        !           227:        {
        !           228:                if (tTd(0, 44))
        !           229:                        printf("\n\t%08x=", *av);
        !           230:                else
        !           231:                        (void) putchar(' ');
        !           232:                xputs(*av++);
        !           233:        }
        !           234:        (void) putchar('\n');
        !           235: }
        !           236: /*
        !           237: **  LOWER -- turn letter into lower case.
        !           238: **
        !           239: **     Parameters:
        !           240: **             c -- character to turn into lower case.
        !           241: **
        !           242: **     Returns:
        !           243: **             c, in lower case.
        !           244: **
        !           245: **     Side Effects:
        !           246: **             none.
        !           247: */
        !           248: 
        !           249: char
        !           250: lower(c)
        !           251:        register char c;
        !           252: {
        !           253:        return(isascii(c) && isupper(c) ? tolower(c) : c);
        !           254: }
        !           255: /*
        !           256: **  XPUTS -- put string doing control escapes.
        !           257: **
        !           258: **     Parameters:
        !           259: **             s -- string to put.
        !           260: **
        !           261: **     Returns:
        !           262: **             none.
        !           263: **
        !           264: **     Side Effects:
        !           265: **             output to stdout
        !           266: */
        !           267: 
        !           268: xputs(s)
        !           269:        register char *s;
        !           270: {
        !           271:        register char c;
        !           272: 
        !           273:        if (s == NULL)
        !           274:        {
        !           275:                printf("<null>");
        !           276:                return;
        !           277:        }
        !           278:        (void) putchar('"');
        !           279:        while ((c = *s++) != '\0')
        !           280:        {
        !           281:                if (!isascii(c))
        !           282:                {
        !           283:                        (void) putchar('\\');
        !           284:                        c &= 0177;
        !           285:                }
        !           286:                if (c < 040 || c >= 0177)
        !           287:                {
        !           288:                        (void) putchar('^');
        !           289:                        c ^= 0100;
        !           290:                }
        !           291:                (void) putchar(c);
        !           292:        }
        !           293:        (void) putchar('"');
        !           294:        (void) fflush(stdout);
        !           295: }
        !           296: /*
        !           297: **  MAKELOWER -- Translate a line into lower case
        !           298: **
        !           299: **     Parameters:
        !           300: **             p -- the string to translate.  If NULL, return is
        !           301: **                     immediate.
        !           302: **
        !           303: **     Returns:
        !           304: **             none.
        !           305: **
        !           306: **     Side Effects:
        !           307: **             String pointed to by p is translated to lower case.
        !           308: **
        !           309: **     Called By:
        !           310: **             parse
        !           311: */
        !           312: 
        !           313: makelower(p)
        !           314:        register char *p;
        !           315: {
        !           316:        register char c;
        !           317: 
        !           318:        if (p == NULL)
        !           319:                return;
        !           320:        for (; (c = *p) != '\0'; p++)
        !           321:                if (isascii(c) && isupper(c))
        !           322:                        *p = tolower(c);
        !           323: }
        !           324: /*
        !           325: **  BUILDFNAME -- build full name from gecos style entry.
        !           326: **
        !           327: **     This routine interprets the strange entry that would appear
        !           328: **     in the GECOS field of the password file.
        !           329: **
        !           330: **     Parameters:
        !           331: **             p -- name to build.
        !           332: **             login -- the login name of this user (for &).
        !           333: **             buf -- place to put the result.
        !           334: **
        !           335: **     Returns:
        !           336: **             none.
        !           337: **
        !           338: **     Side Effects:
        !           339: **             none.
        !           340: */
        !           341: 
        !           342: buildfname(p, login, buf)
        !           343:        register char *p;
        !           344:        char *login;
        !           345:        char *buf;
        !           346: {
        !           347:        register char *bp = buf;
        !           348: 
        !           349:        if (*p == '*')
        !           350:                p++;
        !           351:        while (*p != '\0' && *p != ',' && *p != ';' && *p != '%')
        !           352:        {
        !           353:                if (*p == '&')
        !           354:                {
        !           355:                        (void) strcpy(bp, login);
        !           356:                        *bp = toupper(*bp);
        !           357:                        while (*bp != '\0')
        !           358:                                bp++;
        !           359:                        p++;
        !           360:                }
        !           361:                else
        !           362:                        *bp++ = *p++;
        !           363:        }
        !           364:        *bp = '\0';
        !           365: }
        !           366: /*
        !           367: **  SAFEFILE -- return true if a file exists and is safe for a user.
        !           368: **
        !           369: **     Parameters:
        !           370: **             fn -- filename to check.
        !           371: **             uid -- uid to compare against.
        !           372: **             mode -- mode bits that must match.
        !           373: **
        !           374: **     Returns:
        !           375: **             TRUE if fn exists, is owned by uid, and matches mode.
        !           376: **             FALSE otherwise.
        !           377: **
        !           378: **     Side Effects:
        !           379: **             none.
        !           380: */
        !           381: 
        !           382: bool
        !           383: safefile(fn, uid, mode)
        !           384:        char *fn;
        !           385:        int uid;
        !           386:        int mode;
        !           387: {
        !           388:        struct stat stbuf;
        !           389: 
        !           390:        if (stat(fn, &stbuf) >= 0 && stbuf.st_uid == uid &&
        !           391:            (stbuf.st_mode & mode) == mode)
        !           392:                return (TRUE);
        !           393:        errno = 0;
        !           394:        return (FALSE);
        !           395: }
        !           396: /*
        !           397: **  FIXCRLF -- fix <CR><LF> in line.
        !           398: **
        !           399: **     Looks for the <CR><LF> combination and turns it into the
        !           400: **     UNIX canonical <NL> character.  It only takes one line,
        !           401: **     i.e., it is assumed that the first <NL> found is the end
        !           402: **     of the line.
        !           403: **
        !           404: **     Parameters:
        !           405: **             line -- the line to fix.
        !           406: **             stripnl -- if true, strip the newline also.
        !           407: **
        !           408: **     Returns:
        !           409: **             none.
        !           410: **
        !           411: **     Side Effects:
        !           412: **             line is changed in place.
        !           413: */
        !           414: 
        !           415: fixcrlf(line, stripnl)
        !           416:        char *line;
        !           417:        bool stripnl;
        !           418: {
        !           419:        register char *p;
        !           420: 
        !           421:        p = index(line, '\n');
        !           422:        if (p == NULL)
        !           423:                return;
        !           424:        if (p > line && p[-1] == '\r')
        !           425:                p--;
        !           426:        if (!stripnl)
        !           427:                *p++ = '\n';
        !           428:        *p = '\0';
        !           429: }
        !           430: /*
        !           431: **  DFOPEN -- determined file open
        !           432: **
        !           433: **     This routine has the semantics of fopen, except that it will
        !           434: **     keep trying a few times to make this happen.  The idea is that
        !           435: **     on very loaded systems, we may run out of resources (inodes,
        !           436: **     whatever), so this tries to get around it.
        !           437: */
        !           438: 
        !           439: FILE *
        !           440: dfopen(filename, mode)
        !           441:        char *filename;
        !           442:        char *mode;
        !           443: {
        !           444:        register int tries;
        !           445:        register FILE *fp;
        !           446: 
        !           447:        for (tries = 0; tries < 10; tries++)
        !           448:        {
        !           449:                sleep((unsigned) (10 * tries));
        !           450:                errno = 0;
        !           451:                fp = fopen(filename, mode);
        !           452:                if (fp != NULL)
        !           453:                        break;
        !           454:                if (errno != ENFILE && errno != EINTR)
        !           455:                        break;
        !           456:        }
        !           457:        errno = 0;
        !           458:        return (fp);
        !           459: }
        !           460: /*
        !           461: **  PUTLINE -- put a line like fputs obeying SMTP conventions
        !           462: **
        !           463: **     This routine always guarantees outputing a newline (or CRLF,
        !           464: **     as appropriate) at the end of the string.
        !           465: **
        !           466: **     Parameters:
        !           467: **             l -- line to put.
        !           468: **             fp -- file to put it onto.
        !           469: **             m -- the mailer used to control output.
        !           470: **
        !           471: **     Returns:
        !           472: **             none
        !           473: **
        !           474: **     Side Effects:
        !           475: **             output of l to fp.
        !           476: */
        !           477: 
        !           478: # define SMTPLINELIM   990     /* maximum line length */
        !           479: 
        !           480: putline(l, fp, m)
        !           481:        register char *l;
        !           482:        FILE *fp;
        !           483:        MAILER *m;
        !           484: {
        !           485:        register char *p;
        !           486:        char svchar;
        !           487: 
        !           488:        /* strip out 0200 bits -- these can look like TELNET protocol */
        !           489:        if (bitnset(M_LIMITS, m->m_flags))
        !           490:        {
        !           491:                p = l;
        !           492:                while ((*p++ &= ~0200) != 0)
        !           493:                        continue;
        !           494:        }
        !           495: 
        !           496:        do
        !           497:        {
        !           498:                /* find the end of the line */
        !           499:                p = index(l, '\n');
        !           500:                if (p == NULL)
        !           501:                        p = &l[strlen(l)];
        !           502: 
        !           503:                /* check for line overflow */
        !           504:                while ((p - l) > SMTPLINELIM && bitnset(M_LIMITS, m->m_flags))
        !           505:                {
        !           506:                        register char *q = &l[SMTPLINELIM - 1];
        !           507: 
        !           508:                        svchar = *q;
        !           509:                        *q = '\0';
        !           510:                        if (l[0] == '.' && bitnset(M_XDOT, m->m_flags))
        !           511:                                (void) putc('.', fp);
        !           512:                        fputs(l, fp);
        !           513:                        (void) putc('!', fp);
        !           514:                        fputs(m->m_eol, fp);
        !           515:                        *q = svchar;
        !           516:                        l = q;
        !           517:                }
        !           518: 
        !           519:                /* output last part */
        !           520:                svchar = *p;
        !           521:                *p = '\0';
        !           522:                if (l[0] == '.' && bitnset(M_XDOT, m->m_flags))
        !           523:                        (void) putc('.', fp);
        !           524:                fputs(l, fp);
        !           525:                fputs(m->m_eol, fp);
        !           526:                *p = svchar;
        !           527:                l = p;
        !           528:                if (*l == '\n')
        !           529:                        l++;
        !           530:        } while (l[0] != '\0');
        !           531: }
        !           532: /*
        !           533: **  XUNLINK -- unlink a file, doing logging as appropriate.
        !           534: **
        !           535: **     Parameters:
        !           536: **             f -- name of file to unlink.
        !           537: **
        !           538: **     Returns:
        !           539: **             none.
        !           540: **
        !           541: **     Side Effects:
        !           542: **             f is unlinked.
        !           543: */
        !           544: 
        !           545: xunlink(f)
        !           546:        char *f;
        !           547: {
        !           548:        register int i;
        !           549: 
        !           550: # ifdef LOG
        !           551:        if (LogLevel > 20)
        !           552:                syslog(LOG_DEBUG, "%s: unlink %s\n", CurEnv->e_id, f);
        !           553: # endif LOG
        !           554: 
        !           555:        i = unlink(f);
        !           556: # ifdef LOG
        !           557:        if (i < 0 && LogLevel > 21)
        !           558:                syslog(LOG_DEBUG, "%s: unlink-fail %d", f, errno);
        !           559: # endif LOG
        !           560: }
        !           561: /*
        !           562: **  SFGETS -- "safe" fgets -- times out and ignores random interrupts.
        !           563: **
        !           564: **     Parameters:
        !           565: **             buf -- place to put the input line.
        !           566: **             siz -- size of buf.
        !           567: **             fp -- file to read from.
        !           568: **
        !           569: **     Returns:
        !           570: **             NULL on error (including timeout).  This will also leave
        !           571: **                     buf containing a null string.
        !           572: **             buf otherwise.
        !           573: **
        !           574: **     Side Effects:
        !           575: **             none.
        !           576: */
        !           577: 
        !           578: static jmp_buf CtxReadTimeout;
        !           579: 
        !           580: char *
        !           581: sfgets(buf, siz, fp)
        !           582:        char *buf;
        !           583:        int siz;
        !           584:        FILE *fp;
        !           585: {
        !           586:        register EVENT *ev = NULL;
        !           587:        register char *p;
        !           588:        extern readtimeout();
        !           589: 
        !           590:        /* set the timeout */
        !           591:        if (ReadTimeout != 0)
        !           592:        {
        !           593:                if (setjmp(CtxReadTimeout) != 0)
        !           594:                {
        !           595: # ifdef LOG
        !           596:                        syslog(LOG_NOTICE,
        !           597:                            "timeout waiting for input from %s\n",
        !           598:                            RealHostName? RealHostName: "local");
        !           599: # endif
        !           600:                        errno = 0;
        !           601:                        usrerr("451 timeout waiting for input");
        !           602:                        buf[0] = '\0';
        !           603:                        return (NULL);
        !           604:                }
        !           605:                ev = setevent((time_t) ReadTimeout, readtimeout, 0);
        !           606:        }
        !           607: 
        !           608:        /* try to read */
        !           609:        p = NULL;
        !           610:        while (p == NULL && !feof(fp) && !ferror(fp))
        !           611:        {
        !           612:                errno = 0;
        !           613:                p = fgets(buf, siz, fp);
        !           614:                if (errno == EINTR)
        !           615:                        clearerr(fp);
        !           616:        }
        !           617: 
        !           618:        /* clear the event if it has not sprung */
        !           619:        clrevent(ev);
        !           620: 
        !           621:        /* clean up the books and exit */
        !           622:        LineNumber++;
        !           623:        if (p == NULL)
        !           624:        {
        !           625:                buf[0] = '\0';
        !           626:                return (NULL);
        !           627:        }
        !           628:        for (p = buf; *p != '\0'; p++)
        !           629:                *p &= ~0200;
        !           630:        return (buf);
        !           631: }
        !           632: 
        !           633: static
        !           634: readtimeout()
        !           635: {
        !           636:        longjmp(CtxReadTimeout, 1);
        !           637: }
        !           638: /*
        !           639: **  FGETFOLDED -- like fgets, but know about folded lines.
        !           640: **
        !           641: **     Parameters:
        !           642: **             buf -- place to put result.
        !           643: **             n -- bytes available.
        !           644: **             f -- file to read from.
        !           645: **
        !           646: **     Returns:
        !           647: **             buf on success, NULL on error or EOF.
        !           648: **
        !           649: **     Side Effects:
        !           650: **             buf gets lines from f, with continuation lines (lines
        !           651: **             with leading white space) appended.  CRLF's are mapped
        !           652: **             into single newlines.  Any trailing NL is stripped.
        !           653: */
        !           654: 
        !           655: char *
        !           656: fgetfolded(buf, n, f)
        !           657:        char *buf;
        !           658:        register int n;
        !           659:        FILE *f;
        !           660: {
        !           661:        register char *p = buf;
        !           662:        register int i;
        !           663: 
        !           664:        n--;
        !           665:        while ((i = getc(f)) != EOF)
        !           666:        {
        !           667:                if (i == '\r')
        !           668:                {
        !           669:                        i = getc(f);
        !           670:                        if (i != '\n')
        !           671:                        {
        !           672:                                if (i != EOF)
        !           673:                                        (void) ungetc(i, f);
        !           674:                                i = '\r';
        !           675:                        }
        !           676:                }
        !           677:                if (--n > 0)
        !           678:                        *p++ = i;
        !           679:                if (i == '\n')
        !           680:                {
        !           681:                        LineNumber++;
        !           682:                        i = getc(f);
        !           683:                        if (i != EOF)
        !           684:                                (void) ungetc(i, f);
        !           685:                        if (i != ' ' && i != '\t')
        !           686:                        {
        !           687:                                *--p = '\0';
        !           688:                                return (buf);
        !           689:                        }
        !           690:                }
        !           691:        }
        !           692:        return (NULL);
        !           693: }
        !           694: /*
        !           695: **  CURTIME -- return current time.
        !           696: **
        !           697: **     Parameters:
        !           698: **             none.
        !           699: **
        !           700: **     Returns:
        !           701: **             the current time.
        !           702: **
        !           703: **     Side Effects:
        !           704: **             none.
        !           705: */
        !           706: 
        !           707: time_t
        !           708: curtime()
        !           709: {
        !           710:        auto time_t t;
        !           711: 
        !           712:        (void) time(&t);
        !           713:        return (t);
        !           714: }
        !           715: /*
        !           716: **  ATOBOOL -- convert a string representation to boolean.
        !           717: **
        !           718: **     Defaults to "TRUE"
        !           719: **
        !           720: **     Parameters:
        !           721: **             s -- string to convert.  Takes "tTyY" as true,
        !           722: **                     others as false.
        !           723: **
        !           724: **     Returns:
        !           725: **             A boolean representation of the string.
        !           726: **
        !           727: **     Side Effects:
        !           728: **             none.
        !           729: */
        !           730: 
        !           731: bool
        !           732: atobool(s)
        !           733:        register char *s;
        !           734: {
        !           735:        if (*s == '\0' || index("tTyY", *s) != NULL)
        !           736:                return (TRUE);
        !           737:        return (FALSE);
        !           738: }
        !           739: /*
        !           740: **  ATOOCT -- convert a string representation to octal.
        !           741: **
        !           742: **     Parameters:
        !           743: **             s -- string to convert.
        !           744: **
        !           745: **     Returns:
        !           746: **             An integer representing the string interpreted as an
        !           747: **             octal number.
        !           748: **
        !           749: **     Side Effects:
        !           750: **             none.
        !           751: */
        !           752: 
        !           753: atooct(s)
        !           754:        register char *s;
        !           755: {
        !           756:        register int i = 0;
        !           757: 
        !           758:        while (*s >= '0' && *s <= '7')
        !           759:                i = (i << 3) | (*s++ - '0');
        !           760:        return (i);
        !           761: }
        !           762: /*
        !           763: **  WAITFOR -- wait for a particular process id.
        !           764: **
        !           765: **     Parameters:
        !           766: **             pid -- process id to wait for.
        !           767: **
        !           768: **     Returns:
        !           769: **             status of pid.
        !           770: **             -1 if pid never shows up.
        !           771: **
        !           772: **     Side Effects:
        !           773: **             none.
        !           774: */
        !           775: 
        !           776: waitfor(pid)
        !           777:        int pid;
        !           778: {
        !           779:        auto int st;
        !           780:        int i;
        !           781: 
        !           782:        do
        !           783:        {
        !           784:                errno = 0;
        !           785:                i = wait(&st);
        !           786:        } while ((i >= 0 || errno == EINTR) && i != pid);
        !           787:        if (i < 0)
        !           788:                st = -1;
        !           789:        return (st);
        !           790: }
        !           791: /*
        !           792: **  BITINTERSECT -- tell if two bitmaps intersect
        !           793: **
        !           794: **     Parameters:
        !           795: **             a, b -- the bitmaps in question
        !           796: **
        !           797: **     Returns:
        !           798: **             TRUE if they have a non-null intersection
        !           799: **             FALSE otherwise
        !           800: **
        !           801: **     Side Effects:
        !           802: **             none.
        !           803: */
        !           804: 
        !           805: bool
        !           806: bitintersect(a, b)
        !           807:        BITMAP a;
        !           808:        BITMAP b;
        !           809: {
        !           810:        int i;
        !           811: 
        !           812:        for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
        !           813:                if ((a[i] & b[i]) != 0)
        !           814:                        return (TRUE);
        !           815:        return (FALSE);
        !           816: }
        !           817: /*
        !           818: **  BITZEROP -- tell if a bitmap is all zero
        !           819: **
        !           820: **     Parameters:
        !           821: **             map -- the bit map to check
        !           822: **
        !           823: **     Returns:
        !           824: **             TRUE if map is all zero.
        !           825: **             FALSE if there are any bits set in map.
        !           826: **
        !           827: **     Side Effects:
        !           828: **             none.
        !           829: */
        !           830: 
        !           831: bool
        !           832: bitzerop(map)
        !           833:        BITMAP map;
        !           834: {
        !           835:        int i;
        !           836: 
        !           837:        for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
        !           838:                if (map[i] != 0)
        !           839:                        return (FALSE);
        !           840:        return (TRUE);
        !           841: }

unix.superglobalmegacorp.com

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