#include <sys_defs.h>
#include <string.h>
#include <msg.h>
#include <mymalloc.h>
#include <htable.h>
#include <mac_expand.h>
#include <stringops.h>
#include <mail_conf.h>
#include <mail_params.h>
#include <postconf.h>
static HTABLE *rest_class_table;
#define STR(x) vstring_str(x)
#define NO_SCAN_RESULT ((VSTRING *) 0)
#define NO_SCAN_FILTER ((char *) 0)
#define NO_SCAN_MODE (0)
#define SCAN_USER_PARAMETER_VALUE(value, local_scope) do { \
(void) mac_expand(NO_SCAN_RESULT, (value), MAC_EXP_FLAG_SCAN, \
NO_SCAN_FILTER, flag_user_parameter, ((char *) (local_scope))); \
} while (0)
#define FLAG_USER_PARAMETER(name, local_scope) do { \
flag_user_parameter((name), NO_SCAN_MODE, ((char *) (local_scope))); \
} while (0)
static const char *convert_user_parameter(char *unused_ptr)
{
return ("");
}
static const char *flag_user_parameter(const char *mac_name,
int unused_mode,
char *context)
{
PC_MASTER_ENT *local_scope = (PC_MASTER_ENT *) context;
if (local_scope && dict_get(local_scope->all_params, mac_name)) {
if (PC_PARAM_TABLE_LOCATE(local_scope->valid_names, mac_name) == 0)
PC_PARAM_TABLE_ENTER(local_scope->valid_names, mac_name,
PC_PARAM_FLAG_USER, PC_PARAM_NO_DATA,
convert_user_parameter);
} else if (mail_conf_lookup(mac_name) != 0) {
if (PC_PARAM_TABLE_LOCATE(param_table, mac_name) == 0)
PC_PARAM_TABLE_ENTER(param_table, mac_name, PC_PARAM_FLAG_USER,
PC_PARAM_NO_DATA, convert_user_parameter);
}
return (0);
}
static const char *pc_lookup_eval(const char *dict_name, const char *name)
{
const char *value;
#define RECURSIVE 1
if ((value = dict_lookup(dict_name, name)) != 0)
value = dict_eval(dict_name, value, RECURSIVE);
return (value);
}
static void scan_user_parameter_namespace(const char *dict_name,
PC_MASTER_ENT *local_scope)
{
const char *myname = "scan_user_parameter_namespace";
const char *class_list;
char *saved_class_list;
char *cp;
DICT *dict;
char *param_name;
int how;
const char *cparam_name;
const char *cparam_value;
PC_PARAM_NODE *node;
if ((class_list = pc_lookup_eval(dict_name, VAR_REST_CLASSES)) != 0) {
cp = saved_class_list = mystrdup(class_list);
while ((param_name = mystrtok(&cp, ", \t\r\n")) != 0) {
if (local_scope == 0
&& htable_locate(rest_class_table, param_name) == 0)
htable_enter(rest_class_table, param_name, "");
FLAG_USER_PARAMETER(param_name, local_scope);
}
myfree(saved_class_list);
}
if ((dict = dict_handle(dict_name)) == 0)
msg_panic("%s: parameter dictionary %s not found",
myname, dict_name);
if (dict->sequence == 0)
msg_panic("%s: parameter dictionary %s has no iterator",
myname, dict_name);
for (how = DICT_SEQ_FUN_FIRST;
dict->sequence(dict, how, &cparam_name, &cparam_value) == 0;
how = DICT_SEQ_FUN_NEXT) {
if (local_scope != 0
&& PC_PARAM_TABLE_LOCATE(local_scope->valid_names, cparam_name) == 0
&& htable_locate(rest_class_table, cparam_name) != 0)
PC_PARAM_TABLE_ENTER(local_scope->valid_names, cparam_name,
PC_PARAM_FLAG_USER, PC_PARAM_NO_DATA,
convert_user_parameter);
if ((node = PC_PARAM_TABLE_FIND(param_table, cparam_name)) != 0
&& PC_RAW_PARAMETER(node))
continue;
SCAN_USER_PARAMETER_VALUE(cparam_value, local_scope);
#ifdef LEGACY_DBMS_SUPPORT
register_dbms_parameters(cparam_value, flag_user_parameter,
local_scope);
#endif
}
}
static void scan_default_parameter_values(HTABLE *valid_params,
const char *dict_name,
PC_MASTER_ENT *local_scope)
{
const char *myname = "scan_default_parameter_values";
PC_PARAM_INFO **list;
PC_PARAM_INFO **ht;
const char *param_value;
list = PC_PARAM_TABLE_LIST(valid_params);
for (ht = list; *ht; ht++) {
if (PC_RAW_PARAMETER(PC_PARAM_INFO_NODE(*ht)))
continue;
if (dict_lookup(dict_name, PC_PARAM_INFO_NAME(*ht)))
continue;
if ((param_value = convert_param_node(SHOW_DEFS, PC_PARAM_INFO_NAME(*ht),
PC_PARAM_INFO_NODE(*ht))) == 0)
msg_panic("%s: parameter %s has no default value",
myname, PC_PARAM_INFO_NAME(*ht));
SCAN_USER_PARAMETER_VALUE(param_value, local_scope);
}
myfree((char *) list);
}
void register_user_parameters(void)
{
const char *myname = "register_user_parameters";
PC_MASTER_ENT *masterp;
ARGV *argv;
char *arg;
int field;
char *saved_arg;
char *param_name;
char *param_value;
DICT *dict;
if (param_table == 0)
msg_panic("%s: global parameter table is not initialized", myname);
if (master_table == 0)
msg_panic("%s: master table is not initialized", myname);
if (rest_class_table != 0)
msg_panic("%s: restriction class table is already initialized", myname);
rest_class_table = htable_create(1);
scan_default_parameter_values(param_table, CONFIG_DICT, (PC_MASTER_ENT *) 0);
scan_user_parameter_namespace(CONFIG_DICT, (PC_MASTER_ENT *) 0);
for (masterp = master_table; (argv = masterp->argv) != 0; masterp++) {
for (field = PC_MASTER_MIN_FIELDS; argv->argv[field] != 0; field++) {
arg = argv->argv[field];
if (arg[0] != '-' || strcmp(arg, "--") == 0)
break;
if (strcmp(arg, "-o") == 0 && (arg = argv->argv[field + 1]) != 0) {
saved_arg = mystrdup(arg);
if (split_nameval(saved_arg, ¶m_name, ¶m_value) == 0)
dict_update(masterp->name_space, param_name, param_value);
myfree(saved_arg);
field += 1;
}
}
if ((dict = dict_handle(masterp->name_space)) != 0) {
masterp->all_params = dict;
masterp->valid_names = htable_create(1);
scan_user_parameter_namespace(masterp->name_space, masterp);
}
}
}