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