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