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