1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_event.h>
10 #include <ngx_mail.h>
11
12
13 static void *ngx_mail_core_create_main_conf(ngx_conf_t *cf);
14 static void *ngx_mail_core_create_srv_conf(ngx_conf_t *cf);
15 static char *ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent,
16 void *child);
17 static char *ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
18 void *conf);
19 static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
20 void *conf);
21 static char *ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd,
22 void *conf);
23
24
25 static ngx_command_t ngx_mail_core_commands[] = {
26
27 { ngx_string("server"),
28 NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
29 ngx_mail_core_server,
30 0,
31 0,
32 NULL },
33
34 { ngx_string("listen"),
35 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
36 ngx_mail_core_listen,
37 NGX_MAIL_SRV_CONF_OFFSET,
38 0,
39 NULL },
40
41 { ngx_string("protocol"),
42 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
43 ngx_mail_core_protocol,
44 NGX_MAIL_SRV_CONF_OFFSET,
45 0,
46 NULL },
47
48 { ngx_string("so_keepalive"),
49 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
50 ngx_conf_set_flag_slot,
51 NGX_MAIL_SRV_CONF_OFFSET,
52 offsetof(ngx_mail_core_srv_conf_t, so_keepalive),
53 NULL },
54
55 { ngx_string("timeout"),
56 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
57 ngx_conf_set_msec_slot,
58 NGX_MAIL_SRV_CONF_OFFSET,
59 offsetof(ngx_mail_core_srv_conf_t, timeout),
60 NULL },
61
62 { ngx_string("server_name"),
63 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
64 ngx_conf_set_str_slot,
65 NGX_MAIL_SRV_CONF_OFFSET,
66 offsetof(ngx_mail_core_srv_conf_t, server_name),
67 NULL },
68
69 ngx_null_command
70 };
71
72
73 static ngx_mail_module_t ngx_mail_core_module_ctx = {
74 NULL, /* protocol */
75
76 ngx_mail_core_create_main_conf, /* create main configuration */
77 NULL, /* init main configuration */
78
79 ngx_mail_core_create_srv_conf, /* create server configuration */
80 ngx_mail_core_merge_srv_conf /* merge server configuration */
81 };
82
83
84 ngx_module_t ngx_mail_core_module = {
85 NGX_MODULE_V1,
86 &ngx_mail_core_module_ctx, /* module context */
87 ngx_mail_core_commands, /* module directives */
88 NGX_MAIL_MODULE, /* module type */
89 NULL, /* init master */
90 NULL, /* init module */
91 NULL, /* init process */
92 NULL, /* init thread */
93 NULL, /* exit thread */
94 NULL, /* exit process */
95 NULL, /* exit master */
96 NGX_MODULE_V1_PADDING
97 };
98
99
100 static void *
101 ngx_mail_core_create_main_conf(ngx_conf_t *cf)
102 {
103 ngx_mail_core_main_conf_t *cmcf;
104
105 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t));
106 if (cmcf == NULL) {
107 return NGX_CONF_ERROR;
108 }
109
110 if (ngx_array_init(&cmcf->servers, cf->pool, 4,
111 sizeof(ngx_mail_core_srv_conf_t *))
112 != NGX_OK)
113 {
114 return NGX_CONF_ERROR;
115 }
116
117 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t))
118 != NGX_OK)
119 {
120 return NGX_CONF_ERROR;
121 }
122
123 return cmcf;
124 }
125
126
127 static void *
128 ngx_mail_core_create_srv_conf(ngx_conf_t *cf)
129 {
130 ngx_mail_core_srv_conf_t *cscf;
131
132 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t));
133 if (cscf == NULL) {
134 return NULL;
135 }
136
137 /*
138 * set by ngx_pcalloc():
139 *
140 * cscf->protocol = NULL;
141 */
142
143 cscf->timeout = NGX_CONF_UNSET_MSEC;
144 cscf->so_keepalive = NGX_CONF_UNSET;
145
146 return cscf;
147 }
148
149
150 static char *
151 ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
152 {
153 ngx_mail_core_srv_conf_t *prev = parent;
154 ngx_mail_core_srv_conf_t *conf = child;
155
156 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
157
158 ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
159
160
161 ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
162
163 if (conf->server_name.len == 0) {
164 conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN);
165 if (conf->server_name.data == NULL) {
166 return NGX_CONF_ERROR;
167 }
168
169 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN)
170 == -1)
171 {
172 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
173 "gethostname() failed");
174 return NGX_CONF_ERROR;
175 }
176
177 conf->server_name.len = ngx_strlen(conf->server_name.data);
178 }
179
180 if (conf->protocol == NULL) {
181 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
182 "unknown mail protocol for server in %s:%ui",
183 conf->file_name, conf->line);
184 return NGX_CONF_ERROR;
185 }
186
187 return NGX_CONF_OK;
188 }
189
190
191 static char *
192 ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
193 {
194 char *rv;
195 void *mconf;
196 ngx_uint_t m;
197 ngx_conf_t pcf;
198 ngx_mail_module_t *module;
199 ngx_mail_conf_ctx_t *ctx, *mail_ctx;
200 ngx_mail_core_srv_conf_t *cscf, **cscfp;
201 ngx_mail_core_main_conf_t *cmcf;
202
203 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
204 if (ctx == NULL) {
205 return NGX_CONF_ERROR;
206 }
207
208 mail_ctx = cf->ctx;
209 ctx->main_conf = mail_ctx->main_conf;
210
211 /* the server{}'s srv_conf */
212
213 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module);
214 if (ctx->srv_conf == NULL) {
215 return NGX_CONF_ERROR;
216 }
217
218 for (m = 0; ngx_modules[m]; m++) {
219 if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
220 continue;
221 }
222
223 module = ngx_modules[m]->ctx;
224
225 if (module->create_srv_conf) {
226 mconf = module->create_srv_conf(cf);
227 if (mconf == NULL) {
228 return NGX_CONF_ERROR;
229 }
230
231 ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf;
232 }
233 }
234
235 /* the server configuration context */
236
237 cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index];
238 cscf->ctx = ctx;
239
240 cscf->file_name = cf->conf_file->file.name.data;
241 cscf->line = cf->conf_file->line;
242
243 cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
244
245 cscfp = ngx_array_push(&cmcf->servers);
246 if (cscfp == NULL) {
247 return NGX_CONF_ERROR;
248 }
249
250 *cscfp = cscf;
251
252
253 /* parse inside server{} */
254
255 pcf = *cf;
256 cf->ctx = ctx;
257 cf->cmd_type = NGX_MAIL_SRV_CONF;
258
259 rv = ngx_conf_parse(cf, NULL);
260
261 *cf = pcf;
262
263 return rv;
264 }
265
266
267 /* AF_INET only */
268
269 static char *
270 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
271 {
272 ngx_mail_core_srv_conf_t *cscf = conf;
273
274 ngx_str_t *value;
275 ngx_url_t u;
276 ngx_uint_t i, m;
277 ngx_mail_listen_t *imls;
278 ngx_mail_module_t *module;
279 ngx_mail_core_main_conf_t *cmcf;
280
281 value = cf->args->elts;
282
283 ngx_memzero(&u, sizeof(ngx_url_t));
284
285 u.url = value[1];
286 u.listen = 1;
287
288 if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
289 if (u.err) {
290 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
291 "%s in \"%V\" of the \"listen\" directive",
292 u.err, &u.url);
293 }
294
295 return NGX_CONF_ERROR;
296 }
297
298 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);
299
300 imls = cmcf->listen.elts;
301
302 for (i = 0; i < cmcf->listen.nelts; i++) {
303
304 if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) {
305 continue;
306 }
307
308 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
309 "duplicate \"%V\" address and port pair", &u.url);
310 return NGX_CONF_ERROR;
311 }
312
313 imls = ngx_array_push(&cmcf->listen);
314 if (imls == NULL) {
315 return NGX_CONF_ERROR;
316 }
317
318 ngx_memzero(imls, sizeof(ngx_mail_listen_t));
319
320 imls->addr = u.addr.in_addr;
321 imls->port = u.port;
322 imls->family = AF_INET;
323 imls->ctx = cf->ctx;
324
325 for (m = 0; ngx_modules[m]; m++) {
326 if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
327 continue;
328 }
329
330 module = ngx_modules[m]->ctx;
331
332 if (module->protocol == NULL) {
333 continue;
334 }
335
336 for (i = 0; module->protocol->port[i]; i++) {
337 if (module->protocol->port[i] == u.port) {
338 cscf->protocol = module->protocol;
339 break;
340 }
341 }
342 }
343
344 if (cf->args->nelts == 2) {
345 return NGX_CONF_OK;
346 }
347
348 if (ngx_strcmp(value[2].data, "bind") == 0) {
349 imls->bind = 1;
350 return NGX_CONF_OK;
351 }
352
353 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
354 "the invalid \"%V\" parameter", &value[2]);
355 return NGX_CONF_ERROR;
356 }
357
358
359 static char *
360 ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
361 {
362 ngx_mail_core_srv_conf_t *cscf = conf;
363
364 ngx_str_t *value;
365 ngx_uint_t m;
366 ngx_mail_module_t *module;
367
368 value = cf->args->elts;
369
370 for (m = 0; ngx_modules[m]; m++) {
371 if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
372 continue;
373 }
374
375 module = ngx_modules[m]->ctx;
376
377 if (module->protocol
378 && ngx_strcmp(module->protocol->name.data, value[1].data) == 0)
379 {
380 cscf->protocol = module->protocol;
381
382 return NGX_CONF_OK;
383 }
384 }
385
386 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
387 "unknown protocol \"%V\"", &value[1]);
388 return NGX_CONF_ERROR;
389 }
390
391
392 char *
393 ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
394 {
395 char *p = conf;
396
397 ngx_str_t *c, *value;
398 ngx_uint_t i;
399 ngx_array_t *a;
400
401 a = (ngx_array_t *) (p + cmd->offset);
402
403 value = cf->args->elts;
404
405 for (i = 1; i < cf->args->nelts; i++) {
406 c = ngx_array_push(a);
407 if (c == NULL) {
408 return NGX_CONF_ERROR;
409 }
410
411 *c = value[i];
412 }
413
414 return NGX_CONF_OK;
415 }
416
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.