summaryrefslogtreecommitdiffstats
path: root/src/master/master_conf.c
blob: 37cad2a8564ec0e88c1ecd2a04a4cf98f71626b6 (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
152
/*++
/* NAME
/*	master_conf 3
/* SUMMARY
/*	Postfix master - master.cf file processing
/* SYNOPSIS
/*	#include "master.h"
/*
/*	void	master_config(serv)
/*	MASTER_SERV *serv;
/*
/*	void	master_refresh(serv)
/*	MASTER_SERV *serv;
/* DESCRIPTION
/*	Use master_config() to read the master.cf configuration file
/*	during program initialization.
/*
/*	Use master_refresh() to re-read the master.cf configuration file
/*	when the process is already running.
/* DIAGNOSTICS
/* BUGS
/* SEE ALSO
/*	master_ent(3), configuration file programmatic interface.
/* 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
/*
/*	Wietse Venema
/*	Google, Inc.
/*	111 8th Avenue
/*	New York, NY 10011, USA
/*--*/

/* System libraries. */

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

/* Utility library. */

#include <msg.h>
#include <argv.h>

/* Application-specific. */

#include "master.h"

/* master_refresh - re-read configuration table */

void    master_refresh(void)
{
    MASTER_SERV *serv;
    MASTER_SERV **servp;

    /*
     * Mark all existing services.
     */
    for (serv = master_head; serv != 0; serv = serv->next)
	serv->flags |= MASTER_FLAG_MARK;

    /*
     * Read the master.cf configuration file. The master_conf() routine
     * unmarks services upon update. New services are born with the mark bit
     * off. After this, anything with the mark bit on should be removed.
     */
    master_config();

    /*
     * Delete all services that are still marked - they disappeared from the
     * configuration file and are therefore no longer needed.
     */
    for (servp = &master_head; (serv = *servp) != 0; /* void */ ) {
	if ((serv->flags & MASTER_FLAG_MARK) != 0) {
	    *servp = serv->next;
	    master_stop_service(serv);
	    free_master_ent(serv);
	} else {
	    servp = &serv->next;
	}
    }
}

/* master_config - read config file */

void    master_config(void)
{
    MASTER_SERV *entry;
    MASTER_SERV *serv;

#define STR_DIFF	strcmp
#define STR_SAME	!strcmp
#define SWAP(type,a,b)	{ type temp = a; a = b; b = temp; }

    /*
     * A service is identified by its endpoint name AND by its transport
     * type, not just by its name alone. The name is unique within its
     * transport type. XXX Service privacy is encoded in the service name.
     */
    set_master_ent();
    while ((entry = get_master_ent()) != 0) {
	if (msg_verbose)
	    print_master_ent(entry);
	for (serv = master_head; serv != 0; serv = serv->next)
	    if (STR_SAME(serv->name, entry->name) && serv->type == entry->type)
		break;

	/*
	 * Add a new service entry. We do not really care in what order the
	 * service entries are kept in memory.
	 */
	if (serv == 0) {
	    entry->next = master_head;
	    master_head = entry;
	    master_start_service(entry);
	}

	/*
	 * Update an existing service entry. Make the current generation of
	 * child processes commit suicide whenever it is convenient. The next
	 * generation of child processes will run with the new configuration
	 * settings.
	 */
	else {
	    if ((serv->flags & MASTER_FLAG_MARK) == 0)
		msg_warn("duplicate master.cf entry for service \"%s\" (%s) "
		     "-- using the last entry", serv->ext_name, serv->name);
	    else
		serv->flags &= ~MASTER_FLAG_MARK;
	    if (entry->flags & MASTER_FLAG_CONDWAKE)
		serv->flags |= MASTER_FLAG_CONDWAKE;
	    else
		serv->flags &= ~MASTER_FLAG_CONDWAKE;
	    serv->wakeup_time = entry->wakeup_time;
	    serv->max_proc = entry->max_proc;
	    serv->throttle_delay = entry->throttle_delay;
	    SWAP(char *, serv->ext_name, entry->ext_name);
	    SWAP(char *, serv->path, entry->path);
	    SWAP(ARGV *, serv->args, entry->args);
	    SWAP(char *, serv->stress_param_val, entry->stress_param_val);
	    master_restart_service(serv, DO_CONF_RELOAD);
	    free_master_ent(entry);
	}
    }
    end_master_ent();
}