1 /*	$NetBSD: master_conf.c,v 1.1.1.1 2009/06/23 10:08:49 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	master_conf 3
6 /* SUMMARY
7 /*	Postfix master - master.cf file processing
8 /* SYNOPSIS
9 /*	#include "master.h"
10 /*
11 /*	void	master_config(serv)
12 /*	MASTER_SERV *serv;
13 /*
14 /*	void	master_refresh(serv)
15 /*	MASTER_SERV *serv;
16 /* DESCRIPTION
17 /*	Use master_config() to read the master.cf configuration file
18 /*	during program initialization.
19 /*
20 /*	Use master_refresh() to re-read the master.cf configuration file
21 /*	when the process is already running.
22 /* DIAGNOSTICS
23 /* BUGS
24 /* SEE ALSO
25 /*	master_ent(3), configuration file programmatic interface.
26 /* LICENSE
27 /* .ad
28 /* .fi
29 /*	The Secure Mailer license must be distributed with this software.
30 /* AUTHOR(S)
31 /*	Wietse Venema
32 /*	IBM T.J. Watson Research
33 /*	P.O. Box 704
34 /*	Yorktown Heights, NY 10598, USA
35 /*--*/
36 
37 /* System libraries. */
38 
39 #include <sys_defs.h>
40 #include <unistd.h>
41 #include <string.h>
42 
43 /* Utility library. */
44 
45 #include <msg.h>
46 #include <argv.h>
47 
48 /* Application-specific. */
49 
50 #include "master.h"
51 
52 /* master_refresh - re-read configuration table */
53 
54 void    master_refresh(void)
55 {
56     MASTER_SERV *serv;
57     MASTER_SERV **servp;
58 
59     /*
60      * Mark all existing services.
61      */
62     for (serv = master_head; serv != 0; serv = serv->next)
63 	serv->flags |= MASTER_FLAG_MARK;
64 
65     /*
66      * Read the master.cf configuration file. The master_conf() routine
67      * unmarks services upon update. New services are born with the mark bit
68      * off. After this, anything with the mark bit on should be removed.
69      */
70     master_config();
71 
72     /*
73      * Delete all services that are still marked - they disappeared from the
74      * configuration file and are therefore no longer needed.
75      */
76     for (servp = &master_head; (serv = *servp) != 0; /* void */ ) {
77 	if ((serv->flags & MASTER_FLAG_MARK) != 0) {
78 	    *servp = serv->next;
79 	    master_stop_service(serv);
80 	    free_master_ent(serv);
81 	} else {
82 	    servp = &serv->next;
83 	}
84     }
85 }
86 
87 /* master_config - read config file */
88 
89 void    master_config(void)
90 {
91     MASTER_SERV *entry;
92     MASTER_SERV *serv;
93 
94 #define STR_DIFF	strcmp
95 #define STR_SAME	!strcmp
96 #define SWAP(type,a,b)	{ type temp = a; a = b; b = temp; }
97 
98     /*
99      * A service is identified by its endpoint name AND by its transport
100      * type, not just by its name alone. The name is unique within its
101      * transport type. XXX Service privacy is encoded in the service name.
102      */
103     set_master_ent();
104     while ((entry = get_master_ent()) != 0) {
105 	if (msg_verbose)
106 	    print_master_ent(entry);
107 	for (serv = master_head; serv != 0; serv = serv->next)
108 	    if (STR_SAME(serv->name, entry->name) && serv->type == entry->type)
109 		break;
110 
111 	/*
112 	 * Add a new service entry. We do not really care in what order the
113 	 * service entries are kept in memory.
114 	 */
115 	if (serv == 0) {
116 	    entry->next = master_head;
117 	    master_head = entry;
118 	    master_start_service(entry);
119 	}
120 
121 	/*
122 	 * Update an existing service entry. Make the current generation of
123 	 * child processes commit suicide whenever it is convenient. The next
124 	 * generation of child processes will run with the new configuration
125 	 * settings.
126 	 */
127 	else {
128 	    serv->flags &= ~MASTER_FLAG_MARK;
129 	    if (entry->flags & MASTER_FLAG_CONDWAKE)
130 		serv->flags |= MASTER_FLAG_CONDWAKE;
131 	    else
132 		serv->flags &= ~MASTER_FLAG_CONDWAKE;
133 	    serv->wakeup_time = entry->wakeup_time;
134 	    serv->max_proc = entry->max_proc;
135 	    serv->throttle_delay = entry->throttle_delay;
136 	    SWAP(char *, serv->ext_name, entry->ext_name);
137 	    SWAP(char *, serv->path, entry->path);
138 	    SWAP(ARGV *, serv->args, entry->args);
139 	    SWAP(char *, serv->stress_param_val, entry->stress_param_val);
140 	    master_restart_service(serv);
141 	    free_master_ent(entry);
142 	}
143     }
144     end_master_ent();
145 }
146