summaryrefslogtreecommitdiff
path: root/contrib/sendmail/src/macro.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/macro.c')
-rw-r--r--contrib/sendmail/src/macro.c598
1 files changed, 0 insertions, 598 deletions
diff --git a/contrib/sendmail/src/macro.c b/contrib/sendmail/src/macro.c
deleted file mode 100644
index af8f6d5b1945..000000000000
--- a/contrib/sendmail/src/macro.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * Copyright (c) 1998-2001, 2003 Sendmail, Inc. and its suppliers.
- * All rights reserved.
- * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
- * Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * By using this file, you agree to the terms and conditions set
- * forth in the LICENSE file which can be found at the top level of
- * the sendmail distribution.
- *
- */
-
-#include <sendmail.h>
-
-SM_RCSID("@(#)$Id: macro.c,v 8.88 2003/09/05 23:11:18 ca Exp $")
-
-#if MAXMACROID != (BITMAPBITS - 1)
- ERROR Read the comment in conf.h
-#endif /* MAXMACROID != (BITMAPBITS - 1) */
-
-static char *MacroName[MAXMACROID + 1]; /* macro id to name table */
-int NextMacroId = 0240; /* codes for long named macros */
-
-/*
-** INITMACROS -- initialize the macro system
-**
-** This just involves defining some macros that are actually
-** used internally as metasymbols to be themselves.
-**
-** Parameters:
-** none.
-**
-** Returns:
-** none.
-**
-** Side Effects:
-** initializes several macros to be themselves.
-*/
-
-struct metamac MetaMacros[] =
-{
- /* LHS pattern matching characters */
- { '*', MATCHZANY }, { '+', MATCHANY }, { '-', MATCHONE },
- { '=', MATCHCLASS }, { '~', MATCHNCLASS },
-
- /* these are RHS metasymbols */
- { '#', CANONNET }, { '@', CANONHOST }, { ':', CANONUSER },
- { '>', CALLSUBR },
-
- /* the conditional operations */
- { '?', CONDIF }, { '|', CONDELSE }, { '.', CONDFI },
-
- /* the hostname lookup characters */
- { '[', HOSTBEGIN }, { ']', HOSTEND },
- { '(', LOOKUPBEGIN }, { ')', LOOKUPEND },
-
- /* miscellaneous control characters */
- { '&', MACRODEXPAND },
-
- { '\0', '\0' }
-};
-
-#define MACBINDING(name, mid) \
- stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \
- MacroName[mid] = name;
-
-void
-initmacros(e)
- register ENVELOPE *e;
-{
- register struct metamac *m;
- register int c;
- char buf[5];
-
- for (m = MetaMacros; m->metaname != '\0'; m++)
- {
- buf[0] = m->metaval;
- buf[1] = '\0';
- macdefine(&e->e_macro, A_TEMP, m->metaname, buf);
- }
- buf[0] = MATCHREPL;
- buf[2] = '\0';
- for (c = '0'; c <= '9'; c++)
- {
- buf[1] = c;
- macdefine(&e->e_macro, A_TEMP, c, buf);
- }
-
- /* set defaults for some macros sendmail will use later */
- macdefine(&e->e_macro, A_PERM, 'n', "MAILER-DAEMON");
-
- /* set up external names for some internal macros */
- MACBINDING("opMode", MID_OPMODE);
- /*XXX should probably add equivalents for all short macros here XXX*/
-}
-/*
-** EXPAND -- macro expand a string using $x escapes.
-**
-** Parameters:
-** s -- the string to expand.
-** buf -- the place to put the expansion.
-** bufsize -- the size of the buffer.
-** e -- envelope in which to work.
-**
-** Returns:
-** none.
-**
-** Side Effects:
-** none.
-*/
-
-void
-expand(s, buf, bufsize, e)
- register char *s;
- register char *buf;
- size_t bufsize;
- register ENVELOPE *e;
-{
- register char *xp;
- register char *q;
- bool skipping; /* set if conditionally skipping output */
- bool recurse; /* set if recursion required */
- size_t i;
- int skiplev; /* skipping nesting level */
- int iflev; /* if nesting level */
- char xbuf[MACBUFSIZE];
- static int explevel = 0;
-
- if (tTd(35, 24))
- {
- sm_dprintf("expand(");
- xputs(sm_debug_file(), s);
- sm_dprintf(")\n");
- }
-
- recurse = false;
- skipping = false;
- skiplev = 0;
- iflev = 0;
- if (s == NULL)
- s = "";
- for (xp = xbuf; *s != '\0'; s++)
- {
- int c;
-
- /*
- ** Check for non-ordinary (special?) character.
- ** 'q' will be the interpolated quantity.
- */
-
- q = NULL;
- c = *s;
- switch (c & 0377)
- {
- case CONDIF: /* see if var set */
- iflev++;
- c = *++s;
- if (skipping)
- skiplev++;
- else
- {
- char *mv;
-
- mv = macvalue(c, e);
- skipping = (mv == NULL || *mv == '\0');
- }
- continue;
-
- case CONDELSE: /* change state of skipping */
- if (iflev == 0)
- break; /* XXX: error */
- if (skiplev == 0)
- skipping = !skipping;
- continue;
-
- case CONDFI: /* stop skipping */
- if (iflev == 0)
- break; /* XXX: error */
- iflev--;
- if (skiplev == 0)
- skipping = false;
- if (skipping)
- skiplev--;
- continue;
-
- case MACROEXPAND: /* macro interpolation */
- c = bitidx(*++s);
- if (c != '\0')
- q = macvalue(c, e);
- else
- {
- s--;
- q = NULL;
- }
- if (q == NULL)
- continue;
- break;
- }
-
- /*
- ** Interpolate q or output one character
- */
-
- if (skipping || xp >= &xbuf[sizeof xbuf - 1])
- continue;
- if (q == NULL)
- *xp++ = c;
- else
- {
- /* copy to end of q or max space remaining in buf */
- while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1])
- {
- /* check for any sendmail metacharacters */
- if ((c & 0340) == 0200)
- recurse = true;
- *xp++ = c;
- }
- }
- }
- *xp = '\0';
-
- if (tTd(35, 24))
- {
- sm_dprintf("expand ==> ");
- xputs(sm_debug_file(), xbuf);
- sm_dprintf("\n");
- }
-
- /* recurse as appropriate */
- if (recurse)
- {
- if (explevel < MaxMacroRecursion)
- {
- explevel++;
- expand(xbuf, buf, bufsize, e);
- explevel--;
- return;
- }
- syserr("expand: recursion too deep (%d max)",
- MaxMacroRecursion);
- }
-
- /* copy results out */
- i = xp - xbuf;
- if (i >= bufsize)
- i = bufsize - 1;
- memmove(buf, xbuf, i);
- buf[i] = '\0';
-}
-
-/*
-** MACDEFINE -- bind a macro name to a value
-**
-** Set a macro to a value, with fancy storage management.
-** macdefine will make a copy of the value, if required,
-** and will ensure that the storage for the previous value
-** is not leaked.
-**
-** Parameters:
-** mac -- Macro table.
-** vclass -- storage class of 'value', ignored if value==NULL.
-** A_HEAP means that the value was allocated by
-** malloc, and that macdefine owns the storage.
-** A_TEMP means that value points to temporary storage,
-** and thus macdefine needs to make a copy.
-** A_PERM means that value points to storage that
-** will remain allocated and unchanged for
-** at least the lifetime of mac. Use A_PERM if:
-** -- value == NULL,
-** -- value points to a string literal,
-** -- value was allocated from mac->mac_rpool
-** or (in the case of an envelope macro)
-** from e->e_rpool,
-** -- in the case of an envelope macro,
-** value is a string member of the envelope
-** such as e->e_sender.
-** id -- Macro id. This is a single character macro name
-** such as 'g', or a value returned by macid().
-** value -- Macro value: either NULL, or a string.
-*/
-
-void
-#if SM_HEAP_CHECK
-macdefine_tagged(mac, vclass, id, value, file, line, grp)
-#else /* SM_HEAP_CHECK */
-macdefine(mac, vclass, id, value)
-#endif /* SM_HEAP_CHECK */
- MACROS_T *mac;
- ARGCLASS_T vclass;
- int id;
- char *value;
-#if SM_HEAP_CHECK
- char *file;
- int line;
- int grp;
-#endif /* SM_HEAP_CHECK */
-{
- char *newvalue;
-
- if (id < 0 || id > MAXMACROID)
- return;
-
- if (tTd(35, 9))
- {
- sm_dprintf("%sdefine(%s as ",
- mac->mac_table[id] == NULL ? "" : "re", macname(id));
- xputs(sm_debug_file(), value);
- sm_dprintf(")\n");
- }
-
- if (mac->mac_rpool == NULL)
- {
- char *freeit = NULL;
-
- if (mac->mac_table[id] != NULL &&
- bitnset(id, mac->mac_allocated))
- freeit = mac->mac_table[id];
-
- if (value == NULL || vclass == A_HEAP)
- {
- sm_heap_checkptr_tagged(value, file, line);
- newvalue = value;
- clrbitn(id, mac->mac_allocated);
- }
- else
- {
-#if SM_HEAP_CHECK
- newvalue = sm_strdup_tagged_x(value, file, line, 0);
-#else /* SM_HEAP_CHECK */
- newvalue = sm_strdup_x(value);
-#endif /* SM_HEAP_CHECK */
- setbitn(id, mac->mac_allocated);
- }
- mac->mac_table[id] = newvalue;
- if (freeit != NULL)
- sm_free(freeit);
- }
- else
- {
- if (value == NULL || vclass == A_PERM)
- newvalue = value;
- else
- newvalue = sm_rpool_strdup_x(mac->mac_rpool, value);
- mac->mac_table[id] = newvalue;
- if (vclass == A_HEAP)
- sm_free(value);
- }
-
-#if _FFR_RESET_MACRO_GLOBALS
- switch (id)
- {
- case 'j':
- PSTRSET(MyHostName, value);
- break;
- }
-#endif /* _FFR_RESET_MACRO_GLOBALS */
-}
-
-/*
-** MACSET -- set a named macro to a value (low level)
-**
-** No fancy storage management; the caller takes full responsibility.
-** Often used with macget; see also macdefine.
-**
-** Parameters:
-** mac -- Macro table.
-** i -- Macro name, specified as an integer offset.
-** value -- Macro value: either NULL, or a string.
-*/
-
-void
-macset(mac, i, value)
- MACROS_T *mac;
- int i;
- char *value;
-{
- if (i < 0 || i > MAXMACROID)
- return;
-
- if (tTd(35, 9))
- {
- sm_dprintf("macset(%s as ", macname(i));
- xputs(sm_debug_file(), value);
- sm_dprintf(")\n");
- }
- mac->mac_table[i] = value;
-}
-
-/*
-** MACVALUE -- return uninterpreted value of a macro.
-**
-** Does fancy path searching.
-** The low level counterpart is macget.
-**
-** Parameters:
-** n -- the name of the macro.
-** e -- envelope in which to start looking for the macro.
-**
-** Returns:
-** The value of n.
-**
-** Side Effects:
-** none.
-*/
-
-char *
-macvalue(n, e)
- int n;
- register ENVELOPE *e;
-{
- n = bitidx(n);
- if (e != NULL && e->e_mci != NULL)
- {
- register char *p = e->e_mci->mci_macro.mac_table[n];
-
- if (p != NULL)
- return p;
- }
- while (e != NULL)
- {
- register char *p = e->e_macro.mac_table[n];
-
- if (p != NULL)
- return p;
- if (e == e->e_parent)
- break;
- e = e->e_parent;
- }
- return GlobalMacros.mac_table[n];
-}
-/*
-** MACNAME -- return the name of a macro given its internal id
-**
-** Parameter:
-** n -- the id of the macro
-**
-** Returns:
-** The name of n.
-**
-** Side Effects:
-** none.
-*/
-
-char *
-macname(n)
- int n;
-{
- static char mbuf[2];
-
- n = bitidx(n);
- if (bitset(0200, n))
- {
- char *p = MacroName[n];
-
- if (p != NULL)
- return p;
- return "***UNDEFINED MACRO***";
- }
- mbuf[0] = n;
- mbuf[1] = '\0';
- return mbuf;
-}
-/*
-** MACID_PARSE -- return id of macro identified by its name
-**
-** Parameters:
-** p -- pointer to name string -- either a single
-** character or {name}.
-** ep -- filled in with the pointer to the byte
-** after the name.
-**
-** Returns:
-** 0 -- An error was detected.
-** 1..255 -- The internal id code for this macro.
-**
-** Side Effects:
-** If this is a new macro name, a new id is allocated.
-** On error, syserr is called.
-*/
-
-int
-macid_parse(p, ep)
- register char *p;
- char **ep;
-{
- int mid;
- register char *bp;
- char mbuf[MAXMACNAMELEN + 1];
-
- if (tTd(35, 14))
- {
- sm_dprintf("macid(");
- xputs(sm_debug_file(), p);
- sm_dprintf(") => ");
- }
-
- if (*p == '\0' || (p[0] == '{' && p[1] == '}'))
- {
- syserr("Name required for macro/class");
- if (ep != NULL)
- *ep = p;
- if (tTd(35, 14))
- sm_dprintf("NULL\n");
- return 0;
- }
- if (*p != '{')
- {
- /* the macro is its own code */
- if (ep != NULL)
- *ep = p + 1;
- if (tTd(35, 14))
- sm_dprintf("%c\n", bitidx(*p));
- return bitidx(*p);
- }
- bp = mbuf;
- while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof mbuf - 1])
- {
- if (isascii(*p) && (isalnum(*p) || *p == '_'))
- *bp++ = *p;
- else
- syserr("Invalid macro/class character %c", *p);
- }
- *bp = '\0';
- mid = -1;
- if (*p == '\0')
- {
- syserr("Unbalanced { on %s", mbuf); /* missing } */
- }
- else if (*p != '}')
- {
- syserr("Macro/class name ({%s}) too long (%d chars max)",
- mbuf, (int) (sizeof mbuf - 1));
- }
- else if (mbuf[1] == '\0')
- {
- /* ${x} == $x */
- mid = bitidx(mbuf[0]);
- p++;
- }
- else
- {
- register STAB *s;
-
- s = stab(mbuf, ST_MACRO, ST_ENTER);
- if (s->s_macro != 0)
- mid = s->s_macro;
- else
- {
- if (NextMacroId > MAXMACROID)
- {
- syserr("Macro/class {%s}: too many long names",
- mbuf);
- s->s_macro = -1;
- }
- else
- {
- MacroName[NextMacroId] = s->s_name;
- s->s_macro = mid = NextMacroId++;
- }
- }
- p++;
- }
- if (ep != NULL)
- *ep = p;
- if (mid < 0 || mid > MAXMACROID)
- {
- syserr("Unable to assign macro/class ID (mid = 0x%x)", mid);
- if (tTd(35, 14))
- sm_dprintf("NULL\n");
- return 0;
- }
- if (tTd(35, 14))
- sm_dprintf("0x%x\n", mid);
- return mid;
-}
-/*
-** WORDINCLASS -- tell if a word is in a specific class
-**
-** Parameters:
-** str -- the name of the word to look up.
-** cl -- the class name.
-**
-** Returns:
-** true if str can be found in cl.
-** false otherwise.
-*/
-
-bool
-wordinclass(str, cl)
- char *str;
- int cl;
-{
- register STAB *s;
-
- s = stab(str, ST_CLASS, ST_FIND);
- return s != NULL && bitnset(bitidx(cl), s->s_class);
-}