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