1/*++ 2/* NAME 3/* postconf_main 3 4/* SUMMARY 5/* basic support for main.cf 6/* SYNOPSIS 7/* #include <postconf.h> 8/* 9/* void pcf_read_parameters() 10/* 11/* void pcf_show_parameters(fp, mode, param_class, names) 12/* VSTREAM *fp; 13/* int mode; 14/* int param_class; 15/* char **names; 16/* DESCRIPTION 17/* pcf_read_parameters() reads parameters from main.cf. 18/* 19/* pcf_set_parameters() takes an array of \fIname=value\fR 20/* pairs and overrides settings read with pcf_read_parameters(). 21/* 22/* pcf_show_parameters() writes main.cf parameters to the 23/* specified output stream. 24/* 25/* Arguments: 26/* .IP fp 27/* Output stream. 28/* .IP mode 29/* Bit-wise OR of zero or more of the following: 30/* .RS 31/* .IP PCF_FOLD_LINE 32/* Fold long lines. 33/* .IP PCF_SHOW_DEFS 34/* Output default parameter values. 35/* .IP PCF_SHOW_NONDEF 36/* Output explicit settings only. 37/* .IP PCF_HIDE_NAME 38/* Output parameter values without the "name =" prefix. 39/* .IP PCF_SHOW_EVAL 40/* Expand $name in parameter values. 41/* .RE 42/* .IP param_class 43/* Bit-wise OR of one or more of the following: 44/* .RS 45/* .IP PCF_PARAM_FLAG_BUILTIN 46/* Show built-in parameters. 47/* .IP PCF_PARAM_FLAG_SERVICE 48/* Show service-defined parameters. 49/* .IP PCF_PARAM_FLAG_USER 50/* Show user-defined parameters. 51/* .RE 52/* .IP names 53/* List of zero or more parameter names. If the list is empty, 54/* output all parameters. 55/* DIAGNOSTICS 56/* Problems are reported to the standard error stream. 57/* LICENSE 58/* .ad 59/* .fi 60/* The Secure Mailer license must be distributed with this software. 61/* AUTHOR(S) 62/* Wietse Venema 63/* IBM T.J. Watson Research 64/* P.O. Box 704 65/* Yorktown Heights, NY 10598, USA 66/*--*/ 67 68/* System library. */ 69 70#include <sys_defs.h> 71#include <stdarg.h> 72#include <stdlib.h> 73#include <string.h> 74 75/* Utility library. */ 76 77#include <msg.h> 78#include <mymalloc.h> 79#include <vstream.h> 80#include <vstring.h> 81#include <readlline.h> 82#include <dict.h> 83#include <stringops.h> 84#include <htable.h> 85#include <mac_expand.h> 86 87/* Global library. */ 88 89#include <mail_params.h> 90#include <mail_conf.h> 91 92/* Application-specific. */ 93 94#include <postconf.h> 95 96#define STR(x) vstring_str(x) 97 98/* pcf_read_parameters - read parameter info from file */ 99 100void pcf_read_parameters(void) 101{ 102 char *path; 103 104 /* 105 * A direct rip-off of mail_conf_read(). XXX Avoid code duplication by 106 * better code decomposition. 107 */ 108 pcf_set_config_dir(); 109 path = concatenate(var_config_dir, "/", MAIN_CONF_FILE, (char *) 0); 110 if (dict_load_file_xt(CONFIG_DICT, path) == 0) 111 msg_fatal("open %s: %m", path); 112 myfree(path); 113} 114 115/* pcf_set_parameters - add or override name=value pairs */ 116 117void pcf_set_parameters(char **name_val_array) 118{ 119 char *name, *value, *junk; 120 const char *err; 121 char **cpp; 122 123 for (cpp = name_val_array; *cpp; cpp++) { 124 junk = mystrdup(*cpp); 125 if ((err = split_nameval(junk, &name, &value)) != 0) 126 msg_fatal("invalid parameter override: %s: %s", *cpp, err); 127 mail_conf_update(name, value); 128 myfree(junk); 129 } 130} 131 132/* pcf_print_parameter - show specific parameter */ 133 134static void pcf_print_parameter(VSTREAM *fp, int mode, const char *name, 135 PCF_PARAM_NODE *node) 136{ 137 const char *value; 138 139 /* 140 * Use the default or actual value. 141 */ 142 value = pcf_lookup_parameter_value(mode, name, (PCF_MASTER_ENT *) 0, node); 143 144 /* 145 * Optionally expand $name in the parameter value. Print the result with 146 * or without the name= prefix. 147 */ 148 if (value != 0) { 149 if ((mode & PCF_SHOW_EVAL) != 0 && PCF_RAW_PARAMETER(node) == 0) 150 value = pcf_expand_parameter_value((VSTRING *) 0, mode, value, 151 (PCF_MASTER_ENT *) 0); 152 if ((mode & PCF_HIDE_NAME) == 0) { 153 pcf_print_line(fp, mode, "%s = %s\n", name, value); 154 } else { 155 pcf_print_line(fp, mode, "%s\n", value); 156 } 157 if (msg_verbose) 158 vstream_fflush(fp); 159 } 160} 161 162/* pcf_comp_names - qsort helper */ 163 164static int pcf_comp_names(const void *a, const void *b) 165{ 166 PCF_PARAM_INFO **ap = (PCF_PARAM_INFO **) a; 167 PCF_PARAM_INFO **bp = (PCF_PARAM_INFO **) b; 168 169 return (strcmp(PCF_PARAM_INFO_NAME(ap[0]), 170 PCF_PARAM_INFO_NAME(bp[0]))); 171} 172 173/* pcf_show_parameters - show parameter info */ 174 175void pcf_show_parameters(VSTREAM *fp, int mode, int param_class, char **names) 176{ 177 PCF_PARAM_INFO **list; 178 PCF_PARAM_INFO **ht; 179 char **namep; 180 PCF_PARAM_NODE *node; 181 182 /* 183 * Show all parameters. 184 */ 185 if (*names == 0) { 186 list = PCF_PARAM_TABLE_LIST(pcf_param_table); 187 qsort((char *) list, pcf_param_table->used, sizeof(*list), 188 pcf_comp_names); 189 for (ht = list; *ht; ht++) 190 if (param_class & PCF_PARAM_INFO_NODE(*ht)->flags) 191 pcf_print_parameter(fp, mode, PCF_PARAM_INFO_NAME(*ht), 192 PCF_PARAM_INFO_NODE(*ht)); 193 myfree((char *) list); 194 return; 195 } 196 197 /* 198 * Show named parameters. 199 */ 200 for (namep = names; *namep; namep++) { 201 if ((node = PCF_PARAM_TABLE_FIND(pcf_param_table, *namep)) == 0) { 202 msg_warn("%s: unknown parameter", *namep); 203 } else { 204 pcf_print_parameter(fp, mode, *namep, node); 205 } 206 } 207} 208