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