macro.c revision 7800901e60d340b6af88e94a2149805dcfcaaf56
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright (c) 1998-2001, 2003, 2006, 2007 Sendmail, Inc. and its suppliers.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright (c) 1988, 1993
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The Regents of the University of California. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * By using this file, you agree to the terms and conditions set
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * forth in the LICENSE file which can be found at the top level of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the sendmail distribution.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#pragma ident "%Z%%M% %I% %E% SMI"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteSM_RCSID("@(#)$Id: macro.c,v 8.107 2007/08/06 22:29:02 ca Exp $")
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* MAXMACROID != (BITMAPBITS - 1) */
042f029e72a2d7a92c989ad0d0570f7b21efa2aaAlexander Stetsenkostatic char *MacroName[MAXMACROID + 1]; /* macro id to name table */
6ac72a9ce9da39bd0abf3111fb48494c6d892613Alexander Stetsenko** Codes for long named macros.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** See also macname():
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if not ASCII printable, look up the name *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (n <= 0x20 || n > 0x7f)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** First use 1 to NEXTMACROID_L, then use NEXTMACROID_H to MAXMACROID.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* table for next id in non-printable ASCII range: disallow some value */
a49dc89305dba244dc67270b5afddcf7da3e36cfSaso Kiselkov (mid < NEXTMACROID_L) ? (NextMIdTable[mid]) : \
042f029e72a2d7a92c989ad0d0570f7b21efa2aaAlexander Stetsenko ((mid < NEXTMACROID_H) ? NEXTMACROID_H : (mid + 1)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint NextMacroId = 1; /* codes for long named macros */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* see sendmail.h: Special characters in rewriting rules. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else /* _FFR_MORE_MACROS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint NextMacroId = 0240; /* codes for long named macros */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _FFR_MORE_MACROS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** INITMACROS -- initialize the macro system
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** This just involves defining some macros that are actually
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte** used internally as metasymbols to be themselves.
40c3e8ff0f3a541e3a203404d3a5dc7eb0f5aee8John Forte** Parameters:
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte** Side Effects:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** initializes several macros to be themselves.
6ac72a9ce9da39bd0abf3111fb48494c6d892613Alexander Stetsenko /* LHS pattern matching characters */
042f029e72a2d7a92c989ad0d0570f7b21efa2aaAlexander Stetsenko { '*', MATCHZANY }, { '+', MATCHANY }, { '-', MATCHONE },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* these are RHS metasymbols */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { '#', CANONNET }, { '@', CANONHOST }, { ':', CANONUSER },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* the conditional operations */
91159e90831fc9243576f2ec1a483b3bb462bcf4John Forte { '?', CONDIF }, { '|', CONDELSE }, { '.', CONDFI },
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto /* the hostname lookup characters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* miscellaneous control characters */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte macdefine(&e->e_macro, A_TEMP, m->metaname, buf);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* set defaults for some macros sendmail will use later */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto macdefine(&e->e_macro, A_PERM, 'n', "MAILER-DAEMON");
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* set up external names for some internal macros */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /*XXX should probably add equivalents for all short macros here XXX*/
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto** EXPAND/DOEXPAND -- macro expand a string using $x escapes.
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto** After expansion, the expansion will be in external form (that is,
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto** there will be no sendmail metacharacters and METAQUOTEs will have
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto** been stripped out).
427fcaf873956aad428be801380a44e59d38b8b5tim szeto** Parameters:
427fcaf873956aad428be801380a44e59d38b8b5tim szeto** s -- the string to expand.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto** buf -- the place to put the expansion.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto** bufsize -- the size of the buffer.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto** explevel -- the depth of expansion (doexpand only)
427fcaf873956aad428be801380a44e59d38b8b5tim szeto** e -- envelope in which to work.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Side Effects:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void doexpand __P(( char *, char *, size_t, int, ENVELOPE *));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bool skipping; /* set if conditionally skipping output */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bool quotenext; /* quote the following character */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ** Check for non-ordinary (special?) character.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ** 'q' will be the interpolated quantity.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte c = *s & 0377;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte c = *++s & 0377;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* XXX: error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* XXX: error */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (c != '\0')
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* next octet completely quoted */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ** Interpolate q or output one character
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy to end of q or max space remaining in buf */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((c = *q++) != '\0' &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* check for any sendmail metacharacters */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* give quoted characters a free ride */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* recurse as appropriate */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy results out */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* leave in internal form */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto** MACDEFINE -- bind a macro name to a value
427fcaf873956aad428be801380a44e59d38b8b5tim szeto** Set a macro to a value, with fancy storage management.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** macdefine will make a copy of the value, if required,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** and will ensure that the storage for the previous value
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** is not leaked.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Parameters:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** mac -- Macro table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** vclass -- storage class of 'value', ignored if value==NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** A_HEAP means that the value was allocated by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** malloc, and that macdefine owns the storage.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** A_TEMP means that value points to temporary storage,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** and thus macdefine needs to make a copy.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** A_PERM means that value points to storage that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** will remain allocated and unchanged for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** at least the lifetime of mac. Use A_PERM if:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** -- value == NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** -- value points to a string literal,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** -- value was allocated from mac->mac_rpool
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** or (in the case of an envelope macro)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** from e->e_rpool,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** -- in the case of an envelope macro,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** value is a string member of the envelope
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** such as e->e_sender.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** id -- Macro id. This is a single character macro name
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** such as 'g', or a value returned by macid().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** value -- Macro value: either NULL, or a string.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortemacdefine_tagged(mac, vclass, id, value, file, line, grp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else /* SM_HEAP_CHECK */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* SM_HEAP_CHECK */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* SM_HEAP_CHECK */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mac->mac_table[id] == NULL ? "" : "re", macname(id));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newvalue = sm_strdup_tagged_x(value, file, line, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else /* SM_HEAP_CHECK */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* SM_HEAP_CHECK */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte newvalue = sm_rpool_strdup_x(mac->mac_rpool, value);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _FFR_RESET_MACRO_GLOBALS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** MACSET -- set a named macro to a value (low level)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** No fancy storage management; the caller takes full responsibility.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Often used with macget; see also macdefine.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Parameters:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** mac -- Macro table.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** i -- Macro name, specified as an integer offset.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** value -- Macro value: either NULL, or a string.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i < 0 || i > MAXMACROID)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** MACVALUE -- return uninterpreted value of a macro.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Does fancy path searching.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** The low level counterpart is macget.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Parameters:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** n -- the name of the macro.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** e -- envelope in which to start looking for the macro.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** The value of n.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Side Effects:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (e != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** MACNAME -- return the name of a macro given its internal id
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Parameter:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** n -- the id of the macro
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** The name of n.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Side Effects:
4b31676f89e318c11400fc0c4defc802da29222fsrivijitha dugganapalli** Not thread-safe.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n = (int)(unsigned char)n;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return "***OUT OF RANGE MACRO***";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if not ASCII printable, look up the name */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *p = MacroName[n];
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto return "***UNDEFINED MACRO***";
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto /* if in the ASCII graphic range, just return the id directly */
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** MACID_PARSE -- return id of macro identified by its name
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** Parameters:
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** p -- pointer to name string -- either a single
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** character or {name}.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** ep -- filled in with the pointer to the byte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** after the name.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** 0 -- An error was detected.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** 1..MAXMACROID -- The internal id code for this macro.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** Side Effects:
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** If this is a new macro name, a new id is allocated.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto** On error, syserr is called.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if (*p != '{')
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto /* the macro is its own code */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1])
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (*p == '\0')
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syserr("Unbalanced { on %s", mbuf); /* missing } */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (*p != '}')
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syserr("Macro/class name ({%s}) too long (%d chars max)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ${x} == $x */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syserr("Unable to assign macro/class ID (mid = 0x%x)", mid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** WORDINCLASS -- tell if a word is in a specific class
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** Parameters:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** str -- the name of the word to look up.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** cl -- the class name.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** true if str can be found in cl.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte** false otherwise.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return s != NULL && bitnset(bitidx(cl), s->s_class);