1 /* $NetBSD: postconf_main.c,v 1.3 2022/10/08 16:12:47 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 static VSTRING *exp_buf = 0; 145 const char *value; 146 147 if (exp_buf == 0) 148 exp_buf = vstring_alloc(100); 149 150 /* 151 * Use the default or actual value. 152 */ 153 value = pcf_lookup_parameter_value(mode, name, (PCF_MASTER_ENT *) 0, node); 154 155 /* 156 * Optionally expand $name in the parameter value. Print the result with 157 * or without the name= prefix. 158 */ 159 if (value != 0) { 160 if (mode & PCF_HIDE_VALUE) { 161 pcf_print_line(fp, mode, "%s\n", name); 162 } else { 163 if ((mode & PCF_SHOW_EVAL) != 0 && PCF_RAW_PARAMETER(node) == 0) 164 value = pcf_expand_parameter_value(exp_buf, mode, value, 165 (PCF_MASTER_ENT *) 0); 166 if ((mode & PCF_HIDE_NAME) == 0) { 167 pcf_print_line(fp, mode, "%s = %s\n", name, value); 168 } else { 169 pcf_print_line(fp, mode, "%s\n", value); 170 } 171 } 172 if (msg_verbose) 173 vstream_fflush(fp); 174 } 175 } 176 177 /* pcf_comp_names - qsort helper */ 178 179 static int pcf_comp_names(const void *a, const void *b) 180 { 181 PCF_PARAM_INFO **ap = (PCF_PARAM_INFO **) a; 182 PCF_PARAM_INFO **bp = (PCF_PARAM_INFO **) b; 183 184 return (strcmp(PCF_PARAM_INFO_NAME(ap[0]), 185 PCF_PARAM_INFO_NAME(bp[0]))); 186 } 187 188 /* pcf_show_parameters - show parameter info */ 189 190 void pcf_show_parameters(VSTREAM *fp, int mode, int param_class, char **names) 191 { 192 PCF_PARAM_INFO **list; 193 PCF_PARAM_INFO **ht; 194 char **namep; 195 PCF_PARAM_NODE *node; 196 197 /* 198 * Show all parameters. 199 */ 200 if (*names == 0) { 201 list = PCF_PARAM_TABLE_LIST(pcf_param_table); 202 qsort((void *) list, pcf_param_table->used, sizeof(*list), 203 pcf_comp_names); 204 for (ht = list; *ht; ht++) 205 if (param_class & PCF_PARAM_INFO_NODE(*ht)->flags) 206 pcf_print_parameter(fp, mode, PCF_PARAM_INFO_NAME(*ht), 207 PCF_PARAM_INFO_NODE(*ht)); 208 myfree((void *) list); 209 return; 210 } 211 212 /* 213 * Show named parameters. 214 */ 215 for (namep = names; *namep; namep++) { 216 if ((node = PCF_PARAM_TABLE_FIND(pcf_param_table, *namep)) == 0) { 217 msg_warn("%s: unknown parameter", *namep); 218 } else { 219 pcf_print_parameter(fp, mode, *namep, node); 220 } 221 } 222 } 223