summaryrefslogtreecommitdiffstats
path: root/src/master/master_conf.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/master/master_conf.c152
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();
+}