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