1 /*	$NetBSD: master_watch.c,v 1.1.1.1 2009/06/23 10:08:49 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	master_watch 3
6 /* SUMMARY
7 /*	Postfix master - monitor main.cf changes
8 /* SYNOPSIS
9 /*	#include "master.h"
10 /*
11 /*	void	master_str_watch(str_watch_table)
12 /*	const MASTER_STR_WATCH *str_watch_table;
13 /*
14 /*	void	master_int_watch(int_watch_table)
15 /*	MASTER_INT_WATCH *int_watch_table;
16 /* DESCRIPTION
17 /*	The Postfix master daemon is a long-running process. After
18 /*	main.cf is changed, some parameter changes may require that
19 /*	master data structures be recomputed.
20 /*
21 /*	Unfortunately, some main.cf changes cannot be applied
22 /*	on-the-fly, either because they require killing off existing
23 /*	child processes and thus disrupt service, or because the
24 /*	necessary support for on-the-fly data structure update has
25 /*	not yet been implemented.  Such main.cf changes trigger a
26 /*	warning that they require that Postfix be stopped and
27 /*	restarted.
28 /*
29 /*	This module provides functions that monitor selected main.cf
30 /*	parameters for change. The operation of these functions is
31 /*	controlled by tables that specify the parameter name, the
32 /*	current parameter value, a historical parameter value,
33 /*	optional flags, and an optional notify call-back function.
34 /*
35 /*	master_str_watch() monitors string-valued parameters for
36 /*	change, and master_int_watch() does the same for integer-valued
37 /*	parameters. Note that master_int_watch() needs read-write
38 /*	access to its argument table, while master_str_watch() needs
39 /*	read-only access only.
40 /*
41 /*	The functions log a warning when a parameter value has
42 /*	changed after re-reading main.cf, but the parameter is not
43 /*	flagged in the MASTER_*_WATCH table as "updatable" with
44 /*	MASTER_WATCH_FLAG_UPDATABLE.
45 /*
46 /*	If the parameter has a notify call-back function, then the
47 /*	function is called after main.cf is read for the first time.
48 /*	If the parameter is flagged as "updatable", then the function
49 /*	is also called when the parameter value changes after
50 /*	re-reading main.cf.
51 /* LICENSE
52 /* .ad
53 /* .fi
54 /*	The Secure Mailer license must be distributed with this software.
55 /* AUTHOR(S)
56 /*	Wietse Venema
57 /*	IBM T.J. Watson Research
58 /*	P.O. Box 704
59 /*	Yorktown Heights, NY 10598, USA
60 /*--*/
61 
62 /* System library. */
63 
64 #include <sys_defs.h>
65 #include <string.h>
66 #include <unistd.h>
67 
68 /* Utility library. */
69 
70 #include <msg.h>
71 #include <mymalloc.h>
72 
73 /* Application-specific. */
74 
75 #include "master.h"
76 
77 /* master_str_watch - watch string-valued parameters for change */
78 
79 void    master_str_watch(const MASTER_STR_WATCH *str_watch_table)
80 {
81     const MASTER_STR_WATCH *wp;
82 
83     for (wp = str_watch_table; wp->name != 0; wp++) {
84 
85 	/*
86 	 * Detect changes to monitored parameter values. If a change is
87 	 * supported, we discard the backed up value and update it to the
88 	 * current value later. Otherwise we complain.
89 	 */
90 	if (wp->backup[0] != 0
91 	    && strcmp(wp->backup[0], wp->value[0]) != 0) {
92 	    if ((wp->flags & MASTER_WATCH_FLAG_UPDATABLE) == 0) {
93 		msg_warn("ignoring %s parameter value change", wp->name);
94 		msg_warn("old value: \"%s\", new value: \"%s\"",
95 			 wp->backup[0], wp->value[0]);
96 		msg_warn("to change %s, stop and start Postfix", wp->name);
97 	    } else {
98 		myfree(wp->backup[0]);
99 		wp->backup[0] = 0;
100 	    }
101 	}
102 
103 	/*
104 	 * Initialize the backed up parameter value, or update it if this
105 	 * parameter supports updates after initialization. Optionally
106 	 * notify the application that this parameter has changed.
107 	 */
108 	if (wp->backup[0] == 0) {
109 	    if (wp->notify != 0)
110 		wp->notify();
111 	    wp->backup[0] = mystrdup(wp->value[0]);
112 	}
113     }
114 }
115 
116 /* master_int_watch - watch integer-valued parameters for change */
117 
118 void    master_int_watch(MASTER_INT_WATCH *int_watch_table)
119 {
120     MASTER_INT_WATCH *wp;
121 
122     for (wp = int_watch_table; wp->name != 0; wp++) {
123 
124 	/*
125 	 * Detect changes to monitored parameter values. If a change is
126 	 * supported, we discard the backed up value and update it to the
127 	 * current value later. Otherwise we complain.
128 	 */
129 	if ((wp->flags & MASTER_WATCH_FLAG_ISSET) != 0
130 	    && wp->backup != wp->value[0]) {
131 	    if ((wp->flags & MASTER_WATCH_FLAG_UPDATABLE) == 0) {
132 		msg_warn("ignoring %s parameter value change", wp->name);
133 		msg_warn("old value: \"%d\", new value: \"%d\"",
134 			 wp->backup, wp->value[0]);
135 		msg_warn("to change %s, stop and start Postfix", wp->name);
136 	    } else {
137 		wp->flags &= ~MASTER_WATCH_FLAG_ISSET;
138 	    }
139 	}
140 
141 	/*
142 	 * Initialize the backed up parameter value, or update if it this
143 	 * parameter supports updates after initialization. Optionally
144 	 * notify the application that this parameter has changed.
145 	 */
146 	if ((wp->flags & MASTER_WATCH_FLAG_ISSET) == 0) {
147 	    if (wp->notify != 0)
148 		wp->notify();
149 	    wp->flags |= MASTER_WATCH_FLAG_ISSET;
150 	    wp->backup = wp->value[0];
151 	}
152     }
153 }
154