1 /* $NetBSD: mail_conf_nint.c,v 1.1.1.2 2011/03/02 19:32:15 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* mail_conf_nint 3 6 /* SUMMARY 7 /* integer-valued configuration parameter support 8 /* SYNOPSIS 9 /* #include <mail_conf.h> 10 /* 11 /* int get_mail_conf_nint(name, defval, min, max); 12 /* const char *name; 13 /* const char *defval; 14 /* int min; 15 /* int max; 16 /* 17 /* int get_mail_conf_nint_fn(name, defval, min, max); 18 /* const char *name; 19 /* char *(*defval)(); 20 /* int min; 21 /* int max; 22 /* 23 /* void set_mail_conf_nint(name, value) 24 /* const char *name; 25 /* const char *value; 26 /* 27 /* void set_mail_conf_nint_int(name, value) 28 /* const char *name; 29 /* int value; 30 /* 31 /* void get_mail_conf_nint_table(table) 32 /* const CONFIG_NINT_TABLE *table; 33 /* 34 /* void get_mail_conf_nint_fn_table(table) 35 /* const CONFIG_NINT_TABLE *table; 36 /* AUXILIARY FUNCTIONS 37 /* int get_mail_conf_nint2(name1, name2, defval, min, max); 38 /* const char *name1; 39 /* const char *name2; 40 /* int defval; 41 /* int min; 42 /* int max; 43 /* DESCRIPTION 44 /* This module implements configuration parameter support 45 /* for integer values. Unlike mail_conf_int, the default 46 /* is a string, which can be subjected to macro expansion. 47 /* 48 /* get_mail_conf_nint() looks up the named entry in the global 49 /* configuration dictionary. The default value is returned 50 /* when no value was found. 51 /* \fImin\fR is zero or specifies a lower limit on the integer 52 /* value or string length; \fImax\fR is zero or specifies an 53 /* upper limit on the integer value or string length. 54 /* 55 /* get_mail_conf_nint_fn() is similar but specifies a function that 56 /* provides the default value. The function is called only 57 /* when the default value is needed. 58 /* 59 /* set_mail_conf_nint() updates the named entry in the global 60 /* configuration dictionary. This has no effect on values that 61 /* have been looked up earlier via the get_mail_conf_XXX() routines. 62 /* 63 /* get_mail_conf_nint_table() and get_mail_conf_nint_fn_table() initialize 64 /* lists of variables, as directed by their table arguments. A table 65 /* must be terminated by a null entry. 66 /* 67 /* get_mail_conf_nint2() concatenates the two names and is otherwise 68 /* identical to get_mail_conf_nint(). 69 /* DIAGNOSTICS 70 /* Fatal errors: malformed numerical value. 71 /* SEE ALSO 72 /* config(3) general configuration 73 /* mail_conf_str(3) string-valued configuration parameters 74 /* LICENSE 75 /* .ad 76 /* .fi 77 /* The Secure Mailer license must be distributed with this software. 78 /* AUTHOR(S) 79 /* Wietse Venema 80 /* IBM T.J. Watson Research 81 /* P.O. Box 704 82 /* Yorktown Heights, NY 10598, USA 83 /*--*/ 84 85 /* System library. */ 86 87 #include <sys_defs.h> 88 #include <stdlib.h> 89 #include <stdio.h> /* BUFSIZ */ 90 #include <errno.h> 91 92 /* Utility library. */ 93 94 #include <msg.h> 95 #include <mymalloc.h> 96 #include <dict.h> 97 #include <stringops.h> 98 99 /* Global library. */ 100 101 #include "mail_conf.h" 102 103 /* convert_mail_conf_nint - look up and convert integer parameter value */ 104 105 static int convert_mail_conf_nint(const char *name, int *intval) 106 { 107 const char *strval; 108 char *end; 109 long longval; 110 111 if ((strval = mail_conf_lookup_eval(name)) != 0) { 112 errno = 0; 113 *intval = longval = strtol(strval, &end, 10); 114 if (*strval == 0 || *end != 0 || errno == ERANGE || longval != *intval) 115 msg_fatal("bad numerical configuration: %s = %s", name, strval); 116 return (1); 117 } 118 return (0); 119 } 120 121 /* check_mail_conf_nint - validate integer value */ 122 123 static void check_mail_conf_nint(const char *name, int intval, int min, int max) 124 { 125 if (min && intval < min) 126 msg_fatal("invalid %s parameter value %d < %d", name, intval, min); 127 if (max && intval > max) 128 msg_fatal("invalid %s parameter value %d > %d", name, intval, max); 129 } 130 131 /* get_mail_conf_nint - evaluate integer-valued configuration variable */ 132 133 int get_mail_conf_nint(const char *name, const char *defval, int min, int max) 134 { 135 int intval; 136 137 if (convert_mail_conf_nint(name, &intval) == 0) 138 set_mail_conf_nint(name, defval); 139 if (convert_mail_conf_nint(name, &intval) == 0) 140 msg_panic("get_mail_conf_nint: parameter not found: %s", name); 141 check_mail_conf_nint(name, intval, min, max); 142 return (intval); 143 } 144 145 /* get_mail_conf_nint2 - evaluate integer-valued configuration variable */ 146 147 int get_mail_conf_nint2(const char *name1, const char *name2, int defval, 148 int min, int max) 149 { 150 int intval; 151 char *name; 152 153 name = concatenate(name1, name2, (char *) 0); 154 if (convert_mail_conf_nint(name, &intval) == 0) 155 set_mail_conf_nint_int(name, defval); 156 if (convert_mail_conf_nint(name, &intval) == 0) 157 msg_panic("get_mail_conf_nint2: parameter not found: %s", name); 158 check_mail_conf_nint(name, intval, min, max); 159 myfree(name); 160 return (intval); 161 } 162 163 /* get_mail_conf_nint_fn - evaluate integer-valued configuration variable */ 164 165 typedef const char *(*stupid_indent_int) (void); 166 167 int get_mail_conf_nint_fn(const char *name, stupid_indent_int defval, 168 int min, int max) 169 { 170 int intval; 171 172 if (convert_mail_conf_nint(name, &intval) == 0) 173 set_mail_conf_nint(name, defval()); 174 if (convert_mail_conf_nint(name, &intval) == 0) 175 msg_panic("get_mail_conf_nint_fn: parameter not found: %s", name); 176 check_mail_conf_nint(name, intval, min, max); 177 return (intval); 178 } 179 180 /* set_mail_conf_nint - update integer-valued configuration dictionary entry */ 181 182 void set_mail_conf_nint(const char *name, const char *value) 183 { 184 mail_conf_update(name, value); 185 } 186 187 /* set_mail_conf_nint_int - update integer-valued configuration dictionary entry */ 188 189 void set_mail_conf_nint_int(const char *name, int value) 190 { 191 char buf[BUFSIZ]; /* yeah! crappy code! */ 192 193 sprintf(buf, "%d", value); /* yeah! more crappy code! */ 194 mail_conf_update(name, buf); 195 } 196 197 /* get_mail_conf_nint_table - look up table of integers */ 198 199 void get_mail_conf_nint_table(const CONFIG_NINT_TABLE *table) 200 { 201 while (table->name) { 202 table->target[0] = get_mail_conf_nint(table->name, table->defval, 203 table->min, table->max); 204 table++; 205 } 206 } 207 208 /* get_mail_conf_nint_fn_table - look up integers, defaults are functions */ 209 210 void get_mail_conf_nint_fn_table(const CONFIG_NINT_FN_TABLE *table) 211 { 212 while (table->name) { 213 table->target[0] = get_mail_conf_nint_fn(table->name, table->defval, 214 table->min, table->max); 215 table++; 216 } 217 } 218