postconf_lookup.c revision 1.4
1/* $NetBSD: postconf_lookup.c,v 1.4 2022/10/08 16:12:47 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/* Pointer to user-supplied buffer; must not be null. 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/* Wietse Venema 80/* Google, Inc. 81/* 111 8th Avenue 82/* New York, NY 10011, USA 83/*--*/ 84 85/* System library. */ 86 87#include <sys_defs.h> 88#include <string.h> 89 90/* Utility library. */ 91 92#include <msg.h> 93#include <mymalloc.h> 94#include <vstring.h> 95#include <dict.h> 96#include <stringops.h> 97#include <mac_expand.h> 98 99/* Global library. */ 100 101#include <mail_conf.h> 102 103/* Application-specific. */ 104 105#include <postconf.h> 106 107#define STR(x) vstring_str(x) 108 109/* pcf_lookup_parameter_value - look up specific parameter value */ 110 111const char *pcf_lookup_parameter_value(int mode, const char *name, 112 PCF_MASTER_ENT *local_scope, 113 PCF_PARAM_NODE *node) 114{ 115 const char *value = 0; 116 117#define LOOKUP(dict, name) ((dict) ? dict_get((dict), (name)) : 0) 118 119 /* 120 * Local name=value entries in master.cf take precedence over global 121 * name=value entries in main.cf. Built-in defaults have the lowest 122 * precedence. 123 */ 124 if ((mode & PCF_SHOW_DEFS) != 0 125 || ((local_scope == 0 126 || ((value = LOOKUP(local_scope->ro_params, name)) == 0 127 && (value = LOOKUP(local_scope->all_params, name)) == 0)) 128 && (value = dict_lookup(CONFIG_DICT, name)) == 0 129 && (mode & PCF_SHOW_NONDEF) == 0)) { 130 if (node != 0 || (node = PCF_PARAM_TABLE_FIND(pcf_param_table, name)) != 0) 131 value = pcf_convert_param_node(PCF_SHOW_DEFS, name, node); 132 } 133 return (value); 134} 135 136 /* 137 * Data structure to pass private state while recursively expanding $name in 138 * parameter values. 139 */ 140typedef struct { 141 int mode; 142 PCF_MASTER_ENT *local_scope; 143} PCF_EVAL_CTX; 144 145/* pcf_lookup_parameter_value_wrapper - macro parser call-back routine */ 146 147static const char *pcf_lookup_parameter_value_wrapper(const char *key, 148 int unused_type, 149 void *context) 150{ 151 PCF_EVAL_CTX *cp = (PCF_EVAL_CTX *) context; 152 153 return (pcf_lookup_parameter_value(cp->mode, key, cp->local_scope, 154 (PCF_PARAM_NODE *) 0)); 155} 156 157/* pcf_expand_parameter_value - expand $name in parameter value */ 158 159char *pcf_expand_parameter_value(VSTRING *buf, int mode, const char *value, 160 PCF_MASTER_ENT *local_scope) 161{ 162 const char *myname = "pcf_expand_parameter_value"; 163 int status; 164 PCF_EVAL_CTX eval_ctx; 165 166 /* 167 * Sanity check. 168 */ 169 if (buf == 0) 170 msg_panic("%s: null buffer pointer", myname); 171 172 /* 173 * Expand macros recursively. 174 * 175 * When expanding $name in "postconf -n" parameter values, don't limit the 176 * search to only non-default parameter values. 177 * 178 * When expanding $name in "postconf -d" parameter values, do limit the 179 * search to only default parameter values. 180 */ 181#define DONT_FILTER (char *) 0 182 183 eval_ctx.mode = (mode & ~PCF_SHOW_NONDEF); 184 eval_ctx.local_scope = local_scope; 185 status = mac_expand(buf, value, MAC_EXP_FLAG_RECURSE, DONT_FILTER, 186 pcf_lookup_parameter_value_wrapper, (void *) &eval_ctx); 187 if (status & MAC_PARSE_ERROR) 188 msg_fatal("macro processing error"); 189 if (msg_verbose > 1) { 190 if (strcmp(value, STR(buf)) != 0) 191 msg_info("%s: expand %s -> %s", myname, value, STR(buf)); 192 else 193 msg_info("%s: const %s", myname, value); 194 } 195 return (STR(buf)); 196} 197