|
|
1.1 ! root 1: /* ! 2: ** Sendmail ! 3: ** Copyright (c) 1983 Eric P. Allman ! 4: ** Berkeley, California ! 5: ** ! 6: ** Copyright (c) 1983 Regents of the University of California. ! 7: ** All rights reserved. The Berkeley software License Agreement ! 8: ** specifies the terms and conditions for redistribution. ! 9: */ ! 10: ! 11: #ifndef lint ! 12: static char SccsId[] = "@(#)macro.c 5.3 (Berkeley) 9/19/85"; ! 13: #endif not lint ! 14: ! 15: # include "sendmail.h" ! 16: ! 17: /* ! 18: ** EXPAND -- macro expand a string using $x escapes. ! 19: ** ! 20: ** Parameters: ! 21: ** s -- the string to expand. ! 22: ** buf -- the place to put the expansion. ! 23: ** buflim -- the buffer limit, i.e., the address ! 24: ** of the last usable position in buf. ! 25: ** e -- envelope in which to work. ! 26: ** ! 27: ** Returns: ! 28: ** none. ! 29: ** ! 30: ** Side Effects: ! 31: ** none. ! 32: */ ! 33: ! 34: expand(s, buf, buflim, e) ! 35: register char *s; ! 36: register char *buf; ! 37: char *buflim; ! 38: register ENVELOPE *e; ! 39: { ! 40: register char *xp; ! 41: register char *q; ! 42: bool skipping; /* set if conditionally skipping output */ ! 43: bool recurse = FALSE; /* set if recursion required */ ! 44: int i; ! 45: char xbuf[BUFSIZ]; ! 46: extern char *macvalue(); ! 47: ! 48: # ifdef DEBUG ! 49: if (tTd(35, 24)) ! 50: { ! 51: printf("expand("); ! 52: xputs(s); ! 53: printf(")\n"); ! 54: } ! 55: # endif DEBUG ! 56: ! 57: skipping = FALSE; ! 58: if (s == NULL) ! 59: s = ""; ! 60: for (xp = xbuf; *s != '\0'; s++) ! 61: { ! 62: char c; ! 63: ! 64: /* ! 65: ** Check for non-ordinary (special?) character. ! 66: ** 'q' will be the interpolated quantity. ! 67: */ ! 68: ! 69: q = NULL; ! 70: c = *s; ! 71: switch (c) ! 72: { ! 73: case CONDIF: /* see if var set */ ! 74: c = *++s; ! 75: skipping = macvalue(c, e) == NULL; ! 76: continue; ! 77: ! 78: case CONDELSE: /* change state of skipping */ ! 79: skipping = !skipping; ! 80: continue; ! 81: ! 82: case CONDFI: /* stop skipping */ ! 83: skipping = FALSE; ! 84: continue; ! 85: ! 86: case '\001': /* macro interpolation */ ! 87: c = *++s; ! 88: q = macvalue(c & 0177, e); ! 89: if (q == NULL) ! 90: continue; ! 91: break; ! 92: } ! 93: ! 94: /* ! 95: ** Interpolate q or output one character ! 96: */ ! 97: ! 98: if (skipping || xp >= &xbuf[sizeof xbuf]) ! 99: continue; ! 100: if (q == NULL) ! 101: *xp++ = c; ! 102: else ! 103: { ! 104: /* copy to end of q or max space remaining in buf */ ! 105: while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1]) ! 106: { ! 107: if (iscntrl(c) && !isspace(c)) ! 108: recurse = TRUE; ! 109: *xp++ = c; ! 110: } ! 111: } ! 112: } ! 113: *xp = '\0'; ! 114: ! 115: # ifdef DEBUG ! 116: if (tTd(35, 24)) ! 117: { ! 118: printf("expand ==> "); ! 119: xputs(xbuf); ! 120: printf("\n"); ! 121: } ! 122: # endif DEBUG ! 123: ! 124: /* recurse as appropriate */ ! 125: if (recurse) ! 126: { ! 127: expand(xbuf, buf, buflim, e); ! 128: return; ! 129: } ! 130: ! 131: /* copy results out */ ! 132: i = buflim - buf - 1; ! 133: if (i > xp - xbuf) ! 134: i = xp - xbuf; ! 135: bcopy(xbuf, buf, i); ! 136: buf[i] = '\0'; ! 137: } ! 138: /* ! 139: ** DEFINE -- define a macro. ! 140: ** ! 141: ** this would be better done using a #define macro. ! 142: ** ! 143: ** Parameters: ! 144: ** n -- the macro name. ! 145: ** v -- the macro value. ! 146: ** e -- the envelope to store the definition in. ! 147: ** ! 148: ** Returns: ! 149: ** none. ! 150: ** ! 151: ** Side Effects: ! 152: ** e->e_macro[n] is defined. ! 153: ** ! 154: ** Notes: ! 155: ** There is one macro for each ASCII character, ! 156: ** although they are not all used. The currently ! 157: ** defined macros are: ! 158: ** ! 159: ** $a date in ARPANET format (preferring the Date: line ! 160: ** of the message) ! 161: ** $b the current date (as opposed to the date as found ! 162: ** the message) in ARPANET format ! 163: ** $c hop count ! 164: ** $d (current) date in UNIX (ctime) format ! 165: ** $e the SMTP entry message+ ! 166: ** $f raw from address ! 167: ** $g translated from address ! 168: ** $h to host ! 169: ** $i queue id ! 170: ** $j official SMTP hostname, used in messages+ ! 171: ** $l UNIX-style from line+ ! 172: ** $n name of sendmail ("MAILER-DAEMON" on local ! 173: ** net typically)+ ! 174: ** $o delimiters ("operators") for address tokens+ ! 175: ** $p my process id in decimal ! 176: ** $q the string that becomes an address -- this is ! 177: ** normally used to combine $g & $x. ! 178: ** $r protocol used to talk to sender ! 179: ** $s sender's host name ! 180: ** $t the current time in seconds since 1/1/1970 ! 181: ** $u to user ! 182: ** $v version number of sendmail ! 183: ** $w our host name (if it can be determined) ! 184: ** $x signature (full name) of from person ! 185: ** $y the tty id of our terminal ! 186: ** $z home directory of to person ! 187: ** ! 188: ** Macros marked with + must be defined in the ! 189: ** configuration file and are used internally, but ! 190: ** are not set. ! 191: ** ! 192: ** There are also some macros that can be used ! 193: ** arbitrarily to make the configuration file ! 194: ** cleaner. In general all upper-case letters ! 195: ** are available. ! 196: */ ! 197: ! 198: define(n, v, e) ! 199: char n; ! 200: char *v; ! 201: register ENVELOPE *e; ! 202: { ! 203: # ifdef DEBUG ! 204: if (tTd(35, 9)) ! 205: { ! 206: printf("define(%c as ", n); ! 207: xputs(v); ! 208: printf(")\n"); ! 209: } ! 210: # endif DEBUG ! 211: e->e_macro[n & 0177] = v; ! 212: } ! 213: /* ! 214: ** MACVALUE -- return uninterpreted value of a macro. ! 215: ** ! 216: ** Parameters: ! 217: ** n -- the name of the macro. ! 218: ** ! 219: ** Returns: ! 220: ** The value of n. ! 221: ** ! 222: ** Side Effects: ! 223: ** none. ! 224: */ ! 225: ! 226: char * ! 227: macvalue(n, e) ! 228: char n; ! 229: register ENVELOPE *e; ! 230: { ! 231: n &= 0177; ! 232: while (e != NULL) ! 233: { ! 234: register char *p = e->e_macro[n]; ! 235: ! 236: if (p != NULL) ! 237: return (p); ! 238: e = e->e_parent; ! 239: } ! 240: return (NULL); ! 241: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.