home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / sendmail / src / macro.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-03  |  6.2 KB  |  260 lines

  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, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  *    This product includes software developed by the University of
  17.  *    California, Berkeley and its contributors.
  18.  * 4. Neither the name of the University nor the names of its contributors
  19.  *    may be used to endorse or promote products derived from this software
  20.  *    without specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  */
  34.  
  35. #ifndef lint
  36. static char sccsid[] = "@(#)macro.c    5.7 (Berkeley) 6/1/90";
  37. #endif /* not lint */
  38.  
  39. # include "sendmail.h"
  40.  
  41. /*
  42. **  EXPAND -- macro expand a string using $x escapes.
  43. **
  44. **    Parameters:
  45. **        s -- the string to expand.
  46. **        buf -- the place to put the expansion.
  47. **        buflim -- the buffer limit, i.e., the address
  48. **            of the last usable position in buf.
  49. **        e -- envelope in which to work.
  50. **
  51. **    Returns:
  52. **        none.
  53. **
  54. **    Side Effects:
  55. **        none.
  56. */
  57.  
  58. expand(s, buf, buflim, e)
  59.     register char *s;
  60.     register char *buf;
  61.     char *buflim;
  62.     register ENVELOPE *e;
  63. {
  64.     register char *xp;
  65.     register char *q;
  66.     bool skipping;        /* set if conditionally skipping output */
  67.     bool recurse = FALSE;    /* set if recursion required */
  68.     int i;
  69.     char xbuf[BUFSIZ];
  70.     extern char *macvalue();
  71.  
  72.     if (tTd(35, 24))
  73.     {
  74.         printf("expand(");
  75.         xputs(s);
  76.         printf(")\n");
  77.     }
  78.  
  79.     skipping = FALSE;
  80.     if (s == NULL)
  81.         s = "";
  82.     for (xp = xbuf; *s != '\0'; s++)
  83.     {
  84.         char c;
  85.  
  86.         /*
  87.         **  Check for non-ordinary (special?) character.
  88.         **    'q' will be the interpolated quantity.
  89.         */
  90.  
  91.         q = NULL;
  92.         c = *s;
  93.         switch (c)
  94.         {
  95.           case CONDIF:        /* see if var set */
  96.             c = *++s;
  97.             skipping = macvalue(c, e) == NULL;
  98.             continue;
  99.  
  100.           case CONDELSE:    /* change state of skipping */
  101.             skipping = !skipping;
  102.             continue;
  103.  
  104.           case CONDFI:        /* stop skipping */
  105.             skipping = FALSE;
  106.             continue;
  107.  
  108.           case '\001':        /* macro interpolation */
  109.             c = *++s;
  110.             q = macvalue(c & 0177, e);
  111.             if (q == NULL)
  112.                 continue;
  113.             break;
  114.         }
  115.  
  116.         /*
  117.         **  Interpolate q or output one character
  118.         */
  119.  
  120.         if (skipping || xp >= &xbuf[sizeof xbuf])
  121.             continue;
  122.         if (q == NULL)
  123.             *xp++ = c;
  124.         else
  125.         {
  126.             /* copy to end of q or max space remaining in buf */
  127.             while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1])
  128.             {
  129.                 if (iscntrl(c) && !isspace(c))
  130.                     recurse = TRUE;
  131.                 *xp++ = c;
  132.             }
  133.         }
  134.     }
  135.     *xp = '\0';
  136.  
  137.     if (tTd(35, 24))
  138.     {
  139.         printf("expand ==> ");
  140.         xputs(xbuf);
  141.         printf("\n");
  142.     }
  143.  
  144.     /* recurse as appropriate */
  145.     if (recurse)
  146.     {
  147.         expand(xbuf, buf, buflim, e);
  148.         return;
  149.     }
  150.  
  151.     /* copy results out */
  152.     i = buflim - buf - 1;
  153.     if (i > xp - xbuf)
  154.         i = xp - xbuf;
  155.     bcopy(xbuf, buf, i);
  156.     buf[i] = '\0';
  157. }
  158. /*
  159. **  DEFINE -- define a macro.
  160. **
  161. **    this would be better done using a #define macro.
  162. **
  163. **    Parameters:
  164. **        n -- the macro name.
  165. **        v -- the macro value.
  166. **        e -- the envelope to store the definition in.
  167. **
  168. **    Returns:
  169. **        none.
  170. **
  171. **    Side Effects:
  172. **        e->e_macro[n] is defined.
  173. **
  174. **    Notes:
  175. **        There is one macro for each ASCII character,
  176. **        although they are not all used.  The currently
  177. **        defined macros are:
  178. **
  179. **        $a   date in ARPANET format (preferring the Date: line
  180. **             of the message)
  181. **        $b   the current date (as opposed to the date as found
  182. **             the message) in ARPANET format
  183. **        $c   hop count
  184. **        $d   (current) date in UNIX (ctime) format
  185. **        $e   the SMTP entry message+
  186. **        $f   raw from address
  187. **        $g   translated from address
  188. **        $h   to host
  189. **        $i   queue id
  190. **        $j   official SMTP hostname, used in messages+
  191. **        $l   UNIX-style from line+
  192. **        $n   name of sendmail ("MAILER-DAEMON" on local
  193. **             net typically)+
  194. **        $o   delimiters ("operators") for address tokens+
  195. **        $p   my process id in decimal
  196. **        $q   the string that becomes an address -- this is
  197. **             normally used to combine $g & $x.
  198. **        $r   protocol used to talk to sender
  199. **        $s   sender's host name
  200. **        $t   the current time in seconds since 1/1/1970
  201. **        $u   to user
  202. **        $v   version number of sendmail
  203. **        $w   our host name (if it can be determined)
  204. **        $x   signature (full name) of from person
  205. **        $y   the tty id of our terminal
  206. **        $z   home directory of to person
  207. **
  208. **        Macros marked with + must be defined in the
  209. **        configuration file and are used internally, but
  210. **        are not set.
  211. **
  212. **        There are also some macros that can be used
  213. **        arbitrarily to make the configuration file
  214. **        cleaner.  In general all upper-case letters
  215. **        are available.
  216. */
  217.  
  218. define(n, v, e)
  219.     char n;
  220.     char *v;
  221.     register ENVELOPE *e;
  222. {
  223.     if (tTd(35, 9))
  224.     {
  225.         printf("define(%c as ", n);
  226.         xputs(v);
  227.         printf(")\n");
  228.     }
  229.     e->e_macro[n & 0177] = v;
  230. }
  231. /*
  232. **  MACVALUE -- return uninterpreted value of a macro.
  233. **
  234. **    Parameters:
  235. **        n -- the name of the macro.
  236. **
  237. **    Returns:
  238. **        The value of n.
  239. **
  240. **    Side Effects:
  241. **        none.
  242. */
  243.  
  244. char *
  245. macvalue(n, e)
  246.     char n;
  247.     register ENVELOPE *e;
  248. {
  249.     n &= 0177;
  250.     while (e != NULL)
  251.     {
  252.         register char *p = e->e_macro[n];
  253.  
  254.         if (p != NULL)
  255.             return (p);
  256.         e = e->e_parent;
  257.     }
  258.     return (NULL);
  259. }
  260.