1 /*	$NetBSD: mail_conf_time.c,v 1.1.1.1 2009/06/23 10:08:46 tron 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 /* DESCRIPTION
36 /*	This module implements configuration parameter support
37 /*	for time interval values. The conversion routines understand
38 /*	one-letter suffixes to specify an explicit time unit: s
39 /*	(seconds), m (minutes), h (hours), d (days) or w (weeks).
40 /*	Internally, time is represented in seconds.
41 /*
42 /*	get_mail_conf_time() looks up the named entry in the global
43 /*	configuration dictionary. The default value is returned
44 /*	when no value was found. \fIdef_unit\fR supplies the default
45 /*	time unit for numbers numbers specified without explicit unit.
46 /*	\fImin\fR is zero or specifies a lower limit on the integer
47 /*	value or string length; \fImax\fR is zero or specifies an
48 /*	upper limit on the integer value or string length.
49 /*
50 /*	set_mail_conf_time() updates the named entry in the global
51 /*	configuration dictionary. This has no effect on values that
52 /*	have been looked up earlier via the get_mail_conf_XXX() routines.
53 /*
54 /*	get_mail_conf_time_table() and get_mail_conf_time_fn_table() initialize
55 /*	lists of variables, as directed by their table arguments. A table
56 /*	must be terminated by a null entry.
57 /* DIAGNOSTICS
58 /*	Fatal errors: malformed numerical value, unknown time unit.
59 /* BUGS
60 /*	Values and defaults are given in any unit; upper and lower
61 /*	bounds are given in seconds.
62 /* SEE ALSO
63 /*	config(3) general configuration
64 /*	mail_conf_str(3) string-valued configuration parameters
65 /* LICENSE
66 /* .ad
67 /* .fi
68 /*	The Secure Mailer license must be distributed with this software.
69 /* AUTHOR(S)
70 /*	Wietse Venema
71 /*	IBM T.J. Watson Research
72 /*	P.O. Box 704
73 /*	Yorktown Heights, NY 10598, USA
74 /*--*/
75 
76 /* System library. */
77 
78 #include <sys_defs.h>
79 #include <stdlib.h>
80 #include <stdio.h>			/* sscanf() */
81 #include <ctype.h>
82 
83 /* Utility library. */
84 
85 #include <msg.h>
86 #include <mymalloc.h>
87 #include <dict.h>
88 #include <stringops.h>
89 
90 /* Global library. */
91 
92 #include "conv_time.h"
93 #include "mail_conf.h"
94 
95 /* convert_mail_conf_time - look up and convert integer parameter value */
96 
97 static int convert_mail_conf_time(const char *name, int *intval, int def_unit)
98 {
99     const char *strval;
100 
101     if ((strval = mail_conf_lookup_eval(name)) == 0)
102 	return (0);
103     if (conv_time(strval, intval, def_unit) == 0)
104 	msg_fatal("parameter %s: bad time value or unit: %s", name, strval);
105     return (1);
106 }
107 
108 /* check_mail_conf_time - validate integer value */
109 
110 static void check_mail_conf_time(const char *name, int intval, int min, int max)
111 {
112     if (min && intval < min)
113 	msg_fatal("invalid %s: %d (min %d)", name, intval, min);
114     if (max && intval > max)
115 	msg_fatal("invalid %s: %d (max %d)", name, intval, max);
116 }
117 
118 /* get_def_time_unit - extract time unit from default value */
119 
120 static int get_def_time_unit(const char *name, const char *defval)
121 {
122     const char *cp;
123 
124     for (cp = mail_conf_eval(defval); /* void */ ; cp++) {
125 	if (*cp == 0)
126 	    msg_panic("parameter %s: missing time unit in default value: %s",
127 		      name, defval);
128 	if (ISALPHA(*cp)) {
129 	    if (cp[1] != 0)
130 		msg_panic("parameter %s: bad time unit in default value: %s",
131 			  name, defval);
132 	    return (*cp);
133 	}
134     }
135 }
136 
137 /* get_mail_conf_time - evaluate integer-valued configuration variable */
138 
139 int     get_mail_conf_time(const char *name, const char *defval, int min, int max)
140 {
141     int     intval;
142     int     def_unit;
143 
144     def_unit = get_def_time_unit(name, defval);
145     if (convert_mail_conf_time(name, &intval, def_unit) == 0)
146 	set_mail_conf_time(name, defval);
147     if (convert_mail_conf_time(name, &intval, def_unit) == 0)
148 	msg_panic("get_mail_conf_time: parameter not found: %s", name);
149     check_mail_conf_time(name, intval, min, max);
150     return (intval);
151 }
152 
153 /* get_mail_conf_time2 - evaluate integer-valued configuration variable */
154 
155 int     get_mail_conf_time2(const char *name1, const char *name2,
156 			            int defval, int def_unit, int min, int max)
157 {
158     int     intval;
159     char   *name;
160 
161     name = concatenate(name1, name2, (char *) 0);
162     if (convert_mail_conf_time(name, &intval, def_unit) == 0)
163 	set_mail_conf_time_int(name, defval);
164     if (convert_mail_conf_time(name, &intval, def_unit) == 0)
165 	msg_panic("get_mail_conf_time2: parameter not found: %s", name);
166     check_mail_conf_time(name, intval, min, max);
167     myfree(name);
168     return (intval);
169 }
170 
171 /* set_mail_conf_time - update integer-valued configuration dictionary entry */
172 
173 void    set_mail_conf_time(const char *name, const char *value)
174 {
175     mail_conf_update(name, value);
176 }
177 
178 /* set_mail_conf_time_int - update integer-valued configuration dictionary entry */
179 
180 void    set_mail_conf_time_int(const char *name, int value)
181 {
182     char    buf[BUFSIZ];		/* yeah! crappy code! */
183 
184     sprintf(buf, "%ds", value);		        /* yeah! more crappy code! */
185     mail_conf_update(name, buf);
186 }
187 
188 /* get_mail_conf_time_table - look up table of integers */
189 
190 void    get_mail_conf_time_table(const CONFIG_TIME_TABLE *table)
191 {
192     while (table->name) {
193 	table->target[0] = get_mail_conf_time(table->name, table->defval,
194 					      table->min, table->max);
195 	table++;
196     }
197 }
198 
199 #ifdef TEST
200 
201  /*
202   * Stand-alone driver program for regression testing.
203   */
204 #include <vstream.h>
205 
206 int     main(int unused_argc, char **unused_argv)
207 {
208     static int seconds;
209     static int minutes;
210     static int hours;
211     static int days;
212     static int weeks;
213     static const CONFIG_TIME_TABLE time_table[] = {
214 	"seconds", "10s", &seconds, 0, 0,
215 	"minutes", "10m", &minutes, 0, 0,
216 	"hours", "10h", &hours, 0, 0,
217 	"days", "10d", &days, 0, 0,
218 	"weeks", "10w", &weeks, 0, 0,
219 	0,
220     };
221 
222     get_mail_conf_time_table(time_table);
223     vstream_printf("10 seconds = %d\n", seconds);
224     vstream_printf("10 minutes = %d\n", minutes);
225     vstream_printf("10 hours = %d\n", hours);
226     vstream_printf("10 days = %d\n", days);
227     vstream_printf("10 weeks = %d\n", weeks);
228     vstream_fflush(VSTREAM_OUT);
229     return (0);
230 }
231 
232 #endif
233