xref: /netbsd-src/external/ibm-public/postfix/dist/src/postconf/postconf_service.c (revision af56d1fe9956bd7c616e18c1b7f025f464618471)
1 /*	$NetBSD: postconf_service.c,v 1.1.1.1 2013/01/02 18:59:03 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	postconf_service 3
6 /* SUMMARY
7 /*	service-defined parameter name support
8 /* SYNOPSIS
9 /*	#include <postconf.h>
10 /*
11 /*	void	register_service_parameters()
12 /* DESCRIPTION
13 /*	Service-defined parameter names are created by appending
14 /*	postfix-defined suffixes to master.cf service names. All
15 /*	service-defined parameters have default values that are
16 /*	defined by a built-in parameter.
17 /*
18 /*	register_service_parameters() adds the service-defined parameters
19 /*	to the global name space. This function must be called after
20 /*	the built-in parameters are added to the global name space,
21 /*	and after the master.cf file is read.
22 /* DIAGNOSTICS
23 /*	Problems are reported to the standard error stream.
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 library. */
36 
37 #include <sys_defs.h>
38 #include <string.h>
39 
40 /* Utility library. */
41 
42 #include <msg.h>
43 #include <mymalloc.h>
44 #include <htable.h>
45 #include <vstring.h>
46 #include <stringops.h>
47 #include <argv.h>
48 
49 /* Global library. */
50 
51 #include <mail_params.h>
52 
53 /* Application-specific. */
54 
55 #include <postconf.h>
56 
57  /*
58   * Basename of programs in $daemon_directory. XXX These belong in a header
59   * file, or they should be made configurable.
60   */
61 #ifndef MAIL_PROGRAM_LOCAL
62 #define MAIL_PROGRAM_LOCAL	"local"
63 #define MAIL_PROGRAM_ERROR	"error"
64 #define MAIL_PROGRAM_VIRTUAL	"virtual"
65 #define MAIL_PROGRAM_SMTP	"smtp"
66 #define MAIL_PROGRAM_LMTP	"lmtp"
67 #define MAIL_PROGRAM_PIPE	"pipe"
68 #define MAIL_PROGRAM_SPAWN	"spawn"
69 #endif
70 
71  /*
72   * Ad-hoc name-value string pair.
73   */
74 typedef struct {
75     const char *name;
76     const char *value;
77 } PC_STRING_NV;
78 
79 #define STR(x) vstring_str(x)
80 
81 /* convert_service_parameter - get service parameter string value */
82 
83 static const char *convert_service_parameter(char *ptr)
84 {
85     return (STR(vstring_sprintf(param_string_buf, "$%s", ptr)));
86 }
87 
88 /* register_service_parameter - add one service parameter name and default */
89 
90 static void register_service_parameter(const char *service, const char *suffix,
91 				               const char *defparam)
92 {
93     char   *name = concatenate(service, suffix, (char *) 0);
94     PC_PARAM_NODE *node;
95 
96     /*
97      * Skip service parameter names that have built-in definitions. This
98      * happens with message delivery transports that have a non-default
99      * per-destination concurrency or recipient limit, such as local(8).
100      *
101      * Some parameters were tentatively flagged as built-in, but they are
102      * service parameters with their own default value. We don't change the
103      * default but we correct the parameter class.
104      */
105     if ((node = PC_PARAM_TABLE_FIND(param_table, name)) != 0) {
106 	PC_PARAM_CLASS_OVERRIDE(node, PC_PARAM_FLAG_SERVICE);
107     } else {
108 	PC_PARAM_TABLE_ENTER(param_table, name, PC_PARAM_FLAG_SERVICE,
109 			     (char *) defparam, convert_service_parameter);
110     }
111     myfree(name);
112 }
113 
114 /* register_service_parameters - add all service parameters with defaults */
115 
116 void    register_service_parameters(void)
117 {
118     const char *myname = "register_service_parameters";
119     static const PC_STRING_NV pipe_params[] = {
120 	/* suffix, default parameter name */
121 	_MAXTIME, VAR_COMMAND_MAXTIME,
122 #define service_params (pipe_params + 1)
123 	_XPORT_RCPT_LIMIT, VAR_XPORT_RCPT_LIMIT,
124 	_STACK_RCPT_LIMIT, VAR_STACK_RCPT_LIMIT,
125 	_XPORT_REFILL_LIMIT, VAR_XPORT_REFILL_LIMIT,
126 	_XPORT_REFILL_DELAY, VAR_XPORT_REFILL_DELAY,
127 	_DELIVERY_SLOT_COST, VAR_DELIVERY_SLOT_COST,
128 	_DELIVERY_SLOT_LOAN, VAR_DELIVERY_SLOT_LOAN,
129 	_DELIVERY_SLOT_DISCOUNT, VAR_DELIVERY_SLOT_DISCOUNT,
130 	_MIN_DELIVERY_SLOTS, VAR_MIN_DELIVERY_SLOTS,
131 	_INIT_DEST_CON, VAR_INIT_DEST_CON,
132 	_DEST_CON_LIMIT, VAR_DEST_CON_LIMIT,
133 	_DEST_RCPT_LIMIT, VAR_DEST_RCPT_LIMIT,
134 	_CONC_POS_FDBACK, VAR_CONC_POS_FDBACK,
135 	_CONC_NEG_FDBACK, VAR_CONC_NEG_FDBACK,
136 	_CONC_COHORT_LIM, VAR_CONC_COHORT_LIM,
137 	_DEST_RATE_DELAY, VAR_DEST_RATE_DELAY,
138 	0,
139     };
140     static const PC_STRING_NV spawn_params[] = {
141 	/* suffix, default parameter name */
142 	_MAXTIME, VAR_COMMAND_MAXTIME,
143 	0,
144     };
145     typedef struct {
146 	const char *progname;
147 	const PC_STRING_NV *params;
148     } PC_SERVICE_DEF;
149     static const PC_SERVICE_DEF service_defs[] = {
150 	MAIL_PROGRAM_LOCAL, service_params,
151 	MAIL_PROGRAM_ERROR, service_params,
152 	MAIL_PROGRAM_VIRTUAL, service_params,
153 	MAIL_PROGRAM_SMTP, service_params,
154 	MAIL_PROGRAM_LMTP, service_params,
155 	MAIL_PROGRAM_PIPE, pipe_params,
156 	MAIL_PROGRAM_SPAWN, spawn_params,
157 	0,
158     };
159     const PC_STRING_NV *sp;
160     const char *progname;
161     const char *service;
162     PC_MASTER_ENT *masterp;
163     ARGV   *argv;
164     const PC_SERVICE_DEF *sd;
165 
166     /*
167      * Sanity checks.
168      */
169     if (param_table == 0)
170 	msg_panic("%s: global parameter table is not initialized", myname);
171     if (master_table == 0)
172 	msg_panic("%s: master table is not initialized", myname);
173 
174     /*
175      * Extract service names from master.cf and generate service parameter
176      * information.
177      */
178     for (masterp = master_table; (argv = masterp->argv) != 0; masterp++) {
179 
180 	/*
181 	 * Add service parameters for message delivery transports or spawn
182 	 * programs.
183 	 */
184 	progname = argv->argv[7];
185 	for (sd = service_defs; sd->progname; sd++) {
186 	    if (strcmp(sd->progname, progname) == 0) {
187 		service = argv->argv[0];
188 		for (sp = sd->params; sp->name; sp++)
189 		    register_service_parameter(service, sp->name, sp->value);
190 		break;
191 	    }
192 	}
193     }
194 }
195