Annotation of 43BSDTahoe/usr.lib/sendmail/src/util.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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