summaryrefslogtreecommitdiffstats
path: root/src/postconf/postconf_lookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/postconf/postconf_lookup.c')
-rw-r--r--src/postconf/postconf_lookup.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/postconf/postconf_lookup.c b/src/postconf/postconf_lookup.c
new file mode 100644
index 0000000..5185681
--- /dev/null
+++ b/src/postconf/postconf_lookup.c
@@ -0,0 +1,194 @@
+/*++
+/* NAME
+/* postconf_lookup 3
+/* SUMMARY
+/* parameter lookup routines
+/* SYNOPSIS
+/* #include <postconf.h>
+/*
+/* const char *pcf_lookup_parameter_value(mode, name, local_scope, node)
+/* int mode;
+/* const char *name;
+/* PCF_MASTER_ENT *local_scope;
+/* PCF_PARAM_NODE *node;
+/*
+/* char *pcf_expand_parameter_value(buf, mode, value, local_scope)
+/* VSTRING *buf;
+/* int mode;
+/* const char *value;
+/* PCF_MASTER_ENT *local_scope;
+/* DESCRIPTION
+/* These functions perform parameter value lookups. The order
+/* of decreasing precedence is:
+/* .IP \(bu
+/* Search name=value parameter settings in master.cf. These
+/* lookups are disabled with the PCF_SHOW_DEFS flag.
+/* .IP \(bu
+/* Search name=value parameter settings in main.cf. These
+/* lookups are disabled with the PCF_SHOW_DEFS flag.
+/* .IP \(bu
+/* Search built-in default parameter settings. These lookups
+/* are disabled with the PCF_SHOW_NONDEF flag.
+/* .PP
+/* pcf_lookup_parameter_value() looks up the value for the
+/* named parameter, and returns null if the name was not found.
+/*
+/* pcf_expand_parameter_value() expands $name in the specified
+/* parameter value. This function ignores the PCF_SHOW_NONDEF
+/* flag. The result value is a pointer to storage in a
+/* user-supplied buffer, or in a buffer that is overwritten
+/* with each call.
+/*
+/* Arguments:
+/* .IP buf
+/* Pointer to user-supplied buffer; must not be null.
+/* .IP mode
+/* Bit-wise OR of zero or one of the following (other flags
+/* are ignored):
+/* .RS
+/* .IP PCF_SHOW_DEFS
+/* Search built-in default parameter settings only.
+/* .IP PCF_SHOW_NONDEF
+/* Search local (master.cf) and global (main.cf) name=value
+/* parameter settings only.
+/* .RE
+/* .IP name
+/* The name of a parameter to be looked up.
+/* .IP value
+/* The parameter value where $name should be expanded.
+/* .IP local_scope
+/* Pointer to master.cf entry with local name=value settings,
+/* or a null pointer (i.e. no local parameter lookup).
+/* .IP node
+/* Global default value for the named parameter, or a null
+/* pointer (i.e. do the global default lookup anyway).
+/* DIAGNOSTICS
+/* Problems are reported to the standard error stream.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <vstring.h>
+#include <dict.h>
+#include <stringops.h>
+#include <mac_expand.h>
+
+/* Global library. */
+
+#include <mail_conf.h>
+
+/* Application-specific. */
+
+#include <postconf.h>
+
+#define STR(x) vstring_str(x)
+
+/* pcf_lookup_parameter_value - look up specific parameter value */
+
+const char *pcf_lookup_parameter_value(int mode, const char *name,
+ PCF_MASTER_ENT *local_scope,
+ PCF_PARAM_NODE *node)
+{
+ const char *value = 0;
+
+#define LOOKUP(dict, name) ((dict) ? dict_get((dict), (name)) : 0)
+
+ /*
+ * Local name=value entries in master.cf take precedence over global
+ * name=value entries in main.cf. Built-in defaults have the lowest
+ * precedence.
+ */
+ if ((mode & PCF_SHOW_DEFS) != 0
+ || ((local_scope == 0
+ || ((value = LOOKUP(local_scope->ro_params, name)) == 0
+ && (value = LOOKUP(local_scope->all_params, name)) == 0))
+ && (value = dict_lookup(CONFIG_DICT, name)) == 0
+ && (mode & PCF_SHOW_NONDEF) == 0)) {
+ if (node != 0 || (node = PCF_PARAM_TABLE_FIND(pcf_param_table, name)) != 0)
+ value = pcf_convert_param_node(PCF_SHOW_DEFS, name, node);
+ }
+ return (value);
+}
+
+ /*
+ * Data structure to pass private state while recursively expanding $name in
+ * parameter values.
+ */
+typedef struct {
+ int mode;
+ PCF_MASTER_ENT *local_scope;
+} PCF_EVAL_CTX;
+
+/* pcf_lookup_parameter_value_wrapper - macro parser call-back routine */
+
+static const char *pcf_lookup_parameter_value_wrapper(const char *key,
+ int unused_type,
+ void *context)
+{
+ PCF_EVAL_CTX *cp = (PCF_EVAL_CTX *) context;
+
+ return (pcf_lookup_parameter_value(cp->mode, key, cp->local_scope,
+ (PCF_PARAM_NODE *) 0));
+}
+
+/* pcf_expand_parameter_value - expand $name in parameter value */
+
+char *pcf_expand_parameter_value(VSTRING *buf, int mode, const char *value,
+ PCF_MASTER_ENT *local_scope)
+{
+ const char *myname = "pcf_expand_parameter_value";
+ int status;
+ PCF_EVAL_CTX eval_ctx;
+
+ /*
+ * Sanity check.
+ */
+ if (buf == 0)
+ msg_panic("%s: null buffer pointer", myname);
+
+ /*
+ * Expand macros recursively.
+ *
+ * When expanding $name in "postconf -n" parameter values, don't limit the
+ * search to only non-default parameter values.
+ *
+ * When expanding $name in "postconf -d" parameter values, do limit the
+ * search to only default parameter values.
+ */
+#define DONT_FILTER (char *) 0
+
+ eval_ctx.mode = (mode & ~PCF_SHOW_NONDEF);
+ eval_ctx.local_scope = local_scope;
+ status = mac_expand(buf, value, MAC_EXP_FLAG_RECURSE, DONT_FILTER,
+ pcf_lookup_parameter_value_wrapper, (void *) &eval_ctx);
+ if (status & MAC_PARSE_ERROR)
+ msg_fatal("macro processing error");
+ if (msg_verbose > 1) {
+ if (strcmp(value, STR(buf)) != 0)
+ msg_info("%s: expand %s -> %s", myname, value, STR(buf));
+ else
+ msg_info("%s: const %s", myname, value);
+ }
+ return (STR(buf));
+}