Home | History | Annotate | Line # | Download | only in global
      1 /*	$NetBSD: mail_conf_time.c,v 1.4 2022/10/08 16:12:45 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	mail_conf_time 3
      6 /* SUMMARY
      7 /*	time interval configuration parameter support
      8 /* SYNOPSIS
      9 /*	#include <mail_conf.h>
     10 /*
     11 /*	int	get_mail_conf_time(name, defval, min, max);
     12 /*	const char *name;
     13 /*	const char *defval;
     14 /*	int	min;
     15 /*	int	max;
     16 /*
     17 /*	void	set_mail_conf_time(name, value)
     18 /*	const char *name;
     19 /*	const char *value;
     20 /*
     21 /*	void	set_mail_conf_time_int(name, value)
     22 /*	const char *name;
     23 /*	int     value;
     24 /*
     25 /*	void	get_mail_conf_time_table(table)
     26 /*	const CONFIG_TIME_TABLE *table;
     27 /* AUXILIARY FUNCTIONS
     28 /*	int	get_mail_conf_time2(name1, name2, defval, def_unit, min, max);
     29 /*	const char *name1;
     30 /*	const char *name2;
     31 /*	int	defval;
     32 /*	int	def_unit;
     33 /*	int	min;
     34 /*	int	max;
     35 /*
     36 /*	void	check_mail_conf_time(name, intval, min, max)
     37 /*	const char *name;
     38 /*	int	intval;
     39 /*	int	min;
     40 /*	int	max;
     41 /* DESCRIPTION
     42 /*	This module implements configuration parameter support
     43 /*	for time interval values. The conversion routines understand
     44 /*	one-letter suffixes to specify an explicit time unit: s
     45 /*	(seconds), m (minutes), h (hours), d (days) or w (weeks).
     46 /*	Internally, time is represented in seconds.
     47 /*
     48 /*	get_mail_conf_time() looks up the named entry in the global
     49 /*	configuration dictionary. The default value is returned
     50 /*	when no value was found. \fIdef_unit\fR supplies the default
     51 /*	time unit for numbers specified without explicit unit.
     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 /*	set_mail_conf_time() updates the named entry in the global
     57 /*	configuration dictionary. This has no effect on values that
     58 /*	have been looked up earlier via the get_mail_conf_XXX() routines.
     59 /*
     60 /*	get_mail_conf_time_table() and get_mail_conf_time_fn_table() initialize
     61 /*	lists of variables, as directed by their table arguments. A table
     62 /*	must be terminated by a null entry.
     63 /*
     64 /*	check_mail_conf_time() terminates the program with a fatal
     65 /*	runtime error when the time does not meet its requirements.
     66 /* DIAGNOSTICS
     67 /*	Fatal errors: malformed numerical value, unknown time unit.
     68 /* BUGS
     69 /*	Values and defaults are given in any unit; upper and lower
     70 /*	bounds are given in seconds.
     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 <ctype.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 "conv_time.h"
    107 #include "mail_conf.h"
    108 
    109 /* convert_mail_conf_time - look up and convert integer parameter value */
    110 
    111 static int convert_mail_conf_time(const char *name, int *intval, int def_unit)
    112 {
    113     const char *strval;
    114 
    115     if ((strval = mail_conf_lookup_eval(name)) == 0)
    116 	return (0);
    117     if (conv_time(strval, intval, def_unit) == 0)
    118 	msg_fatal("parameter %s: bad time value or unit: %s", name, strval);
    119     return (1);
    120 }
    121 
    122 /* check_mail_conf_time - validate integer value */
    123 
    124 void    check_mail_conf_time(const char *name, int intval, int min, int max)
    125 {
    126     if (min && intval < min)
    127 	msg_fatal("invalid %s: %d (min %d)", name, intval, min);
    128     if (max && intval > max)
    129 	msg_fatal("invalid %s: %d (max %d)", name, intval, max);
    130 }
    131 
    132 /* get_def_time_unit - extract time unit from default value */
    133 
    134 static int get_def_time_unit(const char *name, const char *defval)
    135 {
    136     const char *cp;
    137 
    138     for (cp = mail_conf_eval(defval); /* void */ ; cp++) {
    139 	if (*cp == 0)
    140 	    msg_panic("parameter %s: missing time unit in default value: %s",
    141 		      name, defval);
    142 	if (ISALPHA(*cp)) {
    143 #if 0
    144 	    if (cp[1] != 0)
    145 		msg_panic("parameter %s: bad time unit in default value: %s",
    146 			  name, defval);
    147 #endif
    148 	    return (*cp);
    149 	}
    150     }
    151 }
    152 
    153 /* get_mail_conf_time - evaluate integer-valued configuration variable */
    154 
    155 int     get_mail_conf_time(const char *name, const char *defval, int min, int max)
    156 {
    157     int     intval;
    158     int     def_unit;
    159 
    160     def_unit = get_def_time_unit(name, defval);
    161     if (convert_mail_conf_time(name, &intval, def_unit) == 0)
    162 	set_mail_conf_time(name, defval);
    163     if (convert_mail_conf_time(name, &intval, def_unit) == 0)
    164 	msg_panic("get_mail_conf_time: parameter not found: %s", name);
    165     check_mail_conf_time(name, intval, min, max);
    166     return (intval);
    167 }
    168 
    169 /* get_mail_conf_time2 - evaluate integer-valued configuration variable */
    170 
    171 int     get_mail_conf_time2(const char *name1, const char *name2,
    172 			         int defval, int def_unit, int min, int max)
    173 {
    174     int     intval;
    175     char   *name;
    176 
    177     name = concatenate(name1, name2, (char *) 0);
    178     if (convert_mail_conf_time(name, &intval, def_unit) == 0)
    179 	set_mail_conf_time_int(name, defval);
    180     if (convert_mail_conf_time(name, &intval, def_unit) == 0)
    181 	msg_panic("get_mail_conf_time2: parameter not found: %s", name);
    182     check_mail_conf_time(name, intval, min, max);
    183     myfree(name);
    184     return (intval);
    185 }
    186 
    187 /* set_mail_conf_time - update integer-valued configuration dictionary entry */
    188 
    189 void    set_mail_conf_time(const char *name, const char *value)
    190 {
    191     mail_conf_update(name, value);
    192 }
    193 
    194 /* set_mail_conf_time_int - update integer-valued configuration dictionary entry */
    195 
    196 void    set_mail_conf_time_int(const char *name, int value)
    197 {
    198     const char myname[] = "set_mail_conf_time_int";
    199     char    buf[BUFSIZ];		/* yeah! crappy code! */
    200 
    201 #ifndef NO_SNPRINTF
    202     ssize_t ret;
    203 
    204     ret = snprintf(buf, sizeof(buf), "%ds", value);
    205     if (ret < 0)
    206 	msg_panic("%s: output error for %%ds", myname);
    207     if (ret >= sizeof(buf))
    208 	msg_panic("%s: output for %%ds exceeds space %ld",
    209 		  myname, (long) sizeof(buf));
    210 #else
    211     sprintf(buf, "%ds", value);			/* yeah! more crappy code! */
    212 #endif
    213     mail_conf_update(name, buf);
    214 }
    215 
    216 /* get_mail_conf_time_table - look up table of integers */
    217 
    218 void    get_mail_conf_time_table(const CONFIG_TIME_TABLE *table)
    219 {
    220     while (table->name) {
    221 	table->target[0] = get_mail_conf_time(table->name, table->defval,
    222 					      table->min, table->max);
    223 	table++;
    224     }
    225 }
    226 
    227 #ifdef TEST
    228 
    229  /*
    230   * Stand-alone driver program for regression testing.
    231   */
    232 #include <vstream.h>
    233 
    234 int     main(int unused_argc, char **unused_argv)
    235 {
    236     static int seconds;
    237     static int minutes;
    238     static int hours;
    239     static int days;
    240     static int weeks;
    241     static const CONFIG_TIME_TABLE time_table[] = {
    242 	"seconds", "10s", &seconds, 0, 0,
    243 	"minutes", "10m", &minutes, 0, 0,
    244 	"hours", "10h", &hours, 0, 0,
    245 	"days", "10d", &days, 0, 0,
    246 	"weeks", "10w", &weeks, 0, 0,
    247 	0,
    248     };
    249 
    250     get_mail_conf_time_table(time_table);
    251     vstream_printf("10 seconds = %d\n", seconds);
    252     vstream_printf("10 minutes = %d\n", minutes);
    253     vstream_printf("10 hours = %d\n", hours);
    254     vstream_printf("10 days = %d\n", days);
    255     vstream_printf("10 weeks = %d\n", weeks);
    256     vstream_fflush(VSTREAM_OUT);
    257     return (0);
    258 }
    259 
    260 #endif
    261