home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / src / RCS / util.c,v < prev    next >
Encoding:
Text File  |  1991-08-08  |  23.3 KB  |  1,467 lines

  1. head    5.18;
  2. branch    5.18.0;
  3. access;
  4. symbols
  5.     RELEASE:5.18.0.13
  6.     BETA:5.18.0.12
  7.     UICSO:5.18.0
  8.     VANILLA:5.18;
  9. locks; strict;
  10. comment    @ * @;
  11.  
  12.  
  13. 5.18
  14. date    90.06.20.08.37.21;    author paul;    state Exp;
  15. branches
  16.     5.18.0.1;
  17. next    ;
  18.  
  19. 5.18.0.1
  20. date    90.06.20.09.44.16;    author paul;    state Exp;
  21. branches;
  22. next    5.18.0.2;
  23.  
  24. 5.18.0.2
  25. date    90.10.13.19.23.30;    author paul;    state Exp;
  26. branches;
  27. next    5.18.0.3;
  28.  
  29. 5.18.0.3
  30. date    90.11.24.17.11.49;    author paul;    state Exp;
  31. branches;
  32. next    5.18.0.4;
  33.  
  34. 5.18.0.4
  35. date    90.11.29.21.17.22;    author paul;    state Exp;
  36. branches;
  37. next    5.18.0.5;
  38.  
  39. 5.18.0.5
  40. date    91.01.19.19.26.02;    author paul;    state Exp;
  41. branches;
  42. next    5.18.0.6;
  43.  
  44. 5.18.0.6
  45. date    91.03.04.21.48.23;    author paul;    state Exp;
  46. branches;
  47. next    5.18.0.7;
  48.  
  49. 5.18.0.7
  50. date    91.03.06.15.14.22;    author paul;    state Exp;
  51. branches;
  52. next    5.18.0.8;
  53.  
  54. 5.18.0.8
  55. date    91.03.06.17.32.56;    author paul;    state Exp;
  56. branches;
  57. next    5.18.0.9;
  58.  
  59. 5.18.0.9
  60. date    91.04.05.06.33.33;    author paul;    state Exp;
  61. branches;
  62. next    5.18.0.10;
  63.  
  64. 5.18.0.10
  65. date    91.04.05.14.55.15;    author paul;    state Exp;
  66. branches;
  67. next    5.18.0.11;
  68.  
  69. 5.18.0.11
  70. date    91.05.23.22.06.36;    author paul;    state Exp;
  71. branches;
  72. next    5.18.0.12;
  73.  
  74. 5.18.0.12
  75. date    91.05.29.19.24.10;    author paul;    state Exp;
  76. branches;
  77. next    5.18.0.13;
  78.  
  79. 5.18.0.13
  80. date    91.06.24.20.31.52;    author paul;    state Exp;
  81. branches;
  82. next    5.18.0.14;
  83.  
  84. 5.18.0.14
  85. date    91.08.08.22.08.18;    author paul;    state Exp;
  86. branches;
  87. next    ;
  88.  
  89.  
  90. desc
  91. @@
  92.  
  93.  
  94. 5.18
  95. log
  96. @5.64 Berkeley release
  97. @
  98. text
  99. @/*
  100.  * Copyright (c) 1983 Eric P. Allman
  101.  * Copyright (c) 1988 Regents of the University of California.
  102.  * All rights reserved.
  103.  *
  104.  * Redistribution and use in source and binary forms are permitted provided
  105.  * that: (1) source distributions retain this entire copyright notice and
  106.  * comment, and (2) distributions including binaries display the following
  107.  * acknowledgement:  ``This product includes software developed by the
  108.  * University of California, Berkeley and its contributors'' in the
  109.  * documentation or other materials provided with the distribution and in
  110.  * all advertising materials mentioning features or use of this software.
  111.  * Neither the name of the University nor the names of its contributors may
  112.  * be used to endorse or promote products derived from this software without
  113.  * specific prior written permission.
  114.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  115.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  116.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  117.  */
  118.  
  119. #ifndef lint
  120. static char sccsid[] = "@@(#)util.c    5.18 (Berkeley) 6/1/90";
  121. #endif /* not lint */
  122.  
  123. # include <stdio.h>
  124. # include <sys/types.h>
  125. # include <sys/stat.h>
  126. # include <sysexits.h>
  127. # include <errno.h>
  128. # include "sendmail.h"
  129.  
  130. /*
  131. **  STRIPQUOTES -- Strip quotes & quote bits from a string.
  132. **
  133. **    Runs through a string and strips off unquoted quote
  134. **    characters and quote bits.  This is done in place.
  135. **
  136. **    Parameters:
  137. **        s -- the string to strip.
  138. **        qf -- if set, remove actual `` " '' characters
  139. **            as well as the quote bits.
  140. **
  141. **    Returns:
  142. **        none.
  143. **
  144. **    Side Effects:
  145. **        none.
  146. **
  147. **    Called By:
  148. **        deliver
  149. */
  150.  
  151. stripquotes(s, qf)
  152.     char *s;
  153.     bool qf;
  154. {
  155.     register char *p;
  156.     register char *q;
  157.     register char c;
  158.  
  159.     if (s == NULL)
  160.         return;
  161.  
  162.     for (p = q = s; (c = *p++) != '\0'; )
  163.     {
  164.         if (c != '"' || !qf)
  165.             *q++ = c & 0177;
  166.     }
  167.     *q = '\0';
  168. }
  169. /*
  170. **  QSTRLEN -- give me the string length assuming 0200 bits add a char
  171. **
  172. **    Parameters:
  173. **        s -- the string to measure.
  174. **
  175. **    Reurns:
  176. **        The length of s, including space for backslash escapes.
  177. **
  178. **    Side Effects:
  179. **        none.
  180. */
  181.  
  182. qstrlen(s)
  183.     register char *s;
  184. {
  185.     register int l = 0;
  186.     register char c;
  187.  
  188.     while ((c = *s++) != '\0')
  189.     {
  190.         if (bitset(0200, c))
  191.             l++;
  192.         l++;
  193.     }
  194.     return (l);
  195. }
  196. /*
  197. **  CAPITALIZE -- return a copy of a string, properly capitalized.
  198. **
  199. **    Parameters:
  200. **        s -- the string to capitalize.
  201. **
  202. **    Returns:
  203. **        a pointer to a properly capitalized string.
  204. **
  205. **    Side Effects:
  206. **        none.
  207. */
  208.  
  209. char *
  210. capitalize(s)
  211.     register char *s;
  212. {
  213.     static char buf[50];
  214.     register char *p;
  215.  
  216.     p = buf;
  217.  
  218.     for (;;)
  219.     {
  220.         while (!isalpha(*s) && *s != '\0')
  221.             *p++ = *s++;
  222.         if (*s == '\0')
  223.             break;
  224.         *p++ = toupper(*s);
  225.         s++;
  226.         while (isalpha(*s))
  227.             *p++ = *s++;
  228.     }
  229.  
  230.     *p = '\0';
  231.     return (buf);
  232. }
  233. /*
  234. **  XALLOC -- Allocate memory and bitch wildly on failure.
  235. **
  236. **    THIS IS A CLUDGE.  This should be made to give a proper
  237. **    error -- but after all, what can we do?
  238. **
  239. **    Parameters:
  240. **        sz -- size of area to allocate.
  241. **
  242. **    Returns:
  243. **        pointer to data region.
  244. **
  245. **    Side Effects:
  246. **        Memory is allocated.
  247. */
  248.  
  249. char *
  250. xalloc(sz)
  251.     register int sz;
  252. {
  253.     register char *p;
  254.     extern char *malloc();
  255.  
  256.     p = malloc((unsigned) sz);
  257.     if (p == NULL)
  258.     {
  259.         syserr("Out of memory!!");
  260.         abort();
  261.         /* exit(EX_UNAVAILABLE); */
  262.     }
  263.     return (p);
  264. }
  265. /*
  266. **  COPYPLIST -- copy list of pointers.
  267. **
  268. **    This routine is the equivalent of newstr for lists of
  269. **    pointers.
  270. **
  271. **    Parameters:
  272. **        list -- list of pointers to copy.
  273. **            Must be NULL terminated.
  274. **        copycont -- if TRUE, copy the contents of the vector
  275. **            (which must be a string) also.
  276. **
  277. **    Returns:
  278. **        a copy of 'list'.
  279. **
  280. **    Side Effects:
  281. **        none.
  282. */
  283.  
  284. char **
  285. copyplist(list, copycont)
  286.     char **list;
  287.     bool copycont;
  288. {
  289.     register char **vp;
  290.     register char **newvp;
  291.  
  292.     for (vp = list; *vp != NULL; vp++)
  293.         continue;
  294.  
  295.     vp++;
  296.  
  297.     newvp = (char **) xalloc((int) (vp - list) * sizeof *vp);
  298.     bcopy((char *) list, (char *) newvp, (int) (vp - list) * sizeof *vp);
  299.  
  300.     if (copycont)
  301.     {
  302.         for (vp = newvp; *vp != NULL; vp++)
  303.             *vp = newstr(*vp);
  304.     }
  305.  
  306.     return (newvp);
  307. }
  308. /*
  309. **  PRINTAV -- print argument vector.
  310. **
  311. **    Parameters:
  312. **        av -- argument vector.
  313. **
  314. **    Returns:
  315. **        none.
  316. **
  317. **    Side Effects:
  318. **        prints av.
  319. */
  320.  
  321. printav(av)
  322.     register char **av;
  323. {
  324.     while (*av != NULL)
  325.     {
  326.         if (tTd(0, 44))
  327.             printf("\n\t%08x=", *av);
  328.         else
  329.             (void) putchar(' ');
  330.         xputs(*av++);
  331.     }
  332.     (void) putchar('\n');
  333. }
  334. /*
  335. **  LOWER -- turn letter into lower case.
  336. **
  337. **    Parameters:
  338. **        c -- character to turn into lower case.
  339. **
  340. **    Returns:
  341. **        c, in lower case.
  342. **
  343. **    Side Effects:
  344. **        none.
  345. */
  346.  
  347. char
  348. lower(c)
  349.     register char c;
  350. {
  351.     return(isascii(c) && isupper(c) ? tolower(c) : c);
  352. }
  353. /*
  354. **  XPUTS -- put string doing control escapes.
  355. **
  356. **    Parameters:
  357. **        s -- string to put.
  358. **
  359. **    Returns:
  360. **        none.
  361. **
  362. **    Side Effects:
  363. **        output to stdout
  364. */
  365.  
  366. xputs(s)
  367.     register char *s;
  368. {
  369.     register char c;
  370.  
  371.     if (s == NULL)
  372.     {
  373.         printf("<null>");
  374.         return;
  375.     }
  376.     (void) putchar('"');
  377.     while ((c = *s++) != '\0')
  378.     {
  379.         if (!isascii(c))
  380.         {
  381.             (void) putchar('\\');
  382.             c &= 0177;
  383.         }
  384.         if (c < 040 || c >= 0177)
  385.         {
  386.             (void) putchar('^');
  387.             c ^= 0100;
  388.         }
  389.         (void) putchar(c);
  390.     }
  391.     (void) putchar('"');
  392.     (void) fflush(stdout);
  393. }
  394. /*
  395. **  MAKELOWER -- Translate a line into lower case
  396. **
  397. **    Parameters:
  398. **        p -- the string to translate.  If NULL, return is
  399. **            immediate.
  400. **
  401. **    Returns:
  402. **        none.
  403. **
  404. **    Side Effects:
  405. **        String pointed to by p is translated to lower case.
  406. **
  407. **    Called By:
  408. **        parse
  409. */
  410.  
  411. makelower(p)
  412.     register char *p;
  413. {
  414.     register char c;
  415.  
  416.     if (p == NULL)
  417.         return;
  418.     for (; (c = *p) != '\0'; p++)
  419.         if (isascii(c) && isupper(c))
  420.             *p = tolower(c);
  421. }
  422. /*
  423. **  BUILDFNAME -- build full name from gecos style entry.
  424. **
  425. **    This routine interprets the strange entry that would appear
  426. **    in the GECOS field of the password file.
  427. **
  428. **    Parameters:
  429. **        p -- name to build.
  430. **        login -- the login name of this user (for &).
  431. **        buf -- place to put the result.
  432. **
  433. **    Returns:
  434. **        none.
  435. **
  436. **    Side Effects:
  437. **        none.
  438. */
  439.  
  440. buildfname(p, login, buf)
  441.     register char *p;
  442.     char *login;
  443.     char *buf;
  444. {
  445.     register char *bp = buf;
  446.  
  447.     if (*p == '*')
  448.         p++;
  449.     while (*p != '\0' && *p != ',' && *p != ';' && *p != '%')
  450.     {
  451.         if (*p == '&')
  452.         {
  453.             (void) strcpy(bp, login);
  454.             *bp = toupper(*bp);
  455.             while (*bp != '\0')
  456.                 bp++;
  457.             p++;
  458.         }
  459.         else
  460.             *bp++ = *p++;
  461.     }
  462.     *bp = '\0';
  463. }
  464. /*
  465. **  SAFEFILE -- return true if a file exists and is safe for a user.
  466. **
  467. **    Parameters:
  468. **        fn -- filename to check.
  469. **        uid -- uid to compare against.
  470. **        mode -- mode bits that must match.
  471. **
  472. **    Returns:
  473. **        TRUE if fn exists, is owned by uid, and matches mode.
  474. **        FALSE otherwise.
  475. **
  476. **    Side Effects:
  477. **        none.
  478. */
  479.  
  480. bool
  481. safefile(fn, uid, mode)
  482.     char *fn;
  483.     int uid;
  484.     int mode;
  485. {
  486.     struct stat stbuf;
  487.  
  488.     if (stat(fn, &stbuf) >= 0 && stbuf.st_uid == uid &&
  489.         (stbuf.st_mode & mode) == mode)
  490.         return (TRUE);
  491.     errno = 0;
  492.     return (FALSE);
  493. }
  494. /*
  495. **  FIXCRLF -- fix <CR><LF> in line.
  496. **
  497. **    Looks for the <CR><LF> combination and turns it into the
  498. **    UNIX canonical <NL> character.  It only takes one line,
  499. **    i.e., it is assumed that the first <NL> found is the end
  500. **    of the line.
  501. **
  502. **    Parameters:
  503. **        line -- the line to fix.
  504. **        stripnl -- if true, strip the newline also.
  505. **
  506. **    Returns:
  507. **        none.
  508. **
  509. **    Side Effects:
  510. **        line is changed in place.
  511. */
  512.  
  513. fixcrlf(line, stripnl)
  514.     char *line;
  515.     bool stripnl;
  516. {
  517.     register char *p;
  518.  
  519.     p = index(line, '\n');
  520.     if (p == NULL)
  521.         return;
  522.     if (p > line && p[-1] == '\r')
  523.         p--;
  524.     if (!stripnl)
  525.         *p++ = '\n';
  526.     *p = '\0';
  527. }
  528. /*
  529. **  DFOPEN -- determined file open
  530. **
  531. **    This routine has the semantics of fopen, except that it will
  532. **    keep trying a few times to make this happen.  The idea is that
  533. **    on very loaded systems, we may run out of resources (inodes,
  534. **    whatever), so this tries to get around it.
  535. */
  536.  
  537. FILE *
  538. dfopen(filename, mode)
  539.     char *filename;
  540.     char *mode;
  541. {
  542.     register int tries;
  543.     register FILE *fp;
  544.  
  545.     for (tries = 0; tries < 10; tries++)
  546.     {
  547.         sleep((unsigned) (10 * tries));
  548.         errno = 0;
  549.         fp = fopen(filename, mode);
  550.         if (fp != NULL)
  551.             break;
  552.         if (errno != ENFILE && errno != EINTR)
  553.             break;
  554.     }
  555.     errno = 0;
  556.     return (fp);
  557. }
  558. /*
  559. **  PUTLINE -- put a line like fputs obeying SMTP conventions
  560. **
  561. **    This routine always guarantees outputing a newline (or CRLF,
  562. **    as appropriate) at the end of the string.
  563. **
  564. **    Parameters:
  565. **        l -- line to put.
  566. **        fp -- file to put it onto.
  567. **        m -- the mailer used to control output.
  568. **
  569. **    Returns:
  570. **        none
  571. **
  572. **    Side Effects:
  573. **        output of l to fp.
  574. */
  575.  
  576. # define SMTPLINELIM    990    /* maximum line length */
  577.  
  578. putline(l, fp, m)
  579.     register char *l;
  580.     FILE *fp;
  581.     MAILER *m;
  582. {
  583.     register char *p;
  584.     char svchar;
  585.  
  586.     /* strip out 0200 bits -- these can look like TELNET protocol */
  587.     if (bitnset(M_LIMITS, m->m_flags))
  588.     {
  589.         p = l;
  590.         while ((*p++ &= ~0200) != 0)
  591.             continue;
  592.     }
  593.  
  594.     do
  595.     {
  596.         /* find the end of the line */
  597.         p = index(l, '\n');
  598.         if (p == NULL)
  599.             p = &l[strlen(l)];
  600.  
  601.         /* check for line overflow */
  602.         while ((p - l) > SMTPLINELIM && bitnset(M_LIMITS, m->m_flags))
  603.         {
  604.             register char *q = &l[SMTPLINELIM - 1];
  605.  
  606.             svchar = *q;
  607.             *q = '\0';
  608.             if (l[0] == '.' && bitnset(M_XDOT, m->m_flags))
  609.                 (void) putc('.', fp);
  610.             fputs(l, fp);
  611.             (void) putc('!', fp);
  612.             fputs(m->m_eol, fp);
  613.             *q = svchar;
  614.             l = q;
  615.         }
  616.  
  617.         /* output last part */
  618.         svchar = *p;
  619.         *p = '\0';
  620.         if (l[0] == '.' && bitnset(M_XDOT, m->m_flags))
  621.             (void) putc('.', fp);
  622.         fputs(l, fp);
  623.         fputs(m->m_eol, fp);
  624.         *p = svchar;
  625.         l = p;
  626.         if (*l == '\n')
  627.             l++;
  628.     } while (l[0] != '\0');
  629. }
  630. /*
  631. **  XUNLINK -- unlink a file, doing logging as appropriate.
  632. **
  633. **    Parameters:
  634. **        f -- name of file to unlink.
  635. **
  636. **    Returns:
  637. **        none.
  638. **
  639. **    Side Effects:
  640. **        f is unlinked.
  641. */
  642.  
  643. xunlink(f)
  644.     char *f;
  645. {
  646.     register int i;
  647.  
  648. # ifdef LOG
  649.     if (LogLevel > 20)
  650.         syslog(LOG_DEBUG, "%s: unlink %s\n", CurEnv->e_id, f);
  651. # endif LOG
  652.  
  653.     i = unlink(f);
  654. # ifdef LOG
  655.     if (i < 0 && LogLevel > 21)
  656.         syslog(LOG_DEBUG, "%s: unlink-fail %d", f, errno);
  657. # endif LOG
  658. }
  659. /*
  660. **  SFGETS -- "safe" fgets -- times out and ignores random interrupts.
  661. **
  662. **    Parameters:
  663. **        buf -- place to put the input line.
  664. **        siz -- size of buf.
  665. **        fp -- file to read from.
  666. **
  667. **    Returns:
  668. **        NULL on error (including timeout).  This will also leave
  669. **            buf containing a null string.
  670. **        buf otherwise.
  671. **
  672. **    Side Effects:
  673. **        none.
  674. */
  675.  
  676. static jmp_buf    CtxReadTimeout;
  677.  
  678. char *
  679. sfgets(buf, siz, fp)
  680.     char *buf;
  681.     int siz;
  682.     FILE *fp;
  683. {
  684.     register EVENT *ev = NULL;
  685.     register char *p;
  686.     extern readtimeout();
  687.  
  688.     /* set the timeout */
  689.     if (ReadTimeout != 0)
  690.     {
  691.         if (setjmp(CtxReadTimeout) != 0)
  692.         {
  693. # ifdef LOG
  694.             syslog(LOG_NOTICE,
  695.                 "timeout waiting for input from %s\n",
  696.                 RealHostName? RealHostName: "local");
  697. # endif
  698.             errno = 0;
  699.             usrerr("451 timeout waiting for input");
  700.             buf[0] = '\0';
  701.             return (NULL);
  702.         }
  703.         ev = setevent((time_t) ReadTimeout, readtimeout, 0);
  704.     }
  705.  
  706.     /* try to read */
  707.     p = NULL;
  708.     while (p == NULL && !feof(fp) && !ferror(fp))
  709.     {
  710.         errno = 0;
  711.         p = fgets(buf, siz, fp);
  712.         if (errno == EINTR)
  713.             clearerr(fp);
  714.     }
  715.  
  716.     /* clear the event if it has not sprung */
  717.     clrevent(ev);
  718.  
  719.     /* clean up the books and exit */
  720.     LineNumber++;
  721.     if (p == NULL)
  722.     {
  723.         buf[0] = '\0';
  724.         return (NULL);
  725.     }
  726.     for (p = buf; *p != '\0'; p++)
  727.         *p &= ~0200;
  728.     return (buf);
  729. }
  730.  
  731. static
  732. readtimeout()
  733. {
  734.     longjmp(CtxReadTimeout, 1);
  735. }
  736. /*
  737. **  FGETFOLDED -- like fgets, but know about folded lines.
  738. **
  739. **    Parameters:
  740. **        buf -- place to put result.
  741. **        n -- bytes available.
  742. **        f -- file to read from.
  743. **
  744. **    Returns:
  745. **        buf on success, NULL on error or EOF.
  746. **
  747. **    Side Effects:
  748. **        buf gets lines from f, with continuation lines (lines
  749. **        with leading white space) appended.  CRLF's are mapped
  750. **        into single newlines.  Any trailing NL is stripped.
  751. */
  752.  
  753. char *
  754. fgetfolded(buf, n, f)
  755.     char *buf;
  756.     register int n;
  757.     FILE *f;
  758. {
  759.     register char *p = buf;
  760.     register int i;
  761.  
  762.     n--;
  763.     while ((i = getc(f)) != EOF)
  764.     {
  765.         if (i == '\r')
  766.         {
  767.             i = getc(f);
  768.             if (i != '\n')
  769.             {
  770.                 if (i != EOF)
  771.                     (void) ungetc(i, f);
  772.                 i = '\r';
  773.             }
  774.         }
  775.         if (--n > 0)
  776.             *p++ = i;
  777.         if (i == '\n')
  778.         {
  779.             LineNumber++;
  780.             i = getc(f);
  781.             if (i != EOF)
  782.                 (void) ungetc(i, f);
  783.             if (i != ' ' && i != '\t')
  784.             {
  785.                 *--p = '\0';
  786.                 return (buf);
  787.             }
  788.         }
  789.     }
  790.     return (NULL);
  791. }
  792. /*
  793. **  CURTIME -- return current time.
  794. **
  795. **    Parameters:
  796. **        none.
  797. **
  798. **    Returns:
  799. **        the current time.
  800. **
  801. **    Side Effects:
  802. **        none.
  803. */
  804.  
  805. time_t
  806. curtime()
  807. {
  808.     auto time_t t;
  809.  
  810.     (void) time(&t);
  811.     return (t);
  812. }
  813. /*
  814. **  ATOBOOL -- convert a string representation to boolean.
  815. **
  816. **    Defaults to "TRUE"
  817. **
  818. **    Parameters:
  819. **        s -- string to convert.  Takes "tTyY" as true,
  820. **            others as false.
  821. **
  822. **    Returns:
  823. **        A boolean representation of the string.
  824. **
  825. **    Side Effects:
  826. **        none.
  827. */
  828.  
  829. bool
  830. atobool(s)
  831.     register char *s;
  832. {
  833.     if (*s == '\0' || index("tTyY", *s) != NULL)
  834.         return (TRUE);
  835.     return (FALSE);
  836. }
  837. /*
  838. **  ATOOCT -- convert a string representation to octal.
  839. **
  840. **    Parameters:
  841. **        s -- string to convert.
  842. **
  843. **    Returns:
  844. **        An integer representing the string interpreted as an
  845. **        octal number.
  846. **
  847. **    Side Effects:
  848. **        none.
  849. */
  850.  
  851. atooct(s)
  852.     register char *s;
  853. {
  854.     register int i = 0;
  855.  
  856.     while (*s >= '0' && *s <= '7')
  857.         i = (i << 3) | (*s++ - '0');
  858.     return (i);
  859. }
  860. /*
  861. **  WAITFOR -- wait for a particular process id.
  862. **
  863. **    Parameters:
  864. **        pid -- process id to wait for.
  865. **
  866. **    Returns:
  867. **        status of pid.
  868. **        -1 if pid never shows up.
  869. **
  870. **    Side Effects:
  871. **        none.
  872. */
  873.  
  874. waitfor(pid)
  875.     int pid;
  876. {
  877.     auto int st;
  878.     int i;
  879.  
  880.     do
  881.     {
  882.         errno = 0;
  883.         i = wait(&st);
  884.     } while ((i >= 0 || errno == EINTR) && i != pid);
  885.     if (i < 0)
  886.         st = -1;
  887.     return (st);
  888. }
  889. /*
  890. **  BITINTERSECT -- tell if two bitmaps intersect
  891. **
  892. **    Parameters:
  893. **        a, b -- the bitmaps in question
  894. **
  895. **    Returns:
  896. **        TRUE if they have a non-null intersection
  897. **        FALSE otherwise
  898. **
  899. **    Side Effects:
  900. **        none.
  901. */
  902.  
  903. bool
  904. bitintersect(a, b)
  905.     BITMAP a;
  906.     BITMAP b;
  907. {
  908.     int i;
  909.  
  910.     for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
  911.         if ((a[i] & b[i]) != 0)
  912.             return (TRUE);
  913.     return (FALSE);
  914. }
  915. /*
  916. **  BITZEROP -- tell if a bitmap is all zero
  917. **
  918. **    Parameters:
  919. **        map -- the bit map to check
  920. **
  921. **    Returns:
  922. **        TRUE if map is all zero.
  923. **        FALSE if there are any bits set in map.
  924. **
  925. **    Side Effects:
  926. **        none.
  927. */
  928.  
  929. bool
  930. bitzerop(map)
  931.     BITMAP map;
  932. {
  933.     int i;
  934.  
  935.     for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
  936.         if (map[i] != 0)
  937.             return (FALSE);
  938.     return (TRUE);
  939. }
  940. @
  941.  
  942.  
  943. 5.18.0.1
  944. log
  945. @IDA patches
  946. @
  947. text
  948. @a31 2
  949. bool catPrint = FALSE;        /* xputs: print strings for catenation */
  950.  
  951. a271 1
  952.     register struct metamac *m;
  953. a272 5
  954.     if (s == MACNULL)
  955.     {
  956.         printf("<macnull>");
  957.         return;
  958.     }
  959. d278 1
  960. a278 16
  961.  
  962.     if (s[0] == MATCHREPL && isdigit(s[1]) && s[2] == '\0')
  963.     {
  964.         printf("$%c", s[1]);
  965.         return;
  966.     }
  967.     else
  968.         for (m = MetaMacros; m->metaname != '\0'; m++)
  969.             if (m->metaval == *s)
  970.             {
  971.                 printf("$%c%s", m->metaname, &s[1]);
  972.                 return;
  973.             }
  974.  
  975.     if (!catPrint)
  976.         (void) putchar('"');
  977. d293 1
  978. a293 2
  979.     if (!catPrint)
  980.         (void) putchar('"');
  981. a316 1
  982.     register bool quoted_string = FALSE;
  983. d321 1
  984. a321 3
  985.         if (c == '"')
  986.             quoted_string = !quoted_string;
  987.         else if (!quoted_string && isascii(c) && isupper(c))
  988. d553 1
  989. a553 1
  990. # endif /* LOG */
  991. d559 1
  992. a559 1
  993. # endif /* LOG */
  994. a589 7
  995.     /* check for reasonable siz arg */
  996.     if (siz < 1)
  997.     {
  998.         buf[0] = '\0';
  999.         return (NULL);
  1000.     }
  1001.  
  1002. d599 1
  1003. a599 1
  1004. # endif  /* LOG */
  1005. a841 44
  1006.  
  1007. /*
  1008. **    PRINTCAV -- Print concatenated argument vector
  1009. **
  1010. **    Parameters:
  1011. **        av -- argument vector.
  1012. **
  1013. **    Returns:
  1014. **        none.
  1015. **
  1016. **    Side Effects:
  1017. **        prints av.
  1018. */
  1019.  
  1020. printcav(av)
  1021.      register char **av;
  1022. {
  1023.   bool oldCatPrint = catPrint;
  1024.  
  1025.   catPrint = TRUE;
  1026.   printav(av);
  1027.   catPrint = oldCatPrint;
  1028. }
  1029.  
  1030. #ifdef OUTPUT_PID
  1031. write_pid_to_file ()
  1032. {
  1033.     extern char *PidFile;
  1034.     FILE *f;
  1035.     (void) unlink (PidFile);    /* try to be safe :-) */
  1036.     f = dfopen (PidFile, "w");
  1037.     if (errno == 0)
  1038.     {
  1039.         fprintf (f, "%d\n", getpid());
  1040.         (void) chmod (PidFile, 0444);
  1041.         (void) fclose (f);
  1042.     }
  1043. #ifdef LOG
  1044.     else
  1045.         syslog(LOG_NOTICE, "Could not log daemon pid %d to file %s\n",
  1046.                getpid(), PidFile);
  1047. #endif
  1048. }
  1049. #endif    /* OUTPUT_PID */
  1050. @
  1051.  
  1052.  
  1053. 5.18.0.2
  1054. log
  1055. @Bruce Lilly (bruce%balilly@@sonyd1.broadcast.sony.com) contributed putline()
  1056. changes: efficiency (don't re-compute XDOT inside loops), and readability
  1057. (let fprintf do the hard work).  Also strip extraneous newlines from 
  1058. syslog() statements.
  1059. @
  1060. text
  1061. @a513 1
  1062.     int    limitsflag,    xdotflag;
  1063. a514 1
  1064.     limitsflag = bitnset(M_LIMITS, m->m_flags);
  1065. d516 6
  1066. a521 4
  1067.     if (limitsflag)
  1068.         for (p=l; (*p & ~0200)!=0; p++)
  1069.             if (*p & 0200)
  1070.                 *p &= ~0200;
  1071. a522 1
  1072.     xdotflag = bitnset(M_XDOT, m->m_flags);
  1073. d531 1
  1074. a531 1
  1075.         while (((p - l) > SMTPLINELIM) && limitsflag)
  1076. d535 3
  1077. a537 1
  1078.             if ((*l == '.') && xdotflag)
  1079. d539 4
  1080. a542 1
  1081.             fprintf(fp, "%.*s!%s", SMTPLINELIM-1, l, m->m_eol);
  1082. d547 3
  1083. a549 1
  1084.         if ((*l == '.') && xdotflag)
  1085. d551 3
  1086. a553 1
  1087.         fprintf(fp, "%.*s%s", p-l, l, m->m_eol);
  1088. d557 1
  1089. a557 1
  1090.     } while (*l != '\0');
  1091. d579 1
  1092. a579 1
  1093.         syslog(LOG_DEBUG, "%s: unlink %s", CurEnv->e_id, f);
  1094. d615 1
  1095. a615 1
  1096.     static readtimeout();
  1097. d631 1
  1098. a631 1
  1099.                 "timeout waiting for input from %s",
  1100. d915 1
  1101. a915 1
  1102.         syslog(LOG_NOTICE, "Could not log daemon pid %d to file %s",
  1103. @
  1104.  
  1105.  
  1106. 5.18.0.3
  1107. log
  1108. @Fixed forward declaration of readtimeout().
  1109. @
  1110. text
  1111. @a597 1
  1112. void        readtimeout();
  1113. d607 1
  1114. d659 1
  1115. a659 1
  1116. static void
  1117. @
  1118.  
  1119.  
  1120. 5.18.0.4
  1121. log
  1122. @Deleted #ifdef/#define OUTPUT_PID in favor of testing whether _PATH_SENDMAILPID
  1123. is set.  sendmail.h now #include's pathnames.h instead of the other
  1124. modules.
  1125. @
  1126. text
  1127. @d25 6
  1128. a30 6
  1129. #include <stdio.h>
  1130. #include <sys/types.h>
  1131. #include <sys/stat.h>
  1132. #include <sysexits.h>
  1133. #include <errno.h>
  1134. #include "sendmail.h"
  1135. d505 1
  1136. a505 1
  1137. #define SMTPLINELIM    990    /* maximum line length */
  1138. d569 1
  1139. a569 1
  1140. #ifdef LOG
  1141. d572 1
  1142. a572 1
  1143. #endif /* LOG */
  1144. d575 1
  1145. a575 1
  1146. #ifdef LOG
  1147. d578 1
  1148. a578 1
  1149. #endif /* LOG */
  1150. d621 1
  1151. a621 1
  1152. #ifdef LOG
  1153. d625 1
  1154. a625 1
  1155. #endif  /* LOG */
  1156. d892 2
  1157. a893 15
  1158. /*
  1159. **    WRITEPID -- Write process id to file
  1160. **
  1161. **    Parameters:
  1162. **        none
  1163. **
  1164. **    Returns:
  1165. **        none.
  1166. **
  1167. **    Side Effects:
  1168. **        writes pid file, creating if necessary
  1169. */
  1170.  
  1171. #ifdef _PATH_SENDMAILPID
  1172. WritePid()
  1173. d897 2
  1174. a898 3
  1175.  
  1176.     (void) unlink(PidFile);    /* try to be safe :-) */
  1177.     f = dfopen(PidFile, "w");
  1178. d901 3
  1179. a903 3
  1180.         fprintf(f, "%d\n", getpid());
  1181.         (void) chmod(PidFile, 0444);
  1182.         (void) fclose(f);
  1183. d905 1
  1184. a905 1
  1185. # ifdef LOG
  1186. d907 1
  1187. a907 1
  1188.         syslog(LOG_NOTICE, "Could not log daemon pid %d to file %s: %m",
  1189. d909 1
  1190. a909 1
  1191. # endif /* LOG */
  1192. d911 1
  1193. a911 1
  1194. #endif    /* _PATH_SENDMAILPID */
  1195. @
  1196.  
  1197.  
  1198. 5.18.0.5
  1199. log
  1200. @Deleted #include <sys/types.h> as it's already included via sendmail.h from
  1201. useful.h.  #include "sendmail.h" relocated to top of #include list.
  1202. @
  1203. text
  1204. @a24 1
  1205. #include "sendmail.h"
  1206. d26 1
  1207. d30 1
  1208. @
  1209.  
  1210.  
  1211. 5.18.0.6
  1212. log
  1213. @ANSIfied.
  1214. @
  1215. text
  1216. @a30 2
  1217. static void readtimeout();
  1218.  
  1219. a53 1
  1220. void
  1221. d78 1
  1222. a78 1
  1223. **    Returns:
  1224. d86 1
  1225. a86 1
  1226.     register const char *s;
  1227. d114 1
  1228. a114 1
  1229.     register const char *s;
  1230. a223 1
  1231. void
  1232. a268 1
  1233. void
  1234. d270 1
  1235. a270 1
  1236.     register const char *s;
  1237. a335 1
  1238. void
  1239. a367 1
  1240. void
  1241. d369 2
  1242. a370 2
  1243.     register const char *p;
  1244.     const char *login;
  1245. a440 1
  1246. void
  1247. d467 2
  1248. a468 2
  1249.     const char *filename;
  1250.     const char *mode;
  1251. d475 1
  1252. a475 1
  1253.         Xsleep((unsigned) (10 * tries));
  1254. a505 1
  1255. void
  1256. d544 1
  1257. a544 10
  1258.  
  1259.         /*
  1260.          * Some broken compilers evaluate %.0s%s as %s%s.  This
  1261.          * doubles blank lines.  I have to remember that portability
  1262.          * is one of my goals (*sigh*).  -pbp
  1263.          */
  1264.         if ((p-l) == 0)
  1265.             fprintf(fp, "%s", m->m_eol);
  1266.         else
  1267.             fprintf(fp, "%.*s%s", p-l, l, m->m_eol);
  1268. a562 1
  1269. void
  1270. d564 1
  1271. a564 1
  1272.     const char *f;
  1273. d597 1
  1274. d758 1
  1275. a758 1
  1276.     register const char *s;
  1277. d779 1
  1278. a779 1
  1279.     register const char *s;
  1280. a810 2
  1281.         if (i > 0 && tTd(4, 2))
  1282.             printf("waitfor: wait (pid = %d)\n", i);
  1283. a880 1
  1284. void
  1285. d882 1
  1286. a882 1
  1287.     register char **av;
  1288. d884 1
  1289. a884 1
  1290.     bool oldCatPrint = catPrint;
  1291. d886 3
  1292. a888 3
  1293.     catPrint = TRUE;
  1294.     printav(av);
  1295.     catPrint = oldCatPrint;
  1296. a904 1
  1297. void
  1298. @
  1299.  
  1300.  
  1301. 5.18.0.7
  1302. log
  1303. @Deleted extern declaration of malloc() (moved to def.h), deleted
  1304. inappropriate const qualifier.
  1305. @
  1306. text
  1307. @d160 1
  1308. d583 1
  1309. a583 1
  1310.     char *f;
  1311. @
  1312.  
  1313.  
  1314. 5.18.0.8
  1315. log
  1316. @WritePid() was checking errno and not return value from dfopen().
  1317. @
  1318. text
  1319. @d932 2
  1320. a933 1
  1321.     if ((f = dfopen(PidFile, "w")) != NULL)
  1322. @
  1323.  
  1324.  
  1325. 5.18.0.9
  1326. log
  1327. @Character set translation changes adapted from patches from Keld Simonsen
  1328. (keld@@dkuug.dk).
  1329. @
  1330. text
  1331. @d257 1
  1332. a257 1
  1333.     return (isascii(c) && isupper(c) ? tolower(c) : c);
  1334. a669 1
  1335. #ifndef BIT8
  1336. a671 1
  1337. #endif /* !BIT8 */
  1338. @
  1339.  
  1340.  
  1341. 5.18.0.10
  1342. log
  1343. @Added RCS ID string
  1344. @
  1345. text
  1346. @a22 1
  1347. static char  rcsid[] = "@@(#)$Id$";
  1348. @
  1349.  
  1350.  
  1351. 5.18.0.11
  1352. log
  1353. @System 5 and general improvement patches contributed by Bruce Lilly
  1354. (bruce%balilly@@broadcast.sony.com).
  1355. @
  1356. text
  1357. @d22 2
  1358. a23 2
  1359. static char sccsid[] = "@@(#)util.c    5.18 (Berkeley) 6/1/90    %I% local";
  1360. static char  rcsid[] = "@@(#)$Id: util.c,v 5.18.0.11 1991/05/18 03:39:00 paul Exp $";
  1361. d34 1
  1362. a34 1
  1363. static bool catPrint = FALSE;    /* xputs: print strings for catenation */
  1364. a88 1
  1365. int
  1366. a122 8
  1367.     if (strlen(s) >= 50)
  1368.     {
  1369.         errno = EFAULT; /* foregone conclusion */
  1370.         syserr("buffer size exceeded in capitalize(), size needed %d",
  1371.             strlen(s));
  1372.         return(NULL);
  1373.     }
  1374.  
  1375. d150 1
  1376. a150 1
  1377. **        pointer to zeroed data region.
  1378. a155 3
  1379. #ifdef __STDC__
  1380. void *
  1381. #else /* !__STDC__ */
  1382. a156 1
  1383. #endif /* __STDC__ */
  1384. a159 3
  1385. #ifdef __STDC__
  1386.     register void *p;
  1387. #else /* !__STDC__ */
  1388. a160 1
  1389. #endif /* __STDC__ */
  1390. a168 1
  1391.     bzero((char *) p, sz);
  1392. d521 1
  1393. a525 1
  1394.     /* damned well had better not have this bit set in constant strings! */
  1395. d559 1
  1396. a559 1
  1397.         if (p == l)
  1398. d755 1
  1399. a755 1
  1400.     auto TIME_TYPE t;
  1401. d758 1
  1402. a758 1
  1403.     return ((time_t)t);
  1404. a797 1
  1405. int
  1406. a820 1
  1407. int
  1408. @
  1409.  
  1410.  
  1411. 5.18.0.12
  1412. log
  1413. @If RealHostName == NULL, use $s.  If that's NULL, use "local".
  1414. @
  1415. text
  1416. @d23 1
  1417. a23 1
  1418. static char  rcsid[] = "@@(#)$Id: util.c,v 5.18.0.11 1991/05/23 22:06:36 paul Exp paul $";
  1419. a656 6
  1420.             char    *host;
  1421.  
  1422.             if (RealHostName != NULL)
  1423.                 host = RealHostName;
  1424.             else if ((host = macvalue('s', CurEnv)) == NULL)
  1425.                 host = "local";
  1426. d658 2
  1427. a659 1
  1428.                 "timeout waiting for input from %s", host);
  1429. @
  1430.  
  1431.  
  1432. 5.18.0.13
  1433. log
  1434. @Changed time_t to TIME_TYPE, editted sccsid.
  1435. @
  1436. text
  1437. @d22 2
  1438. a23 2
  1439. static char sccsid[] = "@@(#)util.c    5.18 (Berkeley) 6/1/90";
  1440. static char  rcsid[] = "@@(#)$Id: util.c,v 5.18.0.12 1991/05/29 19:24:10 paul Exp paul $";
  1441. d671 1
  1442. a671 1
  1443.         ev = setevent((TIME_TYPE) ReadTimeout, readtimeout, 0);
  1444. d775 1
  1445. a775 1
  1446. TIME_TYPE
  1447. d781 1
  1448. a781 1
  1449.     return ((TIME_TYPE)t);
  1450. @
  1451.  
  1452.  
  1453. 5.18.0.14
  1454. log
  1455. @Stephen Cliffe (steve@@cs.uow.edu.au) noted that safefile() fails if
  1456. the uid value is large and compares as a negative number.  The fix
  1457. is to cast the incoming value of uid to (uid_t).
  1458. @
  1459. text
  1460. @d23 1
  1461. a23 1
  1462. static char  rcsid[] = "@@(#)$Id: util.c,v 5.18.0.13 1991/06/24 20:31:52 paul Exp paul $";
  1463. d441 1
  1464. a441 1
  1465.     if (stat(fn, &stbuf) >= 0 && stbuf.st_uid == (uid_t) uid &&
  1466. @
  1467.