postconf_lookup.c revision 1.1
1/* $NetBSD: postconf_lookup.c,v 1.1 2013/09/25 19:06:33 tron Exp $ */ 2 3/*++ 4/* NAME 5/* postconf_lookup 3 6/* SUMMARY 7/* parameter lookup routines 8/* SYNOPSIS 9/* #include <postconf.h> 10/* 11/* const char *lookup_parameter_value(mode, name, local_scope, node) 12/* int mode; 13/* const char *name; 14/* PC_MASTER_ENT *local_scope; 15/* PC_PARAM_NODE *node; 16/* 17/* char *expand_parameter_value(buf, mode, value, local_scope) 18/* VSTRING *buf; 19/* int mode; 20/* const char *value; 21/* PC_MASTER_ENT *local_scope; 22/* DESCRIPTION 23/* These functions perform parameter value lookups. The order 24/* of decreasing precedence is: 25/* .IP \(bu 26/* Search name=value parameter settings in master.cf. 27/* These lookups are disabled with the SHOW_DEFS flag. 28/* .IP \(bu 29/* Search name=value parameter settings in main.cf. 30/* These lookups are disabled with the SHOW_DEFS flag. 31/* .IP \(bu 32/* Search built-in default parameter settings. These lookups 33/* are disabled with the SHOW_NONDEF flag. 34/* .PP 35/* lookup_parameter_value() looks up the value for the named 36/* parameter, and returns null if the name was not found. 37/* 38/* expand_parameter_value() expands $name in the specified 39/* parameter value. This function ignores the SHOW_NONDEF flag. 40/* The result value is a pointer to storage in a user-supplied 41/* buffer, or in a buffer that is overwritten with each call. 42/* 43/* Arguments: 44/* .IP buf 45/* Null buffer pointer, or pointer to user-supplied buffer. 46/* .IP mode 47/* Bit-wise OR of zero or one of the following (other flags 48/* are ignored): 49/* .RS 50/* .IP SHOW_DEFS 51/* Search built-in default parameter settings only. 52/* .IP SHOW_NONDEF 53/* Search local (master.cf) and global (main.cf) name=value 54/* parameter settings only. 55/* .RE 56/* .IP name 57/* The name of a parameter to be looked up. 58/* .IP value 59/* The parameter value where $name should be expanded. 60/* .IP local_scope 61/* Pointer to master.cf entry with local name=value settings, 62/* or a null pointer (i.e. no local parameter lookup). 63/* .IP node 64/* Global default value for the named parameter, or a null 65/* pointer (i.e. do the global default lookup anyway). 66/* DIAGNOSTICS 67/* Problems are reported to the standard error stream. 68/* LICENSE 69/* .ad 70/* .fi 71/* The Secure Mailer license must be distributed with this software. 72/* AUTHOR(S) 73/* Wietse Venema 74/* IBM T.J. Watson Research 75/* P.O. Box 704 76/* Yorktown Heights, NY 10598, USA 77/*--*/ 78 79/* System library. */ 80 81#include <sys_defs.h> 82#include <string.h> 83 84/* Utility library. */ 85 86#include <msg.h> 87#include <mymalloc.h> 88#include <vstring.h> 89#include <dict.h> 90#include <stringops.h> 91#include <mac_expand.h> 92 93/* Global library. */ 94 95#include <mail_conf.h> 96 97/* Application-specific. */ 98 99#include <postconf.h> 100 101#define STR(x) vstring_str(x) 102 103/* lookup_parameter_value - look up specific parameter value */ 104 105const char *lookup_parameter_value(int mode, const char *name, 106 PC_MASTER_ENT *local_scope, 107 PC_PARAM_NODE *node) 108{ 109 const char *value = 0; 110 111 /* 112 * Local name=value entries in master.cf take precedence over global 113 * name=value entries in main.cf. Built-in defaults have the lowest 114 * precedence. 115 */ 116 if ((mode & SHOW_DEFS) != 0 117 || ((local_scope == 0 || local_scope->all_params == 0 118 || (value = dict_get(local_scope->all_params, name)) == 0) 119 && (value = dict_lookup(CONFIG_DICT, name)) == 0 120 && (mode & SHOW_NONDEF) == 0)) { 121 if (node != 0 || (node = PC_PARAM_TABLE_FIND(param_table, name)) != 0) 122 value = convert_param_node(SHOW_DEFS, name, node); 123 } 124 return (value); 125} 126 127 /* 128 * Data structure to pass private state while recursively expanding $name in 129 * parameter values. 130 */ 131typedef struct { 132 int mode; 133 PC_MASTER_ENT *local_scope; 134} PC_EVAL_CTX; 135 136/* lookup_parameter_value_wrapper - macro parser call-back routine */ 137 138static const char *lookup_parameter_value_wrapper(const char *key, 139 int unused_type, 140 char *context) 141{ 142 PC_EVAL_CTX *cp = (PC_EVAL_CTX *) context; 143 144 return (lookup_parameter_value(cp->mode, key, cp->local_scope, 145 (PC_PARAM_NODE *) 0)); 146} 147 148/* expand_parameter_value - expand $name in parameter value */ 149 150char *expand_parameter_value(VSTRING *buf, int mode, const char *value, 151 PC_MASTER_ENT *local_scope) 152{ 153 const char *myname = "expand_parameter_value"; 154 static VSTRING *local_buf; 155 int status; 156 PC_EVAL_CTX eval_ctx; 157 158 /* 159 * Initialize. 160 */ 161 if (buf == 0) { 162 if (local_buf == 0) 163 local_buf = vstring_alloc(10); 164 buf = local_buf; 165 } 166 167 /* 168 * Expand macros recursively. 169 * 170 * When expanding $name in "postconf -n" parameter values, don't limit the 171 * search to only non-default parameter values. 172 * 173 * When expanding $name in "postconf -d" parameter values, do limit the 174 * search to only default parameter values. 175 */ 176#define DONT_FILTER (char *) 0 177 178 eval_ctx.mode = (mode & ~SHOW_NONDEF); 179 eval_ctx.local_scope = local_scope; 180 status = mac_expand(buf, value, MAC_EXP_FLAG_RECURSE, DONT_FILTER, 181 lookup_parameter_value_wrapper, (char *) &eval_ctx); 182 if (status & MAC_PARSE_ERROR) 183 msg_fatal("macro processing error"); 184 if (msg_verbose > 1) { 185 if (strcmp(value, STR(buf)) != 0) 186 msg_info("%s: expand %s -> %s", myname, value, STR(buf)); 187 else 188 msg_info("%s: const %s", myname, value); 189 } 190 return (STR(buf)); 191} 192