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

unix.superglobalmegacorp.com

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