1/*	$NetBSD$	*/
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
79void    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
118void    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