# 2.11BSD#431 - /usr/src/usr.sbin/sendmail/src/util.c

##### Functions

    atobool           X
    atooct            X
    bitintersect      X
    bitzerop          X
    buildfname        X
    capitalize        X
    cleanstrcpy       X
    copyplist         X
    curtime           X
    denlstring        X
    dfopen            X
    fgetfolded        X
    fixcrlf           X
    lower             X
    makelower         X
    printav           X
    putline           X
    qstrlen           X
    readtimeout       X
    safefile          X
    sameword          X
    sfgets            X
    stripquotes       X
    waitfor           X
    xalloc            X
    xputs             X
    xunlink           X

##### Variables

    bool              X

##### Macros

    ETIMEDOUT         X
    SMTPLINELIM       X

       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: #if !defined(lint) && !defined(NOSCCS)
      12: static char SccsId[] = "@(#)util.c	5.8.3 (2.11BSD GTE) 1997/10/3";
      13: #endif
      14:
      15: # include <stdio.h>
      16: # include <sys/types.h>
      17: # include <sys/stat.h>
      18: # include <sysexits.h>
      19: # include <ctype.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:
     146:     p = (char *)malloc((unsigned) sz);
     147:     if (p == NULL)
     148:     {
     149:         syserr("Out of memory!!");
     150:         abort();
     151:         /* exit(EX_UNAVAILABLE); */
     152:     }
     153:     return (p);
     154: }
     155: /*
     156: **  COPYPLIST -- copy list of pointers.
     157: **
     158: **	This routine is the equivalent of newstr for lists of
     159: **	pointers.
     160: **
     161: **	Parameters:
     162: **		list -- list of pointers to copy.
     163: **			Must be NULL terminated.
     164: **		copycont -- if TRUE, copy the contents of the vector
     165: **			(which must be a string) also.
     166: **
     167: **	Returns:
     168: **		a copy of 'list'.
     169: **
     170: **	Side Effects:
     171: **		none.
     172: */
     173:
     174: char **
     175: copyplist(list, copycont)
     176:     char **list;
     177:     bool copycont;
     178: {
     179:     register char **vp;
     180:     register char **newvp;
     181:
     182:     for (vp = list; *vp != NULL; vp++)
     183:         continue;
     184:
     185:     vp++;
     186:
     187:     newvp = (char **) xalloc((int) (vp - list) * sizeof *vp);
     188:     bcopy((char *) list, (char *) newvp, (int) (vp - list) * sizeof *vp);
     189:
     190:     if (copycont)
     191:     {
     192:         for (vp = newvp; *vp != NULL; vp++)
     193:             *vp = newstr(*vp);
     194:     }
     195:
     196:     return (newvp);
     197: }
     198: /*
     199: **  PRINTAV -- print argument vector.
     200: **
     201: **	Parameters:
     202: **		av -- argument vector.
     203: **
     204: **	Returns:
     205: **		none.
     206: **
     207: **	Side Effects:
     208: **		prints av.
     209: */
     210:
     211: printav(av)
     212:     register char **av;
     213: {
     214:     while (*av != NULL)
     215:     {
     216:         if (tTd(0, 44))
     217:             printf("\n\t%08x=", *av);
     218:         else
     219:             (void) putchar(' ');
     220:         xputs(*av++);
     221:     }
     222:     (void) putchar('\n');
     223: }
     224: /*
     225: **  LOWER -- turn letter into lower case.
     226: **
     227: **	Parameters:
     228: **		c -- character to turn into lower case.
     229: **
     230: **	Returns:
     231: **		c, in lower case.
     232: **
     233: **	Side Effects:
     234: **		none.
     235: */
     236:
     237: char
     238: lower(c)
     239:     register char c;
     240: {
     241:     if (isascii(c) && isupper(c))
     242:         c = c - 'A' + 'a';
     243:     return (c);
     244: }
     245: /*
     246: **  XPUTS -- put string doing control escapes.
     247: **
     248: **	Parameters:
     249: **		s -- string to put.
     250: **
     251: **	Returns:
     252: **		none.
     253: **
     254: **	Side Effects:
     255: **		output to stdout
     256: */
     257:
     258: xputs(s)
     259:     register char *s;
     260: {
     261:     register char c;
     262:
     263:     if (s == NULL)
     264:     {
     265:         printf("<null>");
     266:         return;
     267:     }
     268:     (void) putchar('"');
     269:     while ((c = *s++) != '\0')
     270:     {
     271:         if (!isascii(c))
     272:         {
     273:             (void) putchar('\\');
     274:             c &= 0177;
     275:         }
     276:         if (c < 040 || c >= 0177)
     277:         {
     278:             (void) putchar('^');
     279:             c ^= 0100;
     280:         }
     281:         (void) putchar(c);
     282:     }
     283:     (void) putchar('"');
     284:     (void) fflush(stdout);
     285: }
     286: /*
     287: **  MAKELOWER -- Translate a line into lower case
     288: **
     289: **	Parameters:
     290: **		p -- the string to translate.  If NULL, return is
     291: **			immediate.
     292: **
     293: **	Returns:
     294: **		none.
     295: **
     296: **	Side Effects:
     297: **		String pointed to by p is translated to lower case.
     298: **
     299: **	Called By:
     300: **		parse
     301: */
     302:
     303: makelower(p)
     304:     register char *p;
     305: {
     306:     register char c;
     307:
     308:     if (p == NULL)
     309:         return;
     310:     for (; (c = *p) != '\0'; p++)
     311:         if (isascii(c) && isupper(c))
     312:             *p = c - 'A' + 'a';
     313: }
     314: /*
     315: **  SAMEWORD -- return TRUE if the words are the same
     316: **
     317: **	Ignores case.
     318: **
     319: **	Parameters:
     320: **		a, b -- the words to compare.
     321: **
     322: **	Returns:
     323: **		TRUE if a & b match exactly (modulo case)
     324: **		FALSE otherwise.
     325: **
     326: **	Side Effects:
     327: **		none.
     328: */
     329:
     330: bool
     331: sameword(a, b)
     332:     register char *a, *b;
     333: {
     334:     char ca, cb;
     335:
     336:     do
     337:     {
     338:         ca = *a++;
     339:         cb = *b++;
     340:         if (isascii(ca) && isupper(ca))
     341:             ca = ca - 'A' + 'a';
     342:         if (isascii(cb) && isupper(cb))
     343:             cb = cb - 'A' + 'a';
     344:     } while (ca != '\0' && ca == cb);
     345:     return (ca == cb);
     346: }
     347: /*
     348: **  BUILDFNAME -- build full name from gecos style entry.
     349: **
     350: **	This routine interprets the strange entry that would appear
     351: **	in the GECOS field of the password file.
     352: **
     353: **	Parameters:
     354: **		p -- name to build.
     355: **		login -- the login name of this user (for &).
     356: **		buf -- place to put the result.
     357: **
     358: **	Returns:
     359: **		none.
     360: **
     361: **	Side Effects:
     362: **		none.
     363: */
     364:
     365: buildfname(p, login, buf)
     366:     register char *p;
     367:     char *login;
     368:     char *buf;
     369: {
     370:     register char *bp = buf;
     371:
     372:     if (*p == '*')
     373:         p++;
     374:     while (*p != '\0' && *p != ',' && *p != ';' && *p != '%')
     375:     {
     376:         if (*p == '&')
     377:         {
     378:             (void) strcpy(bp, login);
     379:             *bp = toupper(*bp);
     380:             while (*bp != '\0')
     381:                 bp++;
     382:             p++;
     383:         }
     384:         else
     385:             *bp++ = *p++;
     386:     }
     387:     *bp = '\0';
     388: }
     389: /*
     390: **  SAFEFILE -- return true if a file exists and is safe for a user.
     391: **
     392: **	Parameters:
     393: **		fn -- filename to check.
     394: **		uid -- uid to compare against.
     395: **		mode -- mode bits that must match.
     396: **
     397: **	Returns:
     398: **		TRUE if fn exists, is owned by uid, and matches mode.
     399: **		FALSE otherwise.
     400: **
     401: **	Side Effects:
     402: **		none.
     403: */
     404:
     405: bool
     406: safefile(fn, uid, mode)
     407:     char *fn;
     408:     int uid;
     409:     int mode;
     410: {
     411:     struct stat stbuf;
     412:
     413:     if (stat(fn, &stbuf) >= 0 && stbuf.st_uid == uid &&
     414:         (stbuf.st_mode & mode) == mode)
     415:         return (TRUE);
     416:     errno = 0;
     417:     return (FALSE);
     418: }
     419: /*
     420: **  FIXCRLF -- fix <CR><LF> in line.
     421: **
     422: **	Looks for the <CR><LF> combination and turns it into the
     423: **	UNIX canonical <NL> character.  It only takes one line,
     424: **	i.e., it is assumed that the first <NL> found is the end
     425: **	of the line.
     426: **
     427: **	Parameters:
     428: **		line -- the line to fix.
     429: **		stripnl -- if true, strip the newline also.
     430: **
     431: **	Returns:
     432: **		none.
     433: **
     434: **	Side Effects:
     435: **		line is changed in place.
     436: */
     437:
     438: fixcrlf(line, stripnl)
     439:     char *line;
     440:     bool stripnl;
     441: {
     442:     register char *p;
     443:
     444:     p = index(line, '\n');
     445:     if (p == NULL)
     446:         return;
     447:     if (p[-1] == '\r')
     448:         p--;
     449:     if (!stripnl)
     450:         *p++ = '\n';
     451:     *p = '\0';
     452: }
     453: /*
     454: **  DFOPEN -- determined file open
     455: **
     456: **	This routine has the semantics of fopen, except that it will
     457: **	keep trying a few times to make this happen.  The idea is that
     458: **	on very loaded systems, we may run out of resources (inodes,
     459: **	whatever), so this tries to get around it.
     460: */
     461:
     462: FILE *
     463: dfopen(filename, mode)
     464:     char *filename;
     465:     char *mode;
     466: {
     467:     register int tries;
     468:     register FILE *fp;
     469:
     470:     for (tries = 0; tries < 10; tries++)
     471:     {
     472:         sleep((unsigned) (10 * tries));
     473:         errno = 0;
     474:         fp = fopen(filename, mode);
     475:         if (fp != NULL)
     476:             break;
     477:         if (errno != ENFILE && errno != EINTR)
     478:             break;
     479:     }
     480:     errno = 0;
     481:     return (fp);
     482: }
     483: /*
     484: **  PUTLINE -- put a line like fputs obeying SMTP conventions
     485: **
     486: **	This routine always guarantees outputing a newline (or CRLF,
     487: **	as appropriate) at the end of the string.
     488: **
     489: **	Parameters:
     490: **		l -- line to put.
     491: **		fp -- file to put it onto.
     492: **		m -- the mailer used to control output.
     493: **
     494: **	Returns:
     495: **		none
     496: **
     497: **	Side Effects:
     498: **		output of l to fp.
     499: */
     500:
     501: # define SMTPLINELIM    990 /* maximum line length */
     502:
     503: putline(l, fp, m)
     504:     register char *l;
     505:     FILE *fp;
     506:     MAILER *m;
     507: {
     508:     register char *p;
     509:     char svchar;
     510:
     511:     /* strip out 0200 bits -- these can look like TELNET protocol */
     512:     if (bitnset(M_LIMITS, m->m_flags))
     513:     {
     514:         p = l;
     515:         while ((*p++ &= ~0200) != 0)
     516:             continue;
     517:     }
     518:
     519:     do
     520:     {
     521:         /* find the end of the line */
     522:         p = index(l, '\n');
     523:         if (p == NULL)
     524:             p = &l[strlen(l)];
     525:
     526:         /* check for line overflow */
     527:         while ((p - l) > SMTPLINELIM && bitnset(M_LIMITS, m->m_flags))
     528:         {
     529:             register char *q = &l[SMTPLINELIM - 1];
     530:
     531:             svchar = *q;
     532:             *q = '\0';
     533:             if (l[0] == '.' && bitnset(M_XDOT, m->m_flags))
     534:                 (void) putc('.', fp);
     535:             fputs(l, fp);
     536:             (void) putc('!', fp);
     537:             fputs(m->m_eol, fp);
     538:             *q = svchar;
     539:             l = q;
     540:         }
     541:
     542:         /* output last part */
     543:         svchar = *p;
     544:         *p = '\0';
     545:         if (l[0] == '.' && bitnset(M_XDOT, m->m_flags))
     546:             (void) putc('.', fp);
     547:         fputs(l, fp);
     548:         fputs(m->m_eol, fp);
     549:         *p = svchar;
     550:         l = p;
     551:         if (*l == '\n')
     552:             l++;
     553:     } while (l[0] != '\0');
     554: }
     555: /*
     556: **  XUNLINK -- unlink a file, doing logging as appropriate.
     557: **
     558: **	Parameters:
     559: **		f -- name of file to unlink.
     560: **
     561: **	Returns:
     562: **		none.
     563: **
     564: **	Side Effects:
     565: **		f is unlinked.
     566: */
     567:
     568: xunlink(f)
     569:     char *f;
     570: {
     571:     register int i;
     572:
     573: # ifdef LOG
     574:     if (LogLevel > 20)
     575:         syslog(LOG_DEBUG, "%s: unlink %s\n", CurEnv->e_id, f);
     576: # endif LOG
     577:
     578:     i = unlink(f);
     579: # ifdef LOG
     580:     if (i < 0 && LogLevel > 21)
     581:         syslog(LOG_DEBUG, "%s: unlink-fail %d", f, errno);
     582: # endif LOG
     583: }
     584: /*
     585: **  SFGETS -- "safe" fgets -- times out and ignores random interrupts.
     586: **
     587: **	Parameters:
     588: **		buf -- place to put the input line.
     589: **		siz -- size of buf.
     590: **		fp -- file to read from.
     591: **
     592: **	Returns:
     593: **		NULL on error (including timeout).  This will also leave
     594: **			buf containing a null string.
     595: **		buf otherwise.
     596: **
     597: **	Side Effects:
     598: **		none.
     599: */
     600:
     601: static jmp_buf  CtxReadTimeout;
     602:
     603: #ifndef ETIMEDOUT
     604: #define ETIMEDOUT   EINTR
     605: #endif
     606:
     607: char *
     608: sfgets(buf, siz, fp)
     609:     char *buf;
     610:     int siz;
     611:     FILE *fp;
     612: {
     613:     register EVENT *ev = NULL;
     614:     register char *p;
     615:     int readtimeout();
     616:
     617:     /* set the timeout */
     618:     if (ReadTimeout != 0)
     619:     {
     620:         if (setjmp(CtxReadTimeout) != 0)
     621:         {
     622:             errno = ETIMEDOUT;
     623:             syserr("net timeout");
     624:             buf[0] = '\0';
     625:             return (NULL);
     626:         }
     627:         ev = setevent((time_t) ReadTimeout, readtimeout, 0);
     628:     }
     629:
     630:     /* try to read */
     631:     p = NULL;
     632:     while (p == NULL && !feof(fp) && !ferror(fp))
     633:     {
     634:         errno = 0;
     635:         p = fgets(buf, siz, fp);
     636:         if (errno == EINTR)
     637:             clearerr(fp);
     638:     }
     639:
     640:     /* clear the event if it has not sprung */
     641:     clrevent(ev);
     642:
     643:     /* clean up the books and exit */
     644:     LineNumber++;
     645:     if (p == NULL)
     646:     {
     647:         buf[0] = '\0';
     648:         return (NULL);
     649:     }
     650:     for (p = buf; *p != '\0'; p++)
     651:         *p &= ~0200;
     652:     return (buf);
     653: }
     654:
     655: readtimeout()
     656: {
     657:     longjmp(CtxReadTimeout, 1);
     658: }
     659: /*
     660: **  FGETFOLDED -- like fgets, but know about folded lines.
     661: **
     662: **	Parameters:
     663: **		buf -- place to put result.
     664: **		n -- bytes available.
     665: **		f -- file to read from.
     666: **
     667: **	Returns:
     668: **		buf on success, NULL on error or EOF.
     669: **
     670: **	Side Effects:
     671: **		buf gets lines from f, with continuation lines (lines
     672: **		with leading white space) appended.  CRLF's are mapped
     673: **		into single newlines.  Any trailing NL is stripped.
     674: */
     675:
     676: char *
     677: fgetfolded(buf, n, f)
     678:     char *buf;
     679:     int n;
     680:     register FILE *f;
     681: {
     682:     register char *p = buf;
     683:     register int i;
     684:
     685:     n--;
     686:     while ((i = getc(f)) != EOF)
     687:     {
     688:         if (i == '\r')
     689:         {
     690:             i = getc(f);
     691:             if (i != '\n')
     692:             {
     693:                 if (i != EOF)
     694:                     (void) ungetc(i, f);
     695:                 i = '\r';
     696:             }
     697:         }
     698:         if (--n > 0)
     699:             *p++ = i;
     700:         if (i == '\n')
     701:         {
     702:             LineNumber++;
     703:             i = getc(f);
     704:             if (i != EOF)
     705:                 (void) ungetc(i, f);
     706:             if (i != ' ' && i != '\t')
     707:             {
     708:                 *--p = '\0';
     709:                 return (buf);
     710:             }
     711:         }
     712:     }
     713:     return (NULL);
     714: }
     715: /*
     716: **  CURTIME -- return current time.
     717: **
     718: **	Parameters:
     719: **		none.
     720: **
     721: **	Returns:
     722: **		the current time.
     723: **
     724: **	Side Effects:
     725: **		none.
     726: */
     727:
     728: time_t
     729: curtime()
     730: {
     731:     auto time_t t;
     732:
     733:     (void) time(&t);
     734:     return (t);
     735: }
     736: /*
     737: **  ATOBOOL -- convert a string representation to boolean.
     738: **
     739: **	Defaults to "TRUE"
     740: **
     741: **	Parameters:
     742: **		s -- string to convert.  Takes "tTyY" as true,
     743: **			others as false.
     744: **
     745: **	Returns:
     746: **		A boolean representation of the string.
     747: **
     748: **	Side Effects:
     749: **		none.
     750: */
     751:
     752: bool
     753: atobool(s)
     754:     register char *s;
     755: {
     756:     if (*s == '\0' || index("tTyY", *s) != NULL)
     757:         return (TRUE);
     758:     return (FALSE);
     759: }
     760: /*
     761: **  ATOOCT -- convert a string representation to octal.
     762: **
     763: **	Parameters:
     764: **		s -- string to convert.
     765: **
     766: **	Returns:
     767: **		An integer representing the string interpreted as an
     768: **		octal number.
     769: **
     770: **	Side Effects:
     771: **		none.
     772: */
     773:
     774: atooct(s)
     775:     register char *s;
     776: {
     777:     register int i = 0;
     778:
     779:     while (*s >= '0' && *s <= '7')
     780:         i = (i << 3) | (*s++ - '0');
     781:     return (i);
     782: }
     783: /*
     784: **  WAITFOR -- wait for a particular process id.
     785: **
     786: **	Parameters:
     787: **		pid -- process id to wait for.
     788: **
     789: **	Returns:
     790: **		status of pid.
     791: **		-1 if pid never shows up.
     792: **
     793: **	Side Effects:
     794: **		none.
     795: */
     796:
     797: waitfor(pid)
     798:     int pid;
     799: {
     800:     auto int st;
     801:     register int i;
     802:
     803:     do
     804:     {
     805:         errno = 0;
     806:         i = wait(&st);
     807:     } while ((i >= 0 || errno == EINTR) && i != pid);
     808:     if (i < 0)
     809:         st = -1;
     810:     return (st);
     811: }
     812: /*
     813: **  BITINTERSECT -- tell if two bitmaps intersect
     814: **
     815: **	Parameters:
     816: **		a, b -- the bitmaps in question
     817: **
     818: **	Returns:
     819: **		TRUE if they have a non-null intersection
     820: **		FALSE otherwise
     821: **
     822: **	Side Effects:
     823: **		none.
     824: */
     825:
     826: bool
     827: bitintersect(a, b)
     828:     BITMAP a;
     829:     BITMAP b;
     830: {
     831:     register int i;
     832:
     833:     for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
     834:         if ((a[i] & b[i]) != 0)
     835:             return (TRUE);
     836:     return (FALSE);
     837: }
     838: /*
     839: **  BITZEROP -- tell if a bitmap is all zero
     840: **
     841: **	Parameters:
     842: **		map -- the bit map to check
     843: **
     844: **	Returns:
     845: **		TRUE if map is all zero.
     846: **		FALSE if there are any bits set in map.
     847: **
     848: **	Side Effects:
     849: **		none.
     850: */
     851:
     852: bool
     853: bitzerop(map)
     854:     BITMAP map;
     855: {
     856:     register int i;
     857:
     858:     for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
     859:         if (map[i] != 0)
     860:             return (FALSE);
     861:     return (TRUE);
     862: }
     863: /*
     864: **  CLEANSTRCPY -- copy string keeping out bogus characters
     865: **
     866: **	Parameters:
     867: **		t -- "to" string.
     868: **		f -- "from" string.
     869: **		l -- length of space available in "to" string.
     870: **
     871: **	Returns:
     872: **		none.
     873: */
     874:
     875: void
     876: cleanstrcpy(t, f, l)
     877:     register char *t;
     878:     register char *f;
     879:     int l;
     880: {
     881: #ifdef LOG
     882:     /* check for newlines and log if necessary */
     883:     (void) denlstring(f);
     884: #endif
     885:
     886:     l--;
     887:     while (l > 0 && *f != '\0')
     888:     {
     889:         if (isascii(*f) &&
     890:             (isalnum(*f) || strchr("!#$%&'*+-./^_`{|}~", *f) != NULL))
     891:         {
     892:             l--;
     893:             *t++ = *f;
     894:         }
     895:         f++;
     896:     }
     897:     *t = '\0';
     898: }
     899: /*
     900: **  DENLSTRING -- convert newlines in a string to spaces
     901: **
     902: **	Parameters:
     903: **		s -- the input string
     904: **
     905: **	Returns:
     906: **		A pointer to a version of the string with newlines
     907: **		mapped to spaces.  This should be copied.
     908: */
     909:
     910: char *
     911: denlstring(s)
     912:     char *s;
     913: {
     914:     register char *p;
     915:     int l;
     916:     static char *bp = NULL;
     917:     static int bl = 0;
     918:     extern  char    *macvalue();
     919:
     920:     if (strchr(s, '\n') == NULL)
     921:         return s;
     922:
     923:     l = strlen(s) + 1;
     924:     if (bl < l)
     925:     {
     926:         /* allocate more space */
     927:         if (bp != NULL)
     928:             free(bp);
     929:         bp = xalloc(l);
     930:         bl = l;
     931:     }
     932:     strcpy(bp, s);
     933:     for (p = bp; (p = strchr(p, '\n')) != NULL; )
     934:         *p++ = ' ';
     935:
     936: #ifdef LOG
     937:     /*
     938: 	 * V5 doesn't have IDENT capabilities so there is no macro '_'.
     939: 	 * Instead we use the less "trusted" (but better than nothing) 'f'
     940: 	 * macro value.
     941: 	*/
     942:     p = macvalue('f', CurEnv);
     943:     syslog(LOG_ALERT, "POSSIBLE ATTACK from %s: newline in string \"%s\"",
     944:         p == NULL ? "[UNKNOWN]" : p, bp);
     945: #endif
     946:
     947:     return bp;
     948: }

#### Defined functions

atobool defined in line 752; used 11 times

- in /usr/src/usr.sbin/sendmail/src/readcf.c line 655, 728, 760, 784, 799, 815-819(2), 829, 862, 877, 901

atooct defined in line 774; used 1 times

- in /usr/src/usr.sbin/sendmail/src/readcf.c line 780

bitintersect defined in line 826; used 2 times

- in /usr/src/usr.sbin/sendmail/src/headers.c line 628-631(2)

bitzerop defined in line 852; used 2 times

- in /usr/src/usr.sbin/sendmail/src/queue.c line 179, 193

buildfname defined in line 365; used 3 times

- in /usr/src/usr.sbin/sendmail/src/envelope.c line 513
- in /usr/src/usr.sbin/sendmail/src/recipient.c line 331, 393

capitalize defined in line 101; used 5 times

- in /usr/src/usr.sbin/sendmail/src/headers.c line 291-294(2), 622, 662, 718

cleanstrcpy defined in line 875; used 1 times

- in /usr/src/usr.sbin/sendmail/src/readcf.c line 809

copyplist defined in line 174; used 5 times

- in /usr/src/usr.sbin/sendmail/src/envelope.c line 557-562(2)
- in /usr/src/usr.sbin/sendmail/src/readcf.c line 65, 134, 146

curtime defined in line 728; used 9 times

- in /usr/src/usr.sbin/sendmail/src/clock.c line 148, 193
- in /usr/src/usr.sbin/sendmail/src/deliver.c line 451, 1039
- in /usr/src/usr.sbin/sendmail/src/envelope.c line 52, 242, 308
- in /usr/src/usr.sbin/sendmail/src/main.c line 891
- in /usr/src/usr.sbin/sendmail/src/sendmail.h line 584

denlstring defined in line 910; used 9 times

- in line 883
- in /usr/src/usr.sbin/sendmail/src/main.c line 345, 446
- in /usr/src/usr.sbin/sendmail/src/queue.c line 125-128(2), 136, 159
- in /usr/src/usr.sbin/sendmail/src/recipient.c line 84
- in /usr/src/usr.sbin/sendmail/src/sendmail.h line 586

dfopen defined in line 462; used 4 times

- in /usr/src/usr.sbin/sendmail/src/collect.c line 50
- in /usr/src/usr.sbin/sendmail/src/deliver.c line 1232
- in /usr/src/usr.sbin/sendmail/src/savemail.c line 301
- in /usr/src/usr.sbin/sendmail/src/sendmail.h line 580

fgetfolded defined in line 676; used 4 times

- in /usr/src/usr.sbin/sendmail/src/queue.c line 674, 692
- in /usr/src/usr.sbin/sendmail/src/readcf.c line 68, 80

fixcrlf defined in line 438; used 9 times

- in /usr/src/usr.sbin/sendmail/src/collect.c line 70, 76, 104, 118, 150
- in /usr/src/usr.sbin/sendmail/src/queue.c line 836
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 165, 585
- in /usr/src/usr.sbin/sendmail/src/usersmtp.c line 424

lower defined in line 237; used 5 times

- in /usr/src/usr.sbin/sendmail/src/headers.c line 838-840(3)
- in /usr/src/usr.sbin/sendmail/src/stab.c line 51, 66

makelower defined in line 303; used 6 times

- in /usr/src/usr.sbin/sendmail/src/daemon.c line 520
- in /usr/src/usr.sbin/sendmail/src/headers.c line 86
- in /usr/src/usr.sbin/sendmail/src/parseaddr.c line 148, 183
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 571
- in /usr/src/usr.sbin/sendmail/src/stab.c line 113

printav defined in line 211; used 8 times

- in /usr/src/usr.sbin/sendmail/src/deliver.c line 680
- in /usr/src/usr.sbin/sendmail/src/parseaddr.c line 515, 531, 656, 818, 826
- in /usr/src/usr.sbin/sendmail/src/readcf.c line 614-616(2)

putline defined in line 503; used 23 times

- in /usr/src/usr.sbin/sendmail/src/deliver.c line 577, 1092, 1129, 1139, 1238-1240(2)
- in /usr/src/usr.sbin/sendmail/src/extract.c line 152
- in /usr/src/usr.sbin/sendmail/src/headers.c line 668-673(2), 794, 818
- in /usr/src/usr.sbin/sendmail/src/savemail.c line 310-312(2), 479, 494-504(5), 511-513(3)
- in /usr/src/usr.sbin/sendmail/src/usersmtp.c line 297

qstrlen defined in line 74; used 2 times

- in /usr/src/usr.sbin/sendmail/src/headers.c line 788, 799

readtimeout defined in line 655; used 2 times

- in line 615, 627

safefile defined in line 405; used 6 times

- in /usr/src/usr.sbin/sendmail/src/alias.c line 577, 594
- in /usr/src/usr.sbin/sendmail/src/envelope.c line 420
- in /usr/src/usr.sbin/sendmail/src/main.c line 110
- in /usr/src/usr.sbin/sendmail/src/recipient.c line 167, 300

sameword defined in line 330; used 19 times

- in /usr/src/usr.sbin/sendmail/src/headers.c line 414-418(2)
- in /usr/src/usr.sbin/sendmail/src/parseaddr.c line 510, 598, 853, 866, 887
- in /usr/src/usr.sbin/sendmail/src/recipient.c line 391-394(2), 543-547(2)
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 104, 186, 196, 203, 512, 536
- in /usr/src/usr.sbin/sendmail/src/stab.c line 48, 74

sfgets defined in line 607; used 9 times

- in /usr/src/usr.sbin/sendmail/src/collect.c line 69, 75, 116, 131, 140, 170
- in /usr/src/usr.sbin/sendmail/src/sendmail.h line 582
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 153
- in /usr/src/usr.sbin/sendmail/src/usersmtp.c line 397

stripquotes defined in line 43; used 5 times

- in /usr/src/usr.sbin/sendmail/src/deliver.c line 249-255(4)
- in /usr/src/usr.sbin/sendmail/src/recipient.c line 205

waitfor defined in line 797; used 5 times

- in /usr/src/usr.sbin/sendmail/src/deliver.c line 622, 1254
- in /usr/src/usr.sbin/sendmail/src/queue.c line 292, 648
- in /usr/src/usr.sbin/sendmail/src/srvrsmtp.c line 656

xalloc defined in line 140; used 17 times

- in line 187, 929
- in /usr/src/usr.sbin/sendmail/src/clock.c line 65
- in /usr/src/usr.sbin/sendmail/src/collect.c line 322
- in /usr/src/usr.sbin/sendmail/src/envelope.c line 202
- in /usr/src/usr.sbin/sendmail/src/headers.c line 128, 194
- in /usr/src/usr.sbin/sendmail/src/parseaddr.c line 856
- in /usr/src/usr.sbin/sendmail/src/queue.c line 483
- in /usr/src/usr.sbin/sendmail/src/readcf.c line 120-124(2), 392, 580
- in /usr/src/usr.sbin/sendmail/src/recipient.c line 83
- in /usr/src/usr.sbin/sendmail/src/sendmail.h line 568, 578
- in /usr/src/usr.sbin/sendmail/src/stab.c line 110

xputs defined in line 258; used 10 times

- in line 220
- in /usr/src/usr.sbin/sendmail/src/envelope.c line 85
- in /usr/src/usr.sbin/sendmail/src/macro.c line 52, 119, 207
- in /usr/src/usr.sbin/sendmail/src/main.c line 532
- in /usr/src/usr.sbin/sendmail/src/parseaddr.c line 280, 395, 546-548(2)

xunlink defined in line 568; used 4 times

- in /usr/src/usr.sbin/sendmail/src/envelope.c line 137-138(2)
- in /usr/src/usr.sbin/sendmail/src/queue.c line 1026-1030(2)

#### Defined variables

CtxReadTimeout defined in line 601; used 2 times

- in line 620, 657

SccsId defined in line 12; never used
bool defined in line 752; used 7 times

- in line 45, 177, 330, 405, 440, 826, 852

#### Defined macros

ETIMEDOUT defined in line 604; used 2 times

- in line 603, 622

SMTPLINELIM defined in line 501; used 2 times

- in line 527-529(2)

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2702 |