1 /* $NetBSD: postconf_main.c,v 1.2 2017/02/14 01:16:46 christos 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 /* Wietse Venema 70 /* Google, Inc. 71 /* 111 8th Avenue 72 /* New York, NY 10011, USA 73 /*--*/ 74 75 /* System library. */ 76 77 #include <sys_defs.h> 78 #include <stdarg.h> 79 #include <stdlib.h> 80 #include <string.h> 81 82 /* Utility library. */ 83 84 #include <msg.h> 85 #include <mymalloc.h> 86 #include <vstream.h> 87 #include <vstring.h> 88 #include <readlline.h> 89 #include <dict.h> 90 #include <stringops.h> 91 #include <htable.h> 92 #include <mac_expand.h> 93 94 /* Global library. */ 95 96 #include <mail_params.h> 97 #include <mail_conf.h> 98 99 /* Application-specific. */ 100 101 #include <postconf.h> 102 103 #define STR(x) vstring_str(x) 104 105 /* pcf_read_parameters - read parameter info from file */ 106 107 void pcf_read_parameters(void) 108 { 109 char *path; 110 111 /* 112 * A direct rip-off of mail_conf_read(). XXX Avoid code duplication by 113 * better code decomposition. 114 */ 115 pcf_set_config_dir(); 116 path = concatenate(var_config_dir, "/", MAIN_CONF_FILE, (char *) 0); 117 if (dict_load_file_xt(CONFIG_DICT, path) == 0) 118 msg_fatal("open %s: %m", path); 119 myfree(path); 120 } 121 122 /* pcf_set_parameters - add or override name=value pairs */ 123 124 void pcf_set_parameters(char **name_val_array) 125 { 126 char *name, *value, *junk; 127 const char *err; 128 char **cpp; 129 130 for (cpp = name_val_array; *cpp; cpp++) { 131 junk = mystrdup(*cpp); 132 if ((err = split_nameval(junk, &name, &value)) != 0) 133 msg_fatal("invalid parameter override: %s: %s", *cpp, err); 134 mail_conf_update(name, value); 135 myfree(junk); 136 } 137 } 138 139 /* pcf_print_parameter - show specific parameter */ 140 141 static void pcf_print_parameter(VSTREAM *fp, int mode, const char *name, 142 PCF_PARAM_NODE *node) 143 { 144 const char *value; 145 146 /* 147 * Use the default or actual value. 148 */ 149 value = pcf_lookup_parameter_value(mode, name, (PCF_MASTER_ENT *) 0, node); 150 151 /* 152 * Optionally expand $name in the parameter value. Print the result with 153 * or without the name= prefix. 154 */ 155 if (value != 0) { 156 if (mode & PCF_HIDE_VALUE) { 157 pcf_print_line(fp, mode, "%s\n", name); 158 } else { 159 if ((mode & PCF_SHOW_EVAL) != 0 && PCF_RAW_PARAMETER(node) == 0) 160 value = pcf_expand_parameter_value((VSTRING *) 0, mode, value, 161 (PCF_MASTER_ENT *) 0); 162 if ((mode & PCF_HIDE_NAME) == 0) { 163 pcf_print_line(fp, mode, "%s = %s\n", name, value); 164 } else { 165 pcf_print_line(fp, mode, "%s\n", value); 166 } 167 } 168 if (msg_verbose) 169 vstream_fflush(fp); 170 } 171 } 172 173 /* pcf_comp_names - qsort helper */ 174 175 static int pcf_comp_names(const void *a, const void *b) 176 { 177 PCF_PARAM_INFO **ap = (PCF_PARAM_INFO **) a; 178 PCF_PARAM_INFO **bp = (PCF_PARAM_INFO **) b; 179 180 return (strcmp(PCF_PARAM_INFO_NAME(ap[0]), 181 PCF_PARAM_INFO_NAME(bp[0]))); 182 } 183 184 /* pcf_show_parameters - show parameter info */ 185 186 void pcf_show_parameters(VSTREAM *fp, int mode, int param_class, char **names) 187 { 188 PCF_PARAM_INFO **list; 189 PCF_PARAM_INFO **ht; 190 char **namep; 191 PCF_PARAM_NODE *node; 192 193 /* 194 * Show all parameters. 195 */ 196 if (*names == 0) { 197 list = PCF_PARAM_TABLE_LIST(pcf_param_table); 198 qsort((void *) list, pcf_param_table->used, sizeof(*list), 199 pcf_comp_names); 200 for (ht = list; *ht; ht++) 201 if (param_class & PCF_PARAM_INFO_NODE(*ht)->flags) 202 pcf_print_parameter(fp, mode, PCF_PARAM_INFO_NAME(*ht), 203 PCF_PARAM_INFO_NODE(*ht)); 204 myfree((void *) list); 205 return; 206 } 207 208 /* 209 * Show named parameters. 210 */ 211 for (namep = names; *namep; namep++) { 212 if ((node = PCF_PARAM_TABLE_FIND(pcf_param_table, *namep)) == 0) { 213 msg_warn("%s: unknown parameter", *namep); 214 } else { 215 pcf_print_parameter(fp, mode, *namep, node); 216 } 217 } 218 } 219