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