diff options
Diffstat (limited to '')
-rw-r--r-- | src/master/master_conf.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/src/master/master_conf.c b/src/master/master_conf.c new file mode 100644 index 0000000..37cad2a --- /dev/null +++ b/src/master/master_conf.c @@ -0,0 +1,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(); +} |