~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/mail/ngx_mail_core_module.c

Version: ~ [ nginx-0.6.26 ] ~ [ nginx-0.5.35 ] ~ [ nginx-0.5.20 ] ~ [ nginx-0.5.19 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.