blob: 9e4b30a08890d149fb83f9025046d9df35e5513d [file] [log] [blame]
Igor Sysoev88092572002-12-19 07:08:55 +00001
Igor Sysoevd90282d2004-09-28 08:34:51 +00002/*
Igor Sysoevff8da912004-09-29 16:00:49 +00003 * Copyright (C) Igor Sysoev
Igor Sysoevd90282d2004-09-28 08:34:51 +00004 */
5
6
Igor Sysoev88092572002-12-19 07:08:55 +00007#include <ngx_config.h>
Igor Sysoev88092572002-12-19 07:08:55 +00008#include <ngx_core.h>
Igor Sysoev88092572002-12-19 07:08:55 +00009
10
Igor Sysoevc1571722005-03-19 12:38:37 +000011static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last);
Igor Sysoev4d656dc2005-03-22 16:02:46 +000012static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf);
Igor Sysoevab517d52004-05-18 15:29:08 +000013static char *ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoev697d1ae2005-10-27 15:46:13 +000014static void ngx_conf_flush_files(ngx_cycle_t *cycle);
Igor Sysoevab517d52004-05-18 15:29:08 +000015
16
17static ngx_command_t ngx_conf_commands[] = {
18
19 { ngx_string("include"),
20 NGX_ANY_CONF|NGX_CONF_TAKE1,
21 ngx_conf_include,
22 0,
23 0,
24 NULL },
25
26 ngx_null_command
27};
28
29
30ngx_module_t ngx_conf_module = {
Igor Sysoev899b44e2005-05-12 14:58:06 +000031 NGX_MODULE_V1,
Igor Sysoevab517d52004-05-18 15:29:08 +000032 NULL, /* module context */
33 ngx_conf_commands, /* module directives */
34 NGX_CONF_MODULE, /* module type */
Igor Sysoeve5733802005-09-08 14:36:09 +000035 NULL, /* init master */
Igor Sysoevab517d52004-05-18 15:29:08 +000036 NULL, /* init module */
Igor Sysoeve5733802005-09-08 14:36:09 +000037 NULL, /* init process */
38 NULL, /* init thread */
39 NULL, /* exit thread */
Igor Sysoev697d1ae2005-10-27 15:46:13 +000040 ngx_conf_flush_files, /* exit process */
Igor Sysoeve5733802005-09-08 14:36:09 +000041 NULL, /* exit master */
42 NGX_MODULE_V1_PADDING
Igor Sysoevab517d52004-05-18 15:29:08 +000043};
44
45
Igor Sysoevab517d52004-05-18 15:29:08 +000046/* The ten fixed arguments */
Igor Sysoevdc9dd432003-10-22 16:38:26 +000047
Igor Sysoev88092572002-12-19 07:08:55 +000048static int argument_number[] = {
49 NGX_CONF_NOARGS,
50 NGX_CONF_TAKE1,
Igor Sysoevdc9dd432003-10-22 16:38:26 +000051 NGX_CONF_TAKE2,
52 NGX_CONF_TAKE3,
53 NGX_CONF_TAKE4,
54 NGX_CONF_TAKE5,
55 NGX_CONF_TAKE6,
Igor Sysoev43f13192004-04-12 16:38:09 +000056 NGX_CONF_TAKE7
Igor Sysoev88092572002-12-19 07:08:55 +000057};
58
Igor Sysoev960ffa42002-12-26 07:24:21 +000059
Igor Sysoev4d656dc2005-03-22 16:02:46 +000060char *
61ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
Igor Sysoev88092572002-12-19 07:08:55 +000062{
Igor Sysoev4e9393a2003-01-09 05:36:00 +000063 char *rv;
Igor Sysoev960ffa42002-12-26 07:24:21 +000064 ngx_fd_t fd;
Igor Sysoevc1571722005-03-19 12:38:37 +000065 ngx_int_t rc;
Igor Sysoev6d16e1e2006-04-05 13:40:54 +000066 ngx_buf_t *b;
Igor Sysoev31eb8c02005-09-23 11:02:22 +000067 ngx_uint_t block;
Igor Sysoev88092572002-12-19 07:08:55 +000068 ngx_conf_file_t *prev;
69
Igor Sysoev9d639522003-07-07 06:11:50 +000070#if (NGX_SUPPRESS_WARN)
71 fd = NGX_INVALID_FILE;
72 prev = NULL;
73#endif
74
Igor Sysoev88092572002-12-19 07:08:55 +000075 if (filename) {
76
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000077 /* open configuration file */
78
Igor Sysoev50034b82007-01-18 20:15:09 +000079 fd = ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
Igor Sysoev88092572002-12-19 07:08:55 +000080 if (fd == NGX_INVALID_FILE) {
Igor Sysoevc31a9bb2005-11-26 10:11:11 +000081 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
Igor Sysoev305a9d82005-12-26 17:07:48 +000082 ngx_open_file_n " \"%s\" failed",
83 filename->data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000084 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +000085 }
86
Igor Sysoeva6717c42002-12-23 06:29:22 +000087 prev = cf->conf_file;
Igor Sysoevc1571722005-03-19 12:38:37 +000088
89 cf->conf_file = ngx_palloc(cf->pool, sizeof(ngx_conf_file_t));
90 if (cf->conf_file == NULL) {
Igor Sysoev369145c2004-05-28 15:49:23 +000091 return NGX_CONF_ERROR;
92 }
Igor Sysoev88092572002-12-19 07:08:55 +000093
Igor Sysoevf2e676a2003-11-16 21:49:42 +000094 if (ngx_fd_info(fd, &cf->conf_file->file.info) == -1) {
Igor Sysoeva6717c42002-12-23 06:29:22 +000095 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
Igor Sysoev1b735832004-11-11 14:07:14 +000096 ngx_fd_info_n " \"%s\" failed", filename->data);
Igor Sysoeva6717c42002-12-23 06:29:22 +000097 }
98
Igor Sysoev6d16e1e2006-04-05 13:40:54 +000099 b = ngx_calloc_buf(cf->pool);
100 if (b == NULL) {
Igor Sysoev369145c2004-05-28 15:49:23 +0000101 return NGX_CONF_ERROR;
102 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000103
Igor Sysoev6d16e1e2006-04-05 13:40:54 +0000104 cf->conf_file->buffer = b;
105
106 b->start = ngx_alloc(ngx_pagesize, cf->log);
107 if (b->start == NULL) {
108 return NGX_CONF_ERROR;
109 }
110
111 b->pos = b->start;
112 b->last = b->start;
113 b->end = b->last + ngx_pagesize;
114 b->temporary = 1;
115
Igor Sysoeva6717c42002-12-23 06:29:22 +0000116 cf->conf_file->file.fd = fd;
117 cf->conf_file->file.name.len = filename->len;
118 cf->conf_file->file.name.data = filename->data;
Igor Sysoev9d639522003-07-07 06:11:50 +0000119 cf->conf_file->file.offset = 0;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000120 cf->conf_file->file.log = cf->log;;
121 cf->conf_file->line = 1;
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000122
123 block = 0;
124
125 } else {
126 block = 1;
Igor Sysoev88092572002-12-19 07:08:55 +0000127 }
128
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000129
Igor Sysoev88092572002-12-19 07:08:55 +0000130 for ( ;; ) {
131 rc = ngx_conf_read_token(cf);
132
Igor Sysoev369145c2004-05-28 15:49:23 +0000133 /*
Igor Sysoev1b735832004-11-11 14:07:14 +0000134 * ngx_conf_read_token() may return
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000135 *
Igor Sysoev1b735832004-11-11 14:07:14 +0000136 * NGX_ERROR there is error
137 * NGX_OK the token terminated by ";" was found
138 * NGX_CONF_BLOCK_START the token terminated by "{" was found
139 * NGX_CONF_BLOCK_DONE the "}" was found
140 * NGX_CONF_FILE_DONE the configuration file is done
Igor Sysoev369145c2004-05-28 15:49:23 +0000141 */
Igor Sysoev88092572002-12-19 07:08:55 +0000142
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000143 if (rc == NGX_ERROR) {
Igor Sysoev9d639522003-07-07 06:11:50 +0000144 break;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000145 }
146
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000147 if (rc == NGX_CONF_BLOCK_DONE) {
148 block = 0;
149 }
150
151 if (rc == NGX_CONF_FILE_DONE && block) {
152 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoevdd15b552007-01-07 22:44:56 +0000153 "unexpected end of file in %s:%ui, expecting \"}\"",
154 cf->conf_file->file.name.data,
155 cf->conf_file->line);
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000156 rc = NGX_ERROR;
157 break;
158 }
159
Igor Sysoev1b735832004-11-11 14:07:14 +0000160 if (rc != NGX_OK && rc != NGX_CONF_BLOCK_START) {
Igor Sysoev9d639522003-07-07 06:11:50 +0000161 break;
Igor Sysoev88092572002-12-19 07:08:55 +0000162 }
163
Igor Sysoev88092572002-12-19 07:08:55 +0000164 if (cf->handler) {
165
Igor Sysoev1b735832004-11-11 14:07:14 +0000166 /*
167 * the custom handler, i.e., that is used in the http's
168 * "types { ... }" directive
169 */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000170
Igor Sysoev79a80482003-05-14 17:13:13 +0000171 rv = (*cf->handler)(cf, NULL, cf->handler_conf);
172 if (rv == NGX_CONF_OK) {
173 continue;
Igor Sysoevc1571722005-03-19 12:38:37 +0000174 }
Igor Sysoev79a80482003-05-14 17:13:13 +0000175
Igor Sysoevc1571722005-03-19 12:38:37 +0000176 if (rv == NGX_CONF_ERROR) {
Igor Sysoev9d639522003-07-07 06:11:50 +0000177 rc = NGX_ERROR;
178 break;
Igor Sysoev88092572002-12-19 07:08:55 +0000179 }
Igor Sysoev88092572002-12-19 07:08:55 +0000180
Igor Sysoev88092572002-12-19 07:08:55 +0000181 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoevdd15b552007-01-07 22:44:56 +0000182 "%s in %s:%ui",
183 rv, cf->conf_file->file.name.data,
184 cf->conf_file->line);
Igor Sysoev9d639522003-07-07 06:11:50 +0000185 rc = NGX_ERROR;
186 break;
Igor Sysoev88092572002-12-19 07:08:55 +0000187 }
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000188
Igor Sysoevc1571722005-03-19 12:38:37 +0000189
190 rc = ngx_conf_handler(cf, rc);
191
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000192 if (rc == NGX_ERROR) {
193 break;
194 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000195 }
Igor Sysoev88092572002-12-19 07:08:55 +0000196
Igor Sysoevc1571722005-03-19 12:38:37 +0000197
Igor Sysoev88092572002-12-19 07:08:55 +0000198 if (filename) {
Igor Sysoev6d16e1e2006-04-05 13:40:54 +0000199 ngx_free(cf->conf_file->buffer->start);
Igor Sysoevd3283ff2005-12-05 13:18:09 +0000200
Igor Sysoeva6717c42002-12-23 06:29:22 +0000201 cf->conf_file = prev;
Igor Sysoev88092572002-12-19 07:08:55 +0000202
203 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000204 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +0000205 ngx_close_file_n " %s failed",
206 cf->conf_file->file.name.data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000207 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000208 }
209 }
210
Igor Sysoev9d639522003-07-07 06:11:50 +0000211 if (rc == NGX_ERROR) {
212 return NGX_CONF_ERROR;
213 }
214
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000215 return NGX_CONF_OK;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000216}
Igor Sysoev88092572002-12-19 07:08:55 +0000217
Igor Sysoev88092572002-12-19 07:08:55 +0000218
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000219static ngx_int_t
220ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
Igor Sysoevc1571722005-03-19 12:38:37 +0000221{
222 char *rv;
223 void *conf, **confp;
Igor Sysoevac72bd12006-05-04 15:32:46 +0000224 ngx_uint_t i, multi;
Igor Sysoevc1571722005-03-19 12:38:37 +0000225 ngx_str_t *name;
226 ngx_command_t *cmd;
227
228 name = cf->args->elts;
229
Igor Sysoevac72bd12006-05-04 15:32:46 +0000230 multi = 0;
231
Igor Sysoevc1571722005-03-19 12:38:37 +0000232 for (i = 0; ngx_modules[i]; i++) {
233
234 /* look up the directive in the appropriate modules */
235
236 if (ngx_modules[i]->type != NGX_CONF_MODULE
237 && ngx_modules[i]->type != cf->module_type)
238 {
239 continue;
240 }
241
242 cmd = ngx_modules[i]->commands;
243 if (cmd == NULL) {
244 continue;
245 }
246
Igor Sysoevac72bd12006-05-04 15:32:46 +0000247 for ( /* void */ ; cmd->name.len; cmd++) {
Igor Sysoevc1571722005-03-19 12:38:37 +0000248
Igor Sysoevac72bd12006-05-04 15:32:46 +0000249 if (name->len != cmd->name.len) {
250 continue;
251 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000252
Igor Sysoevac72bd12006-05-04 15:32:46 +0000253 if (ngx_strcmp(name->data, cmd->name.data) != 0) {
254 continue;
255 }
256
257
258 /* is the directive's location right ? */
259
260 if (!(cmd->type & cf->cmd_type)) {
261 if (cmd->type & NGX_CONF_MULTI) {
262 multi = 1;
263 continue;
Igor Sysoevc1571722005-03-19 12:38:37 +0000264 }
265
Igor Sysoevac72bd12006-05-04 15:32:46 +0000266 goto not_allowed;
267 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000268
Igor Sysoevac72bd12006-05-04 15:32:46 +0000269 if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {
270 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
271 "directive \"%s\" in %s:%ui "
272 "is not terminated by \";\"",
273 name->data, cf->conf_file->file.name.data,
274 cf->conf_file->line);
275 return NGX_ERROR;
276 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000277
Igor Sysoevac72bd12006-05-04 15:32:46 +0000278 if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {
279 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
280 "directive \"%s\" in %s:%ui "
281 "has not the opening \"{\"",
282 name->data, cf->conf_file->file.name.data,
283 cf->conf_file->line);
284 return NGX_ERROR;
285 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000286
Igor Sysoevac72bd12006-05-04 15:32:46 +0000287 /* is the directive's argument count right ? */
Igor Sysoevc1571722005-03-19 12:38:37 +0000288
Igor Sysoevac72bd12006-05-04 15:32:46 +0000289 if (!(cmd->type & NGX_CONF_ANY)) {
Igor Sysoevc1571722005-03-19 12:38:37 +0000290
Igor Sysoevac72bd12006-05-04 15:32:46 +0000291 if (cmd->type & NGX_CONF_FLAG) {
292
293 if (cf->args->nelts != 2) {
294 goto invalid;
Igor Sysoevc1571722005-03-19 12:38:37 +0000295 }
296
297 } else if (cmd->type & NGX_CONF_1MORE) {
298
Igor Sysoevac72bd12006-05-04 15:32:46 +0000299 if (cf->args->nelts < 2) {
300 goto invalid;
Igor Sysoevc1571722005-03-19 12:38:37 +0000301 }
302
303 } else if (cmd->type & NGX_CONF_2MORE) {
304
Igor Sysoevac72bd12006-05-04 15:32:46 +0000305 if (cf->args->nelts < 3) {
306 goto invalid;
Igor Sysoevc1571722005-03-19 12:38:37 +0000307 }
308
Igor Sysoevac72bd12006-05-04 15:32:46 +0000309 } else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {
310
311 goto invalid;
312
313 } else if (!(cmd->type & argument_number[cf->args->nelts - 1]))
Igor Sysoevc1571722005-03-19 12:38:37 +0000314 {
Igor Sysoevac72bd12006-05-04 15:32:46 +0000315 goto invalid;
Igor Sysoevc1571722005-03-19 12:38:37 +0000316 }
Igor Sysoevac72bd12006-05-04 15:32:46 +0000317 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000318
Igor Sysoevac72bd12006-05-04 15:32:46 +0000319 /* set up the directive's configuration context */
320
321 conf = NULL;
322
323 if (cmd->type & NGX_DIRECT_CONF) {
324 conf = ((void **) cf->ctx)[ngx_modules[i]->index];
325
326 } else if (cmd->type & NGX_MAIN_CONF) {
327 conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
328
329 } else if (cf->ctx) {
330 confp = *(void **) ((char *) cf->ctx + cmd->conf);
331
332 if (confp) {
333 conf = confp[ngx_modules[i]->ctx_index];
Igor Sysoevc1571722005-03-19 12:38:37 +0000334 }
Igor Sysoevac72bd12006-05-04 15:32:46 +0000335 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000336
Igor Sysoevac72bd12006-05-04 15:32:46 +0000337 rv = cmd->set(cf, cmd, conf);
Igor Sysoevc1571722005-03-19 12:38:37 +0000338
Igor Sysoevac72bd12006-05-04 15:32:46 +0000339 if (rv == NGX_CONF_OK) {
340 return NGX_OK;
341 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000342
Igor Sysoevac72bd12006-05-04 15:32:46 +0000343 if (rv == NGX_CONF_ERROR) {
Igor Sysoevc1571722005-03-19 12:38:37 +0000344 return NGX_ERROR;
345 }
346
Igor Sysoevac72bd12006-05-04 15:32:46 +0000347 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
348 "the \"%s\" directive %s in %s:%ui",
349 name->data, rv, cf->conf_file->file.name.data,
350 cf->conf_file->line);
351
352 return NGX_ERROR;
Igor Sysoevc1571722005-03-19 12:38:37 +0000353 }
354 }
355
Igor Sysoevac72bd12006-05-04 15:32:46 +0000356 if (multi == 0) {
357 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
358 "unknown directive \"%s\" in %s:%ui",
359 name->data, cf->conf_file->file.name.data,
360 cf->conf_file->line);
361
362 return NGX_ERROR;
363 }
364
365not_allowed:
366
Igor Sysoevc1571722005-03-19 12:38:37 +0000367 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoevac72bd12006-05-04 15:32:46 +0000368 "directive \"%s\" in %s:%ui "
369 "is not allowed here",
370 name->data, cf->conf_file->file.name.data,
371 cf->conf_file->line);
372 return NGX_ERROR;
373
374invalid:
375
376 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
377 "invalid number arguments in "
378 "directive \"%s\" in %s:%ui",
Igor Sysoevc1571722005-03-19 12:38:37 +0000379 name->data, cf->conf_file->file.name.data,
380 cf->conf_file->line);
381
382 return NGX_ERROR;
383}
384
385
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000386static ngx_int_t
387ngx_conf_read_token(ngx_conf_t *cf)
Igor Sysoev88092572002-12-19 07:08:55 +0000388{
Igor Sysoev10a543a2004-03-16 07:10:12 +0000389 u_char *start, ch, *src, *dst;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000390 int len;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000391 int found, need_space, last_space, sharp_comment, variable;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000392 int quoted, s_quoted, d_quoted;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000393 ssize_t n;
394 ngx_str_t *word;
Igor Sysoev369145c2004-05-28 15:49:23 +0000395 ngx_buf_t *b;
Igor Sysoev88092572002-12-19 07:08:55 +0000396
Igor Sysoeva6717c42002-12-23 06:29:22 +0000397 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000398 need_space = 0;
399 last_space = 1;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000400 sharp_comment = 0;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000401 variable = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000402 quoted = s_quoted = d_quoted = 0;
403
404 cf->args->nelts = 0;
Igor Sysoev369145c2004-05-28 15:49:23 +0000405 b = cf->conf_file->buffer;
406 start = b->pos;
Igor Sysoev88092572002-12-19 07:08:55 +0000407
Igor Sysoev295bb632002-12-23 18:22:18 +0000408 for ( ;; ) {
Igor Sysoev88092572002-12-19 07:08:55 +0000409
Igor Sysoev369145c2004-05-28 15:49:23 +0000410 if (b->pos >= b->last) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000411 if (cf->conf_file->file.offset
Igor Sysoevaa828612005-02-09 14:31:07 +0000412 >= ngx_file_size(&cf->conf_file->file.info))
413 {
414 if (cf->args->nelts > 0) {
415 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoev02f742b2005-04-08 15:18:55 +0000416 "unexpected end of file in %s:%ui, "
Igor Sysoevaa828612005-02-09 14:31:07 +0000417 "expecting \";\" or \"}\"",
418 cf->conf_file->file.name.data,
419 cf->conf_file->line);
420 return NGX_ERROR;
421 }
422
Igor Sysoev960ffa42002-12-26 07:24:21 +0000423 return NGX_CONF_FILE_DONE;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000424 }
425
Igor Sysoev369145c2004-05-28 15:49:23 +0000426 if (b->pos - start) {
427 ngx_memcpy(b->start, start, b->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000428 }
429
Igor Sysoeva6717c42002-12-23 06:29:22 +0000430 n = ngx_read_file(&cf->conf_file->file,
Igor Sysoev369145c2004-05-28 15:49:23 +0000431 b->start + (b->pos - start),
432 b->end - (b->start + (b->pos - start)),
Igor Sysoev88092572002-12-19 07:08:55 +0000433 cf->conf_file->file.offset);
434
435 if (n == NGX_ERROR) {
436 return NGX_ERROR;
437 }
438
Igor Sysoev369145c2004-05-28 15:49:23 +0000439 b->pos = b->start + (b->pos - start);
440 start = b->start;
441 b->last = b->pos + n;
Igor Sysoev88092572002-12-19 07:08:55 +0000442 }
443
Igor Sysoev369145c2004-05-28 15:49:23 +0000444 ch = *b->pos++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000445
Igor Sysoev88092572002-12-19 07:08:55 +0000446 if (ch == LF) {
447 cf->conf_file->line++;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000448
449 if (sharp_comment) {
450 sharp_comment = 0;
451 }
452 }
453
454 if (sharp_comment) {
455 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000456 }
457
Igor Sysoev295bb632002-12-23 18:22:18 +0000458 if (quoted) {
459 quoted = 0;
460 continue;
461 }
462
Igor Sysoeva6717c42002-12-23 06:29:22 +0000463 if (need_space) {
464 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
465 last_space = 1;
466 need_space = 0;
467 continue;
468 }
469
Igor Sysoev1b735832004-11-11 14:07:14 +0000470 if (ch == ';') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000471 return NGX_OK;
472 }
473
Igor Sysoev1b735832004-11-11 14:07:14 +0000474 if (ch == '{') {
475 return NGX_CONF_BLOCK_START;
476 }
477
Igor Sysoevc31a9bb2005-11-26 10:11:11 +0000478 if (ch == ')') {
479 last_space = 1;
480 need_space = 0;
Igor Sysoev78329332003-11-10 17:17:31 +0000481
Igor Sysoevc31a9bb2005-11-26 10:11:11 +0000482 } else {
483 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
484 "unexpected \"%c\" in %s:%ui",
485 ch, cf->conf_file->file.name.data,
486 cf->conf_file->line);
487
488 return NGX_ERROR;
489 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000490 }
491
Igor Sysoev88092572002-12-19 07:08:55 +0000492 if (last_space) {
Igor Sysoev88092572002-12-19 07:08:55 +0000493 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000494 continue;
495 }
496
Igor Sysoev369145c2004-05-28 15:49:23 +0000497 start = b->pos - 1;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000498
499 switch (ch) {
500
Igor Sysoev295bb632002-12-23 18:22:18 +0000501 case ';':
502 case '{':
Igor Sysoev960ffa42002-12-26 07:24:21 +0000503 if (cf->args->nelts == 0) {
504 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoev02f742b2005-04-08 15:18:55 +0000505 "unexpected \"%c\" in %s:%ui",
Igor Sysoev960ffa42002-12-26 07:24:21 +0000506 ch, cf->conf_file->file.name.data,
507 cf->conf_file->line);
508 return NGX_ERROR;
509 }
510
Igor Sysoev1b735832004-11-11 14:07:14 +0000511 if (ch == '{') {
512 return NGX_CONF_BLOCK_START;
513 }
514
Igor Sysoev295bb632002-12-23 18:22:18 +0000515 return NGX_OK;
516
Igor Sysoev960ffa42002-12-26 07:24:21 +0000517 case '}':
Igor Sysoev4959ec42005-05-23 12:07:45 +0000518 if (cf->args->nelts != 0) {
Igor Sysoev960ffa42002-12-26 07:24:21 +0000519 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoev02f742b2005-04-08 15:18:55 +0000520 "unexpected \"}\" in %s:%ui",
Igor Sysoev960ffa42002-12-26 07:24:21 +0000521 cf->conf_file->file.name.data,
522 cf->conf_file->line);
523 return NGX_ERROR;
524 }
525
526 return NGX_CONF_BLOCK_DONE;
527
528 case '#':
529 sharp_comment = 1;
530 continue;
531
Igor Sysoeva6717c42002-12-23 06:29:22 +0000532 case '\\':
533 quoted = 1;
534 last_space = 0;
535 continue;
536
537 case '"':
Igor Sysoev88092572002-12-19 07:08:55 +0000538 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000539 d_quoted = 1;
540 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000541 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000542
Igor Sysoeva6717c42002-12-23 06:29:22 +0000543 case '\'':
544 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000545 s_quoted = 1;
546 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000547 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000548
Igor Sysoeva6717c42002-12-23 06:29:22 +0000549 default:
550 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000551 }
552
553 } else {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000554 if (ch == '{' && variable) {
555 continue;
556 }
557
558 variable = 0;
559
Igor Sysoeva6717c42002-12-23 06:29:22 +0000560 if (ch == '\\') {
561 quoted = 1;
562 continue;
563 }
Igor Sysoev88092572002-12-19 07:08:55 +0000564
Igor Sysoev899b44e2005-05-12 14:58:06 +0000565 if (ch == '$') {
566 variable = 1;
567 continue;
568 }
569
Igor Sysoeva6717c42002-12-23 06:29:22 +0000570 if (d_quoted) {
571 if (ch == '"') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000572 d_quoted = 0;
573 need_space = 1;
574 found = 1;
575 }
576
577 } else if (s_quoted) {
578 if (ch == '\'') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000579 s_quoted = 0;
580 need_space = 1;
581 found = 1;
582 }
583
584 } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
585 || ch == ';' || ch == '{') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000586 last_space = 1;
587 found = 1;
588 }
589
590 if (found) {
Igor Sysoevc1571722005-03-19 12:38:37 +0000591 word = ngx_array_push(cf->args);
592 if (word == NULL) {
Igor Sysoev369145c2004-05-28 15:49:23 +0000593 return NGX_ERROR;
594 }
595
Igor Sysoevc1571722005-03-19 12:38:37 +0000596 word->data = ngx_palloc(cf->pool, b->pos - start + 1);
597 if (word->data == NULL) {
Igor Sysoev369145c2004-05-28 15:49:23 +0000598 return NGX_ERROR;
599 }
Igor Sysoev88092572002-12-19 07:08:55 +0000600
Igor Sysoev295bb632002-12-23 18:22:18 +0000601 for (dst = word->data, src = start, len = 0;
Igor Sysoev369145c2004-05-28 15:49:23 +0000602 src < b->pos - 1;
Igor Sysoev295bb632002-12-23 18:22:18 +0000603 len++)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000604 {
605 if (*src == '\\') {
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000606 switch (src[1]) {
607 case '"':
608 case '\'':
609 case '\\':
610 src++;
611 break;
612
613 case 't':
614 *dst++ = '\t';
615 src += 2;
616 continue;
617
618 case 'r':
619 *dst++ = '\r';
620 src += 2;
621 continue;
622
623 case 'n':
624 *dst++ = '\n';
625 src += 2;
626 continue;
627 }
628
Igor Sysoeva6717c42002-12-23 06:29:22 +0000629 }
Igor Sysoev88092572002-12-19 07:08:55 +0000630 *dst++ = *src++;
631 }
632 *dst = '\0';
Igor Sysoev295bb632002-12-23 18:22:18 +0000633 word->len = len;
Igor Sysoev88092572002-12-19 07:08:55 +0000634
Igor Sysoev1b735832004-11-11 14:07:14 +0000635 if (ch == ';') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000636 return NGX_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000637 }
638
Igor Sysoev1b735832004-11-11 14:07:14 +0000639 if (ch == '{') {
640 return NGX_CONF_BLOCK_START;
641 }
642
Igor Sysoeva6717c42002-12-23 06:29:22 +0000643 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000644 }
Igor Sysoev88092572002-12-19 07:08:55 +0000645 }
646 }
647}
648
Igor Sysoev88092572002-12-19 07:08:55 +0000649
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000650static char *
651ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoevab517d52004-05-18 15:29:08 +0000652{
Igor Sysoev97c2f462006-10-02 08:46:45 +0000653 char *rv;
654 ngx_int_t n;
655 ngx_str_t *value, file;
656 ngx_glob_t gl;
Igor Sysoevab517d52004-05-18 15:29:08 +0000657
658 value = cf->args->elts;
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000659 file = value[1];
Igor Sysoevab517d52004-05-18 15:29:08 +0000660
Igor Sysoev97c2f462006-10-02 08:46:45 +0000661 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
662
Igor Sysoevc2068d02005-10-19 12:33:58 +0000663 if (ngx_conf_full_name(cf->cycle, &file) == NGX_ERROR) {
Igor Sysoevab517d52004-05-18 15:29:08 +0000664 return NGX_CONF_ERROR;
665 }
666
Igor Sysoev97c2f462006-10-02 08:46:45 +0000667 ngx_memzero(&gl, sizeof(ngx_glob_t));
Igor Sysoevab517d52004-05-18 15:29:08 +0000668
Igor Sysoev97c2f462006-10-02 08:46:45 +0000669 gl.pattern = file.data;
670 gl.log = cf->log;
671
672 if (ngx_open_glob(&gl) != NGX_OK) {
673 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
674 ngx_open_glob_n " \"%s\" failed", file.data);
675 return NGX_CONF_ERROR;
676 }
677
678 rv = NGX_CONF_OK;
679
680 for ( ;; ) {
681 n = ngx_read_glob(&gl, &file);
682
683 if (n != NGX_OK) {
684 break;
685 }
686
687 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
688
689 rv = ngx_conf_parse(cf, &file);
690
691 if (rv != NGX_CONF_OK) {
692 break;
693 }
694 }
695
696 ngx_close_glob(&gl);
697
698 return rv;
Igor Sysoevab517d52004-05-18 15:29:08 +0000699}
700
701
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000702ngx_int_t
703ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name)
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000704{
705 u_char *p;
706 ngx_str_t old;
707
708 if (name->data[0] == '/') {
709 return NGX_OK;
710 }
711
Igor Sysoev1b735832004-11-11 14:07:14 +0000712#if (NGX_WIN32)
713
714 if (name->len > 2
715 && name->data[1] == ':'
716 && ((name->data[0] >= 'a' && name->data[0] <= 'z')
717 || (name->data[0] >= 'A' && name->data[0] <= 'Z')))
718 {
719 return NGX_OK;
720 }
721
722#endif
723
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000724 old = *name;
725
726 name->len = cycle->root.len + old.len;
727
Igor Sysoev9e580192006-02-01 18:22:15 +0000728 name->data = ngx_palloc(cycle->pool, name->len + 1);
729 if (name->data == NULL) {
730 return NGX_ERROR;
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000731 }
732
733 p = ngx_cpymem(name->data, cycle->root.data, cycle->root.len),
734 ngx_cpystrn(p, old.data, old.len + 1);
735
736 return NGX_OK;
737}
738
739
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000740ngx_open_file_t *
741ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
Igor Sysoev890fc962003-07-20 21:15:59 +0000742{
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000743 ngx_str_t full;
Igor Sysoev10a543a2004-03-16 07:10:12 +0000744 ngx_uint_t i;
Igor Sysoevb9e34412004-09-03 15:50:30 +0000745 ngx_list_part_t *part;
Igor Sysoev890fc962003-07-20 21:15:59 +0000746 ngx_open_file_t *file;
747
Igor Sysoevaad1b892004-10-03 20:02:06 +0000748#if (NGX_SUPPRESS_WARN)
749 full.len = 0;
750 full.data = NULL;
751#endif
752
Igor Sysoev890fc962003-07-20 21:15:59 +0000753 if (name) {
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000754 full = *name;
755
756 if (ngx_conf_full_name(cycle, &full) == NGX_ERROR) {
757 return NULL;
758 }
759
Igor Sysoevb9e34412004-09-03 15:50:30 +0000760 part = &cycle->open_files.part;
761 file = part->elts;
762
763 for (i = 0; /* void */ ; i++) {
764
765 if (i >= part->nelts) {
766 if (part->next == NULL) {
767 break;
768 }
769 part = part->next;
770 file = part->elts;
771 i = 0;
772 }
773
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000774 if (full.len != file[i].name.len) {
Igor Sysoev890fc962003-07-20 21:15:59 +0000775 continue;
776 }
777
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000778 if (ngx_strcmp(full.data, file[i].name.data) == 0) {
Igor Sysoev890fc962003-07-20 21:15:59 +0000779 return &file[i];
780 }
781 }
782 }
783
Igor Sysoevc1571722005-03-19 12:38:37 +0000784 file = ngx_list_push(&cycle->open_files);
785 if (file == NULL) {
Igor Sysoev369145c2004-05-28 15:49:23 +0000786 return NULL;
787 }
788
Igor Sysoev890fc962003-07-20 21:15:59 +0000789 if (name) {
Igor Sysoev4bed15b2004-09-30 19:44:38 +0000790 file->fd = NGX_INVALID_FILE;
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000791 file->name = full;
792
Igor Sysoev980a9242004-09-05 19:54:02 +0000793 } else {
Igor Sysoevaad1b892004-10-03 20:02:06 +0000794 file->fd = ngx_stderr_fileno;
Igor Sysoev980a9242004-09-05 19:54:02 +0000795 file->name.len = 0;
796 file->name.data = NULL;
Igor Sysoev890fc962003-07-20 21:15:59 +0000797 }
798
Igor Sysoev697d1ae2005-10-27 15:46:13 +0000799 file->buffer = NULL;
800
Igor Sysoev890fc962003-07-20 21:15:59 +0000801 return file;
802}
803
804
Igor Sysoev697d1ae2005-10-27 15:46:13 +0000805static void
806ngx_conf_flush_files(ngx_cycle_t *cycle)
807{
808 ngx_uint_t i;
809 ngx_list_part_t *part;
810 ngx_open_file_t *file;
811
812 ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "flush files");
813
814 part = &cycle->open_files.part;
815 file = part->elts;
816
817 for (i = 0; /* void */ ; i++) {
818
819 if (i >= part->nelts) {
820 if (part->next == NULL) {
821 break;
822 }
823 part = part->next;
824 file = part->elts;
825 i = 0;
826 }
827
828 if (file[i].buffer == NULL || file[i].pos - file[i].buffer == 0) {
829 continue;
830 }
831
832 ngx_write_fd(file[i].fd, file[i].buffer, file[i].pos - file[i].buffer);
833 }
834}
835
836
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000837void ngx_cdecl
838ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf, ngx_err_t err,
839 char *fmt, ...)
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000840{
Igor Sysoev1b735832004-11-11 14:07:14 +0000841 u_char errstr[NGX_MAX_CONF_ERRSTR], *buf, *last;
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000842 va_list args;
843
Igor Sysoev1b735832004-11-11 14:07:14 +0000844 last = errstr + NGX_MAX_CONF_ERRSTR;
845
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000846 va_start(args, fmt);
Igor Sysoev1b735832004-11-11 14:07:14 +0000847 buf = ngx_vsnprintf(errstr, last - errstr, fmt, args);
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000848 va_end(args);
849
Igor Sysoev1b735832004-11-11 14:07:14 +0000850 *buf = '\0';
851
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000852 if (err) {
Igor Sysoev1b735832004-11-11 14:07:14 +0000853 buf = ngx_snprintf(buf, last - buf - 1, " (%d: ", err);
854 buf = ngx_strerror_r(err, buf, last - buf - 1);
855 *buf++ = ')';
856 *buf = '\0';
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000857 }
858
Igor Sysoev305a9d82005-12-26 17:07:48 +0000859 if (cf->conf_file == NULL) {
860 ngx_log_error(level, cf->log, 0, "%s", errstr);
861 return;
862 }
863
Igor Sysoev02f742b2005-04-08 15:18:55 +0000864 ngx_log_error(level, cf->log, 0, "%s in %s:%ui",
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000865 errstr, cf->conf_file->file.name.data, cf->conf_file->line);
866}
867
868
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000869char *
870ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000871{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000872 char *p = conf;
873
Igor Sysoev85080d02004-09-22 16:18:21 +0000874 ngx_str_t *value;
875 ngx_flag_t *fp;
876 ngx_conf_post_t *post;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000877
Igor Sysoev85080d02004-09-22 16:18:21 +0000878 fp = (ngx_flag_t *) (p + cmd->offset);
Igor Sysoevf1079102003-10-23 06:13:16 +0000879
Igor Sysoev85080d02004-09-22 16:18:21 +0000880 if (*fp != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000881 return "is duplicate";
882 }
883
Igor Sysoeva3677242004-04-14 05:57:36 +0000884 value = cf->args->elts;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000885
886 if (ngx_strcasecmp(value[1].data, "on") == 0) {
Igor Sysoev85080d02004-09-22 16:18:21 +0000887 *fp = 1;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000888
889 } else if (ngx_strcasecmp(value[1].data, "off") == 0) {
Igor Sysoev85080d02004-09-22 16:18:21 +0000890 *fp = 0;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000891
892 } else {
Igor Sysoev890fc962003-07-20 21:15:59 +0000893 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
894 "invalid value \"%s\" in \"%s\" directive, "
895 "it must be \"on\" or \"off\"",
896 value[1].data, cmd->name.data);
897 return NGX_CONF_ERROR;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000898 }
899
Igor Sysoev85080d02004-09-22 16:18:21 +0000900 if (cmd->post) {
901 post = cmd->post;
902 return post->post_handler(cf, post, fp);
903 }
Igor Sysoev6a644c62003-03-04 06:33:48 +0000904
905 return NGX_CONF_OK;
906}
907
908
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000909char *
910ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000911{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000912 char *p = conf;
913
Igor Sysoev13836ce2004-08-31 15:32:52 +0000914 ngx_str_t *field, *value;
915 ngx_conf_post_t *post;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000916
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000917 field = (ngx_str_t *) (p + cmd->offset);
Igor Sysoev1c13c662003-05-20 15:37:55 +0000918
Igor Sysoev6253ca12003-05-27 12:18:54 +0000919 if (field->data) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000920 return "is duplicate";
921 }
922
Igor Sysoeva3677242004-04-14 05:57:36 +0000923 value = cf->args->elts;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000924
Igor Sysoevdc9dd432003-10-22 16:38:26 +0000925 *field = value[1];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000926
Igor Sysoev13836ce2004-08-31 15:32:52 +0000927 if (cmd->post) {
928 post = cmd->post;
929 return post->post_handler(cf, post, field);
930 }
931
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000932 return NGX_CONF_OK;
933}
934
935
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000936char *
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000937ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev899b44e2005-05-12 14:58:06 +0000938{
939 char *p = conf;
940
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000941 ngx_str_t *value, *s;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000942 ngx_array_t **a;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000943 ngx_conf_post_t *post;
944
945 a = (ngx_array_t **) (p + cmd->offset);
946
947 if (*a == NULL) {
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000948 *a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
Igor Sysoev899b44e2005-05-12 14:58:06 +0000949 if (*a == NULL) {
950 return NGX_CONF_ERROR;
951 }
952 }
953
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000954 s = ngx_array_push(*a);
955 if (s == NULL) {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000956 return NGX_CONF_ERROR;
957 }
958
959 value = cf->args->elts;
960
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000961 *s = value[1];
Igor Sysoev899b44e2005-05-12 14:58:06 +0000962
963 if (cmd->post) {
964 post = cmd->post;
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000965 return post->post_handler(cf, post, s);
966 }
967
968 return NGX_CONF_OK;
969}
970
971
972char *
973ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
974{
975 char *p = conf;
976
977 ngx_str_t *value;
978 ngx_array_t **a;
979 ngx_keyval_t *kv;
980 ngx_conf_post_t *post;
981
982 a = (ngx_array_t **) (p + cmd->offset);
983
984 if (*a == NULL) {
985 *a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
986 if (*a == NULL) {
987 return NGX_CONF_ERROR;
988 }
989 }
990
991 kv = ngx_array_push(*a);
992 if (kv == NULL) {
993 return NGX_CONF_ERROR;
994 }
995
996 value = cf->args->elts;
997
998 kv->key = value[1];
999 kv->value = value[2];
1000
1001 if (cmd->post) {
1002 post = cmd->post;
1003 return post->post_handler(cf, post, kv);
Igor Sysoev899b44e2005-05-12 14:58:06 +00001004 }
1005
1006 return NGX_CONF_OK;
1007}
1008
1009
1010char *
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001011ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001012{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001013 char *p = conf;
1014
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001015 ngx_int_t *np;
Igor Sysoev12b4b002003-10-24 06:53:41 +00001016 ngx_str_t *value;
1017 ngx_conf_post_t *post;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001018
Igor Sysoevf1079102003-10-23 06:13:16 +00001019
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001020 np = (ngx_int_t *) (p + cmd->offset);
Igor Sysoevf1079102003-10-23 06:13:16 +00001021
1022 if (*np != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +00001023 return "is duplicate";
1024 }
1025
Igor Sysoeva3677242004-04-14 05:57:36 +00001026 value = cf->args->elts;
Igor Sysoevf1079102003-10-23 06:13:16 +00001027 *np = ngx_atoi(value[1].data, value[1].len);
1028 if (*np == NGX_ERROR) {
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001029 return "invalid number";
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001030 }
1031
Igor Sysoev12b4b002003-10-24 06:53:41 +00001032 if (cmd->post) {
1033 post = cmd->post;
1034 return post->post_handler(cf, post, np);
Igor Sysoevf1079102003-10-23 06:13:16 +00001035 }
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001036
1037 return NGX_CONF_OK;
1038}
1039
1040
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001041char *
1042ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +00001043{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001044 char *p = conf;
1045
Igor Sysoev10a543a2004-03-16 07:10:12 +00001046 size_t *sp;
Igor Sysoev12b4b002003-10-24 06:53:41 +00001047 ngx_str_t *value;
1048 ngx_conf_post_t *post;
Igor Sysoev960ffa42002-12-26 07:24:21 +00001049
Igor Sysoevf1079102003-10-23 06:13:16 +00001050
Igor Sysoev10a543a2004-03-16 07:10:12 +00001051 sp = (size_t *) (p + cmd->offset);
1052 if (*sp != NGX_CONF_UNSET_SIZE) {
Igor Sysoev1c13c662003-05-20 15:37:55 +00001053 return "is duplicate";
1054 }
1055
Igor Sysoeva3677242004-04-14 05:57:36 +00001056 value = cf->args->elts;
Igor Sysoev960ffa42002-12-26 07:24:21 +00001057
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001058 *sp = ngx_parse_size(&value[1]);
Igor Sysoev10a543a2004-03-16 07:10:12 +00001059 if (*sp == (size_t) NGX_ERROR) {
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001060 return "invalid value";
Igor Sysoev960ffa42002-12-26 07:24:21 +00001061 }
Igor Sysoev88092572002-12-19 07:08:55 +00001062
Igor Sysoev12b4b002003-10-24 06:53:41 +00001063 if (cmd->post) {
1064 post = cmd->post;
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001065 return post->post_handler(cf, post, sp);
Igor Sysoevf1079102003-10-23 06:13:16 +00001066 }
Igor Sysoev960ffa42002-12-26 07:24:21 +00001067
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001068 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +00001069}
1070
Igor Sysoev88092572002-12-19 07:08:55 +00001071
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001072char *
Igor Sysoev1765f472006-07-07 16:33:19 +00001073ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1074{
1075 char *p = conf;
1076
1077 off_t *op;
1078 ngx_str_t *value;
1079 ngx_conf_post_t *post;
1080
1081
1082 op = (off_t *) (p + cmd->offset);
1083 if (*op != NGX_CONF_UNSET) {
1084 return "is duplicate";
1085 }
1086
1087 value = cf->args->elts;
1088
1089 *op = ngx_parse_offset(&value[1]);
1090 if (*op == (off_t) NGX_ERROR) {
1091 return "invalid value";
1092 }
1093
1094 if (cmd->post) {
1095 post = cmd->post;
1096 return post->post_handler(cf, post, op);
1097 }
1098
1099 return NGX_CONF_OK;
1100}
1101
1102
1103char *
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001104ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +00001105{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001106 char *p = conf;
1107
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001108 ngx_msec_t *msp;
Igor Sysoev12b4b002003-10-24 06:53:41 +00001109 ngx_str_t *value;
1110 ngx_conf_post_t *post;
Igor Sysoev960ffa42002-12-26 07:24:21 +00001111
Igor Sysoevf1079102003-10-23 06:13:16 +00001112
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001113 msp = (ngx_msec_t *) (p + cmd->offset);
Igor Sysoev10a543a2004-03-16 07:10:12 +00001114 if (*msp != NGX_CONF_UNSET_MSEC) {
Igor Sysoev1c13c662003-05-20 15:37:55 +00001115 return "is duplicate";
1116 }
1117
Igor Sysoeva3677242004-04-14 05:57:36 +00001118 value = cf->args->elts;
Igor Sysoev960ffa42002-12-26 07:24:21 +00001119
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001120 *msp = ngx_parse_time(&value[1], 0);
1121 if (*msp == (ngx_msec_t) NGX_ERROR) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001122 return "invalid value";
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +00001123 }
1124
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001125 if (*msp == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001126 return "value must be less than 597 hours";
1127 }
Igor Sysoevf1079102003-10-23 06:13:16 +00001128
Igor Sysoev12b4b002003-10-24 06:53:41 +00001129 if (cmd->post) {
1130 post = cmd->post;
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001131 return post->post_handler(cf, post, msp);
Igor Sysoevf1079102003-10-23 06:13:16 +00001132 }
Igor Sysoev960ffa42002-12-26 07:24:21 +00001133
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001134 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +00001135}
Igor Sysoev6a644c62003-03-04 06:33:48 +00001136
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001137
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001138char *
1139ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001140{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001141 char *p = conf;
1142
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001143 time_t *sp;
Igor Sysoev12b4b002003-10-24 06:53:41 +00001144 ngx_str_t *value;
1145 ngx_conf_post_t *post;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001146
Igor Sysoevf1079102003-10-23 06:13:16 +00001147
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001148 sp = (time_t *) (p + cmd->offset);
1149 if (*sp != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +00001150 return "is duplicate";
1151 }
1152
Igor Sysoeva3677242004-04-14 05:57:36 +00001153 value = cf->args->elts;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001154
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001155 *sp = ngx_parse_time(&value[1], 1);
1156 if (*sp == NGX_ERROR) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001157 return "invalid value";
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001158 }
1159
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001160 if (*sp == NGX_PARSE_LARGE_TIME) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001161 return "value must be less than 68 years";
1162 }
Igor Sysoevf1079102003-10-23 06:13:16 +00001163
Igor Sysoev12b4b002003-10-24 06:53:41 +00001164 if (cmd->post) {
1165 post = cmd->post;
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001166 return post->post_handler(cf, post, sp);
Igor Sysoevf1079102003-10-23 06:13:16 +00001167 }
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001168
1169 return NGX_CONF_OK;
1170}
1171
1172
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001173char *
1174ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev3ae32482003-10-08 15:32:54 +00001175{
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001176 char *p = conf;
Igor Sysoev3ae32482003-10-08 15:32:54 +00001177
Igor Sysoev3ae32482003-10-08 15:32:54 +00001178 ngx_str_t *value;
1179 ngx_bufs_t *bufs;
1180
1181
1182 bufs = (ngx_bufs_t *) (p + cmd->offset);
Igor Sysoev3ae32482003-10-08 15:32:54 +00001183 if (bufs->num) {
1184 return "is duplicate";
1185 }
1186
Igor Sysoeva3677242004-04-14 05:57:36 +00001187 value = cf->args->elts;
Igor Sysoev3ae32482003-10-08 15:32:54 +00001188
1189 bufs->num = ngx_atoi(value[1].data, value[1].len);
1190 if (bufs->num == NGX_ERROR || bufs->num == 0) {
1191 return "invalid value";
1192 }
1193
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001194 bufs->size = ngx_parse_size(&value[2]);
Igor Sysoevb5910d42003-10-30 16:51:33 +00001195 if (bufs->size == (size_t) NGX_ERROR || bufs->size == 0) {
Igor Sysoev3ae32482003-10-08 15:32:54 +00001196 return "invalid value";
1197 }
1198
Igor Sysoev3ae32482003-10-08 15:32:54 +00001199 return NGX_CONF_OK;
1200}
1201
1202
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001203char *
1204ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoeva3677242004-04-14 05:57:36 +00001205{
1206 char *p = conf;
1207
1208 ngx_uint_t *np, i;
1209 ngx_str_t *value;
1210 ngx_conf_enum_t *e;
1211
1212 np = (ngx_uint_t *) (p + cmd->offset);
1213
1214 if (*np != NGX_CONF_UNSET_UINT) {
1215 return "is duplicate";
1216 }
1217
1218 value = cf->args->elts;
1219 e = cmd->post;
1220
1221 for (i = 0; e[i].name.len != 0; i++) {
1222 if (e[i].name.len != value[1].len
1223 || ngx_strcasecmp(e[i].name.data, value[1].data) != 0)
1224 {
1225 continue;
1226 }
1227
1228 *np = e[i].value;
1229
1230 return NGX_CONF_OK;
1231 }
1232
1233 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1234 "invalid value \"%s\"", value[1].data);
1235
1236 return NGX_CONF_ERROR;
1237}
1238
1239
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001240char *
1241ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001242{
1243 char *p = conf;
1244
Igor Sysoev10a543a2004-03-16 07:10:12 +00001245 ngx_uint_t *np, i, m;
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001246 ngx_str_t *value;
1247 ngx_conf_bitmask_t *mask;
1248
1249
Igor Sysoev10a543a2004-03-16 07:10:12 +00001250 np = (ngx_uint_t *) (p + cmd->offset);
Igor Sysoeva3677242004-04-14 05:57:36 +00001251 value = cf->args->elts;
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001252 mask = cmd->post;
1253
1254 for (i = 1; i < cf->args->nelts; i++) {
1255 for (m = 0; mask[m].name.len != 0; m++) {
1256
1257 if (mask[m].name.len != value[i].len
Igor Sysoeva3677242004-04-14 05:57:36 +00001258 || ngx_strcasecmp(mask[m].name.data, value[i].data) != 0)
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001259 {
1260 continue;
1261 }
1262
1263 if (*np & mask[m].mask) {
1264 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1265 "duplicate value \"%s\"", value[i].data);
1266
1267 } else {
1268 *np |= mask[m].mask;
1269 }
1270
1271 break;
1272 }
1273
1274 if (mask[m].name.len == 0) {
1275 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1276 "invalid value \"%s\"", value[i].data);
1277
1278 return NGX_CONF_ERROR;
1279 }
1280 }
1281
1282 return NGX_CONF_OK;
1283}
1284
1285
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001286char *
1287ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +00001288{
1289 return "unsupported on this platform";
1290}
Igor Sysoevf1079102003-10-23 06:13:16 +00001291
1292
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001293char *
Igor Sysoevc31a9bb2005-11-26 10:11:11 +00001294ngx_conf_deprecated(ngx_conf_t *cf, void *post, void *data)
1295{
1296 ngx_conf_deprecated_t *d = post;
1297
1298 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1299 "the \"%s\" directive is deprecated, "
1300 "use the \"%s\" directive instead",
1301 d->old_name, d->new_name);
1302
1303 return NGX_CONF_OK;
1304}
1305
1306
1307char *
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001308ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data)
Igor Sysoevf1079102003-10-23 06:13:16 +00001309{
Igor Sysoev369145c2004-05-28 15:49:23 +00001310 ngx_conf_num_bounds_t *bounds = post;
1311 ngx_int_t *np = data;
Igor Sysoevf1079102003-10-23 06:13:16 +00001312
Igor Sysoevcf80a702003-11-03 22:20:44 +00001313 if (bounds->high == -1) {
1314 if (*np >= bounds->low) {
1315 return NGX_CONF_OK;
1316 }
1317
1318 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev02f742b2005-04-08 15:18:55 +00001319 "value must be equal or more than %i", bounds->low);
Igor Sysoevcf80a702003-11-03 22:20:44 +00001320
1321 return NGX_CONF_ERROR;
1322 }
1323
1324 if (*np >= bounds->low && *np <= bounds->high) {
Igor Sysoevf1079102003-10-23 06:13:16 +00001325 return NGX_CONF_OK;
Igor Sysoevf1079102003-10-23 06:13:16 +00001326 }
1327
Igor Sysoevcf80a702003-11-03 22:20:44 +00001328 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev02f742b2005-04-08 15:18:55 +00001329 "value must be between %i and %i",
Igor Sysoevcf80a702003-11-03 22:20:44 +00001330 bounds->low, bounds->high);
1331
1332 return NGX_CONF_ERROR;
Igor Sysoevf1079102003-10-23 06:13:16 +00001333}