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