Home | History | Annotate | Line # | Download | only in master
      1 /*	$NetBSD: master_watch.c,v 1.2 2025/02/25 19:15:46 christos 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 notify
    106 	 * 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 notify
    144 	 * 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