Annotation of 42BSD/usr.lib/sendmail/src/util.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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