Home | History | Annotate | Line # | Download | only in global
      1 /*	$NetBSD: mail_conf_nint.c,v 1.2 2020/03/18 19:05:16 christos 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 /*	Wietse Venema
     85 /*	Google, Inc.
     86 /*	111 8th Avenue
     87 /*	New York, NY 10011, USA
     88 /*--*/
     89 
     90 /* System library. */
     91 
     92 #include <sys_defs.h>
     93 #include <stdlib.h>
     94 #include <stdio.h>			/* BUFSIZ */
     95 #include <errno.h>
     96 
     97 /* Utility library. */
     98 
     99 #include <msg.h>
    100 #include <mymalloc.h>
    101 #include <dict.h>
    102 #include <stringops.h>
    103 
    104 /* Global library. */
    105 
    106 #include "mail_conf.h"
    107 
    108 /* convert_mail_conf_nint - look up and convert integer parameter value */
    109 
    110 static int convert_mail_conf_nint(const char *name, int *intval)
    111 {
    112     const char *strval;
    113     char   *end;
    114     long    longval;
    115 
    116     if ((strval = mail_conf_lookup_eval(name)) != 0) {
    117 	errno = 0;
    118 	*intval = longval = strtol(strval, &end, 10);
    119 	if (*strval == 0 || *end != 0 || errno == ERANGE || longval != *intval)
    120 	    msg_fatal("bad numerical configuration: %s = %s", name, strval);
    121 	return (1);
    122     }
    123     return (0);
    124 }
    125 
    126 /* check_mail_conf_nint - validate integer value */
    127 
    128 static void check_mail_conf_nint(const char *name, int intval, int min, int max)
    129 {
    130     if (min && intval < min)
    131 	msg_fatal("invalid %s parameter value %d < %d", name, intval, min);
    132     if (max && intval > max)
    133 	msg_fatal("invalid %s parameter value %d > %d", name, intval, max);
    134 }
    135 
    136 /* get_mail_conf_nint - evaluate integer-valued configuration variable */
    137 
    138 int     get_mail_conf_nint(const char *name, const char *defval, int min, int max)
    139 {
    140     int     intval;
    141 
    142     if (convert_mail_conf_nint(name, &intval) == 0)
    143 	set_mail_conf_nint(name, defval);
    144     if (convert_mail_conf_nint(name, &intval) == 0)
    145 	msg_panic("get_mail_conf_nint: parameter not found: %s", name);
    146     check_mail_conf_nint(name, intval, min, max);
    147     return (intval);
    148 }
    149 
    150 /* get_mail_conf_nint2 - evaluate integer-valued configuration variable */
    151 
    152 int     get_mail_conf_nint2(const char *name1, const char *name2, int defval,
    153 			            int min, int max)
    154 {
    155     int     intval;
    156     char   *name;
    157 
    158     name = concatenate(name1, name2, (char *) 0);
    159     if (convert_mail_conf_nint(name, &intval) == 0)
    160 	set_mail_conf_nint_int(name, defval);
    161     if (convert_mail_conf_nint(name, &intval) == 0)
    162 	msg_panic("get_mail_conf_nint2: parameter not found: %s", name);
    163     check_mail_conf_nint(name, intval, min, max);
    164     myfree(name);
    165     return (intval);
    166 }
    167 
    168 /* get_mail_conf_nint_fn - evaluate integer-valued configuration variable */
    169 
    170 typedef const char *(*stupid_indent_int) (void);
    171 
    172 int     get_mail_conf_nint_fn(const char *name, stupid_indent_int defval,
    173 			              int min, int max)
    174 {
    175     int     intval;
    176 
    177     if (convert_mail_conf_nint(name, &intval) == 0)
    178 	set_mail_conf_nint(name, defval());
    179     if (convert_mail_conf_nint(name, &intval) == 0)
    180 	msg_panic("get_mail_conf_nint_fn: parameter not found: %s", name);
    181     check_mail_conf_nint(name, intval, min, max);
    182     return (intval);
    183 }
    184 
    185 /* set_mail_conf_nint - update integer-valued configuration dictionary entry */
    186 
    187 void    set_mail_conf_nint(const char *name, const char *value)
    188 {
    189     mail_conf_update(name, value);
    190 }
    191 
    192 /* set_mail_conf_nint_int - update integer-valued configuration dictionary entry */
    193 
    194 void    set_mail_conf_nint_int(const char *name, int value)
    195 {
    196     const char myname[] = "set_mail_conf_nint_int";
    197     char    buf[BUFSIZ];		/* yeah! crappy code! */
    198 
    199 #ifndef NO_SNPRINTF
    200     ssize_t ret;
    201 
    202     ret = snprintf(buf, sizeof(buf), "%d", value);
    203     if (ret < 0)
    204 	msg_panic("%s: output error for %%d", myname);
    205     if (ret >= sizeof(buf))
    206 	msg_panic("%s: output for %%d exceeds space %ld",
    207 		  myname, (long) sizeof(buf));
    208 #else
    209     sprintf(buf, "%d", value);			/* yeah! more crappy code! */
    210 #endif
    211     mail_conf_update(name, buf);
    212 }
    213 
    214 /* get_mail_conf_nint_table - look up table of integers */
    215 
    216 void    get_mail_conf_nint_table(const CONFIG_NINT_TABLE *table)
    217 {
    218     while (table->name) {
    219 	table->target[0] = get_mail_conf_nint(table->name, table->defval,
    220 					      table->min, table->max);
    221 	table++;
    222     }
    223 }
    224 
    225 /* get_mail_conf_nint_fn_table - look up integers, defaults are functions */
    226 
    227 void    get_mail_conf_nint_fn_table(const CONFIG_NINT_FN_TABLE *table)
    228 {
    229     while (table->name) {
    230 	table->target[0] = get_mail_conf_nint_fn(table->name, table->defval,
    231 						 table->min, table->max);
    232 	table++;
    233     }
    234 }
    235