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