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

/* System library. */

#include <sys_defs.h>
#include <string.h>
#include <unistd.h>

/* Utility library. */

#include <msg.h>
#include <mymalloc.h>

/* Application-specific. */

#include "master.h"

/* master_str_watch - watch string-valued parameters for change */

void    master_str_watch(const MASTER_STR_WATCH *str_watch_table)
{
    const MASTER_STR_WATCH *wp;

    for (wp = str_watch_table; wp->name != 0; wp++) {

	/*
	 * Detect changes to monitored parameter values. If a change is
	 * supported, we discard the backed up value and update it to the
	 * current value later. Otherwise we complain.
	 */
	if (wp->backup[0] != 0
	    && strcmp(wp->backup[0], wp->value[0]) != 0) {
	    if ((wp->flags & MASTER_WATCH_FLAG_UPDATABLE) == 0) {
		msg_warn("ignoring %s parameter value change", wp->name);
		msg_warn("old value: \"%s\", new value: \"%s\"",
			 wp->backup[0], wp->value[0]);
		msg_warn("to change %s, stop and start Postfix", wp->name);
	    } else {
		myfree(wp->backup[0]);
		wp->backup[0] = 0;
	    }
	}

	/*
	 * Initialize the backed up parameter value, or update it if this
	 * parameter supports updates after initialization. Optionally 
	 * notify the application that this parameter has changed.
	 */
	if (wp->backup[0] == 0) {
	    if (wp->notify != 0)
		wp->notify();
	    wp->backup[0] = mystrdup(wp->value[0]);
	}
    }
}

/* master_int_watch - watch integer-valued parameters for change */

void    master_int_watch(MASTER_INT_WATCH *int_watch_table)
{
    MASTER_INT_WATCH *wp;

    for (wp = int_watch_table; wp->name != 0; wp++) {

	/*
	 * Detect changes to monitored parameter values. If a change is
	 * supported, we discard the backed up value and update it to the
	 * current value later. Otherwise we complain.
	 */
	if ((wp->flags & MASTER_WATCH_FLAG_ISSET) != 0
	    && wp->backup != wp->value[0]) {
	    if ((wp->flags & MASTER_WATCH_FLAG_UPDATABLE) == 0) {
		msg_warn("ignoring %s parameter value change", wp->name);
		msg_warn("old value: \"%d\", new value: \"%d\"",
			 wp->backup, wp->value[0]);
		msg_warn("to change %s, stop and start Postfix", wp->name);
	    } else {
		wp->flags &= ~MASTER_WATCH_FLAG_ISSET;
	    }
	}

	/*
	 * Initialize the backed up parameter value, or update if it this
	 * parameter supports updates after initialization. Optionally 
	 * notify the application that this parameter has changed.
	 */
	if ((wp->flags & MASTER_WATCH_FLAG_ISSET) == 0) {
	    if (wp->notify != 0)
		wp->notify();
	    wp->flags |= MASTER_WATCH_FLAG_ISSET;
	    wp->backup = wp->value[0];
	}
    }
}