1 /* $NetBSD: master_conf.c,v 1.2 2020/03/18 19:05:16 christos 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 /* Wietse Venema 37 /* Google, Inc. 38 /* 111 8th Avenue 39 /* New York, NY 10011, USA 40 /*--*/ 41 42 /* System libraries. */ 43 44 #include <sys_defs.h> 45 #include <unistd.h> 46 #include <string.h> 47 48 /* Utility library. */ 49 50 #include <msg.h> 51 #include <argv.h> 52 53 /* Application-specific. */ 54 55 #include "master.h" 56 57 /* master_refresh - re-read configuration table */ 58 59 void master_refresh(void) 60 { 61 MASTER_SERV *serv; 62 MASTER_SERV **servp; 63 64 /* 65 * Mark all existing services. 66 */ 67 for (serv = master_head; serv != 0; serv = serv->next) 68 serv->flags |= MASTER_FLAG_MARK; 69 70 /* 71 * Read the master.cf configuration file. The master_conf() routine 72 * unmarks services upon update. New services are born with the mark bit 73 * off. After this, anything with the mark bit on should be removed. 74 */ 75 master_config(); 76 77 /* 78 * Delete all services that are still marked - they disappeared from the 79 * configuration file and are therefore no longer needed. 80 */ 81 for (servp = &master_head; (serv = *servp) != 0; /* void */ ) { 82 if ((serv->flags & MASTER_FLAG_MARK) != 0) { 83 *servp = serv->next; 84 master_stop_service(serv); 85 free_master_ent(serv); 86 } else { 87 servp = &serv->next; 88 } 89 } 90 } 91 92 /* master_config - read config file */ 93 94 void master_config(void) 95 { 96 MASTER_SERV *entry; 97 MASTER_SERV *serv; 98 99 #define STR_DIFF strcmp 100 #define STR_SAME !strcmp 101 #define SWAP(type,a,b) { type temp = a; a = b; b = temp; } 102 103 /* 104 * A service is identified by its endpoint name AND by its transport 105 * type, not just by its name alone. The name is unique within its 106 * transport type. XXX Service privacy is encoded in the service name. 107 */ 108 set_master_ent(); 109 while ((entry = get_master_ent()) != 0) { 110 if (msg_verbose) 111 print_master_ent(entry); 112 for (serv = master_head; serv != 0; serv = serv->next) 113 if (STR_SAME(serv->name, entry->name) && serv->type == entry->type) 114 break; 115 116 /* 117 * Add a new service entry. We do not really care in what order the 118 * service entries are kept in memory. 119 */ 120 if (serv == 0) { 121 entry->next = master_head; 122 master_head = entry; 123 master_start_service(entry); 124 } 125 126 /* 127 * Update an existing service entry. Make the current generation of 128 * child processes commit suicide whenever it is convenient. The next 129 * generation of child processes will run with the new configuration 130 * settings. 131 */ 132 else { 133 if ((serv->flags & MASTER_FLAG_MARK) == 0) 134 msg_warn("duplicate master.cf entry for service \"%s\" (%s) " 135 "-- using the last entry", serv->ext_name, serv->name); 136 else 137 serv->flags &= ~MASTER_FLAG_MARK; 138 if (entry->flags & MASTER_FLAG_CONDWAKE) 139 serv->flags |= MASTER_FLAG_CONDWAKE; 140 else 141 serv->flags &= ~MASTER_FLAG_CONDWAKE; 142 serv->wakeup_time = entry->wakeup_time; 143 serv->max_proc = entry->max_proc; 144 serv->throttle_delay = entry->throttle_delay; 145 SWAP(char *, serv->ext_name, entry->ext_name); 146 SWAP(char *, serv->path, entry->path); 147 SWAP(ARGV *, serv->args, entry->args); 148 SWAP(char *, serv->stress_param_val, entry->stress_param_val); 149 master_restart_service(serv, DO_CONF_RELOAD); 150 free_master_ent(entry); 151 } 152 } 153 end_master_ent(); 154 } 155