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

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

unix.superglobalmegacorp.com

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