blob: 514d55badc4a692c4807dcd41a721776113bf764 [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 Sysoevbb4c1122007-02-20 14:36:48 +0000144 goto done;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000145 }
146
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000147 if (rc == NGX_CONF_BLOCK_DONE) {
Igor Sysoev83fe6622007-02-20 14:33:26 +0000148 if (!block) {
149 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected \"}\"");
Igor Sysoevbb4c1122007-02-20 14:36:48 +0000150 goto failed;
Igor Sysoev83fe6622007-02-20 14:33:26 +0000151 }
152
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000153 block = 0;
154 }
155
156 if (rc == NGX_CONF_FILE_DONE && block) {
Igor Sysoev40460ba2007-02-20 15:47:54 +0000157 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
158 "unexpected end of file, expecting \"}\"");
Igor Sysoevbb4c1122007-02-20 14:36:48 +0000159 goto failed;
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000160 }
161
Igor Sysoev1b735832004-11-11 14:07:14 +0000162 if (rc != NGX_OK && rc != NGX_CONF_BLOCK_START) {
Igor Sysoevbb4c1122007-02-20 14:36:48 +0000163 goto done;
Igor Sysoev88092572002-12-19 07:08:55 +0000164 }
165
Igor Sysoev88092572002-12-19 07:08:55 +0000166 if (cf->handler) {
167
Igor Sysoev1b735832004-11-11 14:07:14 +0000168 /*
169 * the custom handler, i.e., that is used in the http's
170 * "types { ... }" directive
171 */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000172
Igor Sysoev79a80482003-05-14 17:13:13 +0000173 rv = (*cf->handler)(cf, NULL, cf->handler_conf);
174 if (rv == NGX_CONF_OK) {
175 continue;
Igor Sysoevc1571722005-03-19 12:38:37 +0000176 }
Igor Sysoev79a80482003-05-14 17:13:13 +0000177
Igor Sysoevc1571722005-03-19 12:38:37 +0000178 if (rv == NGX_CONF_ERROR) {
Igor Sysoevbb4c1122007-02-20 14:36:48 +0000179 goto failed;
Igor Sysoev88092572002-12-19 07:08:55 +0000180 }
Igor Sysoev88092572002-12-19 07:08:55 +0000181
Igor Sysoev40460ba2007-02-20 15:47:54 +0000182 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, rv);
Igor Sysoevbb4c1122007-02-20 14:36:48 +0000183
184 goto failed;
Igor Sysoev88092572002-12-19 07:08:55 +0000185 }
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000186
Igor Sysoevc1571722005-03-19 12:38:37 +0000187
188 rc = ngx_conf_handler(cf, rc);
189
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000190 if (rc == NGX_ERROR) {
Igor Sysoevbb4c1122007-02-20 14:36:48 +0000191 goto failed;
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000192 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000193 }
Igor Sysoev88092572002-12-19 07:08:55 +0000194
Igor Sysoevbb4c1122007-02-20 14:36:48 +0000195failed:
196
197 rc = NGX_ERROR;
198
199done:
Igor Sysoevc1571722005-03-19 12:38:37 +0000200
Igor Sysoev88092572002-12-19 07:08:55 +0000201 if (filename) {
Igor Sysoev6d16e1e2006-04-05 13:40:54 +0000202 ngx_free(cf->conf_file->buffer->start);
Igor Sysoevd3283ff2005-12-05 13:18:09 +0000203
Igor Sysoeva6717c42002-12-23 06:29:22 +0000204 cf->conf_file = prev;
Igor Sysoev88092572002-12-19 07:08:55 +0000205
206 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000207 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +0000208 ngx_close_file_n " %s failed",
209 cf->conf_file->file.name.data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000210 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000211 }
212 }
213
Igor Sysoev9d639522003-07-07 06:11:50 +0000214 if (rc == NGX_ERROR) {
215 return NGX_CONF_ERROR;
216 }
217
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000218 return NGX_CONF_OK;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000219}
Igor Sysoev88092572002-12-19 07:08:55 +0000220
Igor Sysoev88092572002-12-19 07:08:55 +0000221
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000222static ngx_int_t
223ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
Igor Sysoevc1571722005-03-19 12:38:37 +0000224{
225 char *rv;
226 void *conf, **confp;
Igor Sysoevac72bd12006-05-04 15:32:46 +0000227 ngx_uint_t i, multi;
Igor Sysoevc1571722005-03-19 12:38:37 +0000228 ngx_str_t *name;
229 ngx_command_t *cmd;
230
231 name = cf->args->elts;
232
Igor Sysoevac72bd12006-05-04 15:32:46 +0000233 multi = 0;
234
Igor Sysoevc1571722005-03-19 12:38:37 +0000235 for (i = 0; ngx_modules[i]; i++) {
236
237 /* look up the directive in the appropriate modules */
238
239 if (ngx_modules[i]->type != NGX_CONF_MODULE
240 && ngx_modules[i]->type != cf->module_type)
241 {
242 continue;
243 }
244
245 cmd = ngx_modules[i]->commands;
246 if (cmd == NULL) {
247 continue;
248 }
249
Igor Sysoevac72bd12006-05-04 15:32:46 +0000250 for ( /* void */ ; cmd->name.len; cmd++) {
Igor Sysoevc1571722005-03-19 12:38:37 +0000251
Igor Sysoevac72bd12006-05-04 15:32:46 +0000252 if (name->len != cmd->name.len) {
253 continue;
254 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000255
Igor Sysoevac72bd12006-05-04 15:32:46 +0000256 if (ngx_strcmp(name->data, cmd->name.data) != 0) {
257 continue;
258 }
259
260
261 /* is the directive's location right ? */
262
263 if (!(cmd->type & cf->cmd_type)) {
264 if (cmd->type & NGX_CONF_MULTI) {
265 multi = 1;
266 continue;
Igor Sysoevc1571722005-03-19 12:38:37 +0000267 }
268
Igor Sysoevac72bd12006-05-04 15:32:46 +0000269 goto not_allowed;
270 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000271
Igor Sysoevac72bd12006-05-04 15:32:46 +0000272 if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {
Igor Sysoev40460ba2007-02-20 15:47:54 +0000273 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
274 "directive \"%s\" is not terminated by \";\"",
275 name->data);
Igor Sysoevac72bd12006-05-04 15:32:46 +0000276 return NGX_ERROR;
277 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000278
Igor Sysoevac72bd12006-05-04 15:32:46 +0000279 if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {
Igor Sysoev40460ba2007-02-20 15:47:54 +0000280 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
281 "directive \"%s\" has no opening \"{\"",
282 name->data);
Igor Sysoevac72bd12006-05-04 15:32:46 +0000283 return NGX_ERROR;
284 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000285
Igor Sysoevac72bd12006-05-04 15:32:46 +0000286 /* is the directive's argument count right ? */
Igor Sysoevc1571722005-03-19 12:38:37 +0000287
Igor Sysoevac72bd12006-05-04 15:32:46 +0000288 if (!(cmd->type & NGX_CONF_ANY)) {
Igor Sysoevc1571722005-03-19 12:38:37 +0000289
Igor Sysoevac72bd12006-05-04 15:32:46 +0000290 if (cmd->type & NGX_CONF_FLAG) {
291
292 if (cf->args->nelts != 2) {
293 goto invalid;
Igor Sysoevc1571722005-03-19 12:38:37 +0000294 }
295
296 } else if (cmd->type & NGX_CONF_1MORE) {
297
Igor Sysoevac72bd12006-05-04 15:32:46 +0000298 if (cf->args->nelts < 2) {
299 goto invalid;
Igor Sysoevc1571722005-03-19 12:38:37 +0000300 }
301
302 } else if (cmd->type & NGX_CONF_2MORE) {
303
Igor Sysoevac72bd12006-05-04 15:32:46 +0000304 if (cf->args->nelts < 3) {
305 goto invalid;
Igor Sysoevc1571722005-03-19 12:38:37 +0000306 }
307
Igor Sysoevac72bd12006-05-04 15:32:46 +0000308 } else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {
309
310 goto invalid;
311
312 } else if (!(cmd->type & argument_number[cf->args->nelts - 1]))
Igor Sysoevc1571722005-03-19 12:38:37 +0000313 {
Igor Sysoevac72bd12006-05-04 15:32:46 +0000314 goto invalid;
Igor Sysoevc1571722005-03-19 12:38:37 +0000315 }
Igor Sysoevac72bd12006-05-04 15:32:46 +0000316 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000317
Igor Sysoevac72bd12006-05-04 15:32:46 +0000318 /* set up the directive's configuration context */
319
320 conf = NULL;
321
322 if (cmd->type & NGX_DIRECT_CONF) {
323 conf = ((void **) cf->ctx)[ngx_modules[i]->index];
324
325 } else if (cmd->type & NGX_MAIN_CONF) {
326 conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
327
328 } else if (cf->ctx) {
329 confp = *(void **) ((char *) cf->ctx + cmd->conf);
330
331 if (confp) {
332 conf = confp[ngx_modules[i]->ctx_index];
Igor Sysoevc1571722005-03-19 12:38:37 +0000333 }
Igor Sysoevac72bd12006-05-04 15:32:46 +0000334 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000335
Igor Sysoevac72bd12006-05-04 15:32:46 +0000336 rv = cmd->set(cf, cmd, conf);
Igor Sysoevc1571722005-03-19 12:38:37 +0000337
Igor Sysoevac72bd12006-05-04 15:32:46 +0000338 if (rv == NGX_CONF_OK) {
339 return NGX_OK;
340 }
Igor Sysoevc1571722005-03-19 12:38:37 +0000341
Igor Sysoevac72bd12006-05-04 15:32:46 +0000342 if (rv == NGX_CONF_ERROR) {
Igor Sysoevc1571722005-03-19 12:38:37 +0000343 return NGX_ERROR;
344 }
345
Igor Sysoev40460ba2007-02-20 15:47:54 +0000346 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1849ba82007-06-05 11:55:39 +0000347 "\"%s\" directive %s", name->data, rv);
Igor Sysoevac72bd12006-05-04 15:32:46 +0000348
349 return NGX_ERROR;
Igor Sysoevc1571722005-03-19 12:38:37 +0000350 }
351 }
352
Igor Sysoevac72bd12006-05-04 15:32:46 +0000353 if (multi == 0) {
Igor Sysoev40460ba2007-02-20 15:47:54 +0000354 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
355 "unknown directive \"%s\"", name->data);
Igor Sysoevac72bd12006-05-04 15:32:46 +0000356
357 return NGX_ERROR;
358 }
359
360not_allowed:
361
Igor Sysoev40460ba2007-02-20 15:47:54 +0000362 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1849ba82007-06-05 11:55:39 +0000363 "\"%s\" directive is not allowed here", name->data);
Igor Sysoevac72bd12006-05-04 15:32:46 +0000364 return NGX_ERROR;
365
366invalid:
367
Igor Sysoev40460ba2007-02-20 15:47:54 +0000368 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1849ba82007-06-05 11:55:39 +0000369 "invalid number arguments in \"%s\" directive",
Igor Sysoev40460ba2007-02-20 15:47:54 +0000370 name->data);
Igor Sysoevc1571722005-03-19 12:38:37 +0000371
372 return NGX_ERROR;
373}
374
375
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000376static ngx_int_t
377ngx_conf_read_token(ngx_conf_t *cf)
Igor Sysoev88092572002-12-19 07:08:55 +0000378{
Igor Sysoev10a543a2004-03-16 07:10:12 +0000379 u_char *start, ch, *src, *dst;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000380 int len;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000381 int found, need_space, last_space, sharp_comment, variable;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000382 int quoted, s_quoted, d_quoted;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000383 ssize_t n;
384 ngx_str_t *word;
Igor Sysoev369145c2004-05-28 15:49:23 +0000385 ngx_buf_t *b;
Igor Sysoev88092572002-12-19 07:08:55 +0000386
Igor Sysoeva6717c42002-12-23 06:29:22 +0000387 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000388 need_space = 0;
389 last_space = 1;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000390 sharp_comment = 0;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000391 variable = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000392 quoted = s_quoted = d_quoted = 0;
393
394 cf->args->nelts = 0;
Igor Sysoev369145c2004-05-28 15:49:23 +0000395 b = cf->conf_file->buffer;
396 start = b->pos;
Igor Sysoev88092572002-12-19 07:08:55 +0000397
Igor Sysoev295bb632002-12-23 18:22:18 +0000398 for ( ;; ) {
Igor Sysoev88092572002-12-19 07:08:55 +0000399
Igor Sysoev369145c2004-05-28 15:49:23 +0000400 if (b->pos >= b->last) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000401 if (cf->conf_file->file.offset
Igor Sysoevaa828612005-02-09 14:31:07 +0000402 >= ngx_file_size(&cf->conf_file->file.info))
403 {
404 if (cf->args->nelts > 0) {
Igor Sysoev40460ba2007-02-20 15:47:54 +0000405 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
406 "unexpected end of file, "
407 "expecting \";\" or \"}\"");
Igor Sysoevaa828612005-02-09 14:31:07 +0000408 return NGX_ERROR;
409 }
410
Igor Sysoev960ffa42002-12-26 07:24:21 +0000411 return NGX_CONF_FILE_DONE;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000412 }
413
Igor Sysoev369145c2004-05-28 15:49:23 +0000414 if (b->pos - start) {
415 ngx_memcpy(b->start, start, b->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000416 }
417
Igor Sysoeva6717c42002-12-23 06:29:22 +0000418 n = ngx_read_file(&cf->conf_file->file,
Igor Sysoev369145c2004-05-28 15:49:23 +0000419 b->start + (b->pos - start),
420 b->end - (b->start + (b->pos - start)),
Igor Sysoev88092572002-12-19 07:08:55 +0000421 cf->conf_file->file.offset);
422
423 if (n == NGX_ERROR) {
424 return NGX_ERROR;
425 }
426
Igor Sysoev369145c2004-05-28 15:49:23 +0000427 b->pos = b->start + (b->pos - start);
428 start = b->start;
429 b->last = b->pos + n;
Igor Sysoev88092572002-12-19 07:08:55 +0000430 }
431
Igor Sysoev369145c2004-05-28 15:49:23 +0000432 ch = *b->pos++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000433
Igor Sysoev88092572002-12-19 07:08:55 +0000434 if (ch == LF) {
435 cf->conf_file->line++;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000436
437 if (sharp_comment) {
438 sharp_comment = 0;
439 }
440 }
441
442 if (sharp_comment) {
443 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000444 }
445
Igor Sysoev295bb632002-12-23 18:22:18 +0000446 if (quoted) {
447 quoted = 0;
448 continue;
449 }
450
Igor Sysoeva6717c42002-12-23 06:29:22 +0000451 if (need_space) {
452 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
453 last_space = 1;
454 need_space = 0;
455 continue;
456 }
457
Igor Sysoev1b735832004-11-11 14:07:14 +0000458 if (ch == ';') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000459 return NGX_OK;
460 }
461
Igor Sysoev1b735832004-11-11 14:07:14 +0000462 if (ch == '{') {
463 return NGX_CONF_BLOCK_START;
464 }
465
Igor Sysoevc31a9bb2005-11-26 10:11:11 +0000466 if (ch == ')') {
467 last_space = 1;
468 need_space = 0;
Igor Sysoev78329332003-11-10 17:17:31 +0000469
Igor Sysoevc31a9bb2005-11-26 10:11:11 +0000470 } else {
Igor Sysoev40460ba2007-02-20 15:47:54 +0000471 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
472 "unexpected \"%c\"", ch);
Igor Sysoevc31a9bb2005-11-26 10:11:11 +0000473 return NGX_ERROR;
474 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000475 }
476
Igor Sysoev88092572002-12-19 07:08:55 +0000477 if (last_space) {
Igor Sysoev88092572002-12-19 07:08:55 +0000478 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000479 continue;
480 }
481
Igor Sysoev369145c2004-05-28 15:49:23 +0000482 start = b->pos - 1;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000483
484 switch (ch) {
485
Igor Sysoev295bb632002-12-23 18:22:18 +0000486 case ';':
487 case '{':
Igor Sysoev960ffa42002-12-26 07:24:21 +0000488 if (cf->args->nelts == 0) {
Igor Sysoev40460ba2007-02-20 15:47:54 +0000489 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
490 "unexpected \"%c\"", ch);
Igor Sysoev960ffa42002-12-26 07:24:21 +0000491 return NGX_ERROR;
492 }
493
Igor Sysoev1b735832004-11-11 14:07:14 +0000494 if (ch == '{') {
495 return NGX_CONF_BLOCK_START;
496 }
497
Igor Sysoev295bb632002-12-23 18:22:18 +0000498 return NGX_OK;
499
Igor Sysoev960ffa42002-12-26 07:24:21 +0000500 case '}':
Igor Sysoev4959ec42005-05-23 12:07:45 +0000501 if (cf->args->nelts != 0) {
Igor Sysoev40460ba2007-02-20 15:47:54 +0000502 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
503 "unexpected \"}\"");
Igor Sysoev960ffa42002-12-26 07:24:21 +0000504 return NGX_ERROR;
505 }
506
507 return NGX_CONF_BLOCK_DONE;
508
509 case '#':
510 sharp_comment = 1;
511 continue;
512
Igor Sysoeva6717c42002-12-23 06:29:22 +0000513 case '\\':
514 quoted = 1;
515 last_space = 0;
516 continue;
517
518 case '"':
Igor Sysoev88092572002-12-19 07:08:55 +0000519 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000520 d_quoted = 1;
521 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000522 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000523
Igor Sysoeva6717c42002-12-23 06:29:22 +0000524 case '\'':
525 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000526 s_quoted = 1;
527 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000528 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000529
Igor Sysoeva6717c42002-12-23 06:29:22 +0000530 default:
531 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000532 }
533
534 } else {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000535 if (ch == '{' && variable) {
536 continue;
537 }
538
539 variable = 0;
540
Igor Sysoeva6717c42002-12-23 06:29:22 +0000541 if (ch == '\\') {
542 quoted = 1;
543 continue;
544 }
Igor Sysoev88092572002-12-19 07:08:55 +0000545
Igor Sysoev899b44e2005-05-12 14:58:06 +0000546 if (ch == '$') {
547 variable = 1;
548 continue;
549 }
550
Igor Sysoeva6717c42002-12-23 06:29:22 +0000551 if (d_quoted) {
552 if (ch == '"') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000553 d_quoted = 0;
554 need_space = 1;
555 found = 1;
556 }
557
558 } else if (s_quoted) {
559 if (ch == '\'') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000560 s_quoted = 0;
561 need_space = 1;
562 found = 1;
563 }
564
565 } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
566 || ch == ';' || ch == '{') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000567 last_space = 1;
568 found = 1;
569 }
570
571 if (found) {
Igor Sysoevc1571722005-03-19 12:38:37 +0000572 word = ngx_array_push(cf->args);
573 if (word == NULL) {
Igor Sysoev369145c2004-05-28 15:49:23 +0000574 return NGX_ERROR;
575 }
576
Igor Sysoevc1571722005-03-19 12:38:37 +0000577 word->data = ngx_palloc(cf->pool, b->pos - start + 1);
578 if (word->data == NULL) {
Igor Sysoev369145c2004-05-28 15:49:23 +0000579 return NGX_ERROR;
580 }
Igor Sysoev88092572002-12-19 07:08:55 +0000581
Igor Sysoev295bb632002-12-23 18:22:18 +0000582 for (dst = word->data, src = start, len = 0;
Igor Sysoev369145c2004-05-28 15:49:23 +0000583 src < b->pos - 1;
Igor Sysoev295bb632002-12-23 18:22:18 +0000584 len++)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000585 {
586 if (*src == '\\') {
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000587 switch (src[1]) {
588 case '"':
589 case '\'':
590 case '\\':
591 src++;
592 break;
593
594 case 't':
595 *dst++ = '\t';
596 src += 2;
597 continue;
598
599 case 'r':
600 *dst++ = '\r';
601 src += 2;
602 continue;
603
604 case 'n':
605 *dst++ = '\n';
606 src += 2;
607 continue;
608 }
609
Igor Sysoeva6717c42002-12-23 06:29:22 +0000610 }
Igor Sysoev88092572002-12-19 07:08:55 +0000611 *dst++ = *src++;
612 }
613 *dst = '\0';
Igor Sysoev295bb632002-12-23 18:22:18 +0000614 word->len = len;
Igor Sysoev88092572002-12-19 07:08:55 +0000615
Igor Sysoev1b735832004-11-11 14:07:14 +0000616 if (ch == ';') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000617 return NGX_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000618 }
619
Igor Sysoev1b735832004-11-11 14:07:14 +0000620 if (ch == '{') {
621 return NGX_CONF_BLOCK_START;
622 }
623
Igor Sysoeva6717c42002-12-23 06:29:22 +0000624 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000625 }
Igor Sysoev88092572002-12-19 07:08:55 +0000626 }
627 }
628}
629
Igor Sysoev88092572002-12-19 07:08:55 +0000630
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000631static char *
632ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoevab517d52004-05-18 15:29:08 +0000633{
Igor Sysoev97c2f462006-10-02 08:46:45 +0000634 char *rv;
635 ngx_int_t n;
636 ngx_str_t *value, file;
637 ngx_glob_t gl;
Igor Sysoevab517d52004-05-18 15:29:08 +0000638
639 value = cf->args->elts;
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000640 file = value[1];
Igor Sysoevab517d52004-05-18 15:29:08 +0000641
Igor Sysoev97c2f462006-10-02 08:46:45 +0000642 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
643
Igor Sysoeva1df4162007-07-29 18:05:45 +0000644 if (ngx_conf_full_name(cf->cycle, &file, 1) == NGX_ERROR) {
Igor Sysoevab517d52004-05-18 15:29:08 +0000645 return NGX_CONF_ERROR;
646 }
647
Igor Sysoev97c2f462006-10-02 08:46:45 +0000648 ngx_memzero(&gl, sizeof(ngx_glob_t));
Igor Sysoevab517d52004-05-18 15:29:08 +0000649
Igor Sysoev97c2f462006-10-02 08:46:45 +0000650 gl.pattern = file.data;
651 gl.log = cf->log;
652
653 if (ngx_open_glob(&gl) != NGX_OK) {
654 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
655 ngx_open_glob_n " \"%s\" failed", file.data);
656 return NGX_CONF_ERROR;
657 }
658
659 rv = NGX_CONF_OK;
660
661 for ( ;; ) {
662 n = ngx_read_glob(&gl, &file);
663
664 if (n != NGX_OK) {
665 break;
666 }
667
668 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
669
670 rv = ngx_conf_parse(cf, &file);
671
672 if (rv != NGX_CONF_OK) {
673 break;
674 }
675 }
676
677 ngx_close_glob(&gl);
678
679 return rv;
Igor Sysoevab517d52004-05-18 15:29:08 +0000680}
681
682
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000683ngx_int_t
Igor Sysoeva1df4162007-07-29 18:05:45 +0000684ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000685{
Igor Sysoeva1df4162007-07-29 18:05:45 +0000686 size_t len;
687 u_char *p, *prefix;
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000688 ngx_str_t old;
689
690 if (name->data[0] == '/') {
691 return NGX_OK;
692 }
693
Igor Sysoev1b735832004-11-11 14:07:14 +0000694#if (NGX_WIN32)
695
696 if (name->len > 2
697 && name->data[1] == ':'
698 && ((name->data[0] >= 'a' && name->data[0] <= 'z')
699 || (name->data[0] >= 'A' && name->data[0] <= 'Z')))
700 {
701 return NGX_OK;
702 }
703
704#endif
705
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000706 old = *name;
707
Igor Sysoeva1df4162007-07-29 18:05:45 +0000708 if (conf_prefix) {
709 len = sizeof(NGX_CONF_PREFIX) - 1;
710 prefix = (u_char *) NGX_CONF_PREFIX;
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000711
Igor Sysoeva1df4162007-07-29 18:05:45 +0000712 } else {
713 len = cycle->root.len;
714 prefix = cycle->root.data;
715 }
716
717 name->len = len + old.len;
Igor Sysoev9e580192006-02-01 18:22:15 +0000718 name->data = ngx_palloc(cycle->pool, name->len + 1);
719 if (name->data == NULL) {
720 return NGX_ERROR;
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000721 }
722
Igor Sysoeva1df4162007-07-29 18:05:45 +0000723 p = ngx_cpymem(name->data, prefix, len);
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000724 ngx_cpystrn(p, old.data, old.len + 1);
725
726 return NGX_OK;
727}
728
729
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000730ngx_open_file_t *
731ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
Igor Sysoev890fc962003-07-20 21:15:59 +0000732{
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000733 ngx_str_t full;
Igor Sysoev10a543a2004-03-16 07:10:12 +0000734 ngx_uint_t i;
Igor Sysoevb9e34412004-09-03 15:50:30 +0000735 ngx_list_part_t *part;
Igor Sysoev890fc962003-07-20 21:15:59 +0000736 ngx_open_file_t *file;
737
Igor Sysoevaad1b892004-10-03 20:02:06 +0000738#if (NGX_SUPPRESS_WARN)
739 full.len = 0;
740 full.data = NULL;
741#endif
742
Igor Sysoev890fc962003-07-20 21:15:59 +0000743 if (name) {
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000744 full = *name;
745
Igor Sysoeva1df4162007-07-29 18:05:45 +0000746 if (ngx_conf_full_name(cycle, &full, 0) == NGX_ERROR) {
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000747 return NULL;
748 }
749
Igor Sysoevb9e34412004-09-03 15:50:30 +0000750 part = &cycle->open_files.part;
751 file = part->elts;
752
753 for (i = 0; /* void */ ; i++) {
754
755 if (i >= part->nelts) {
756 if (part->next == NULL) {
757 break;
758 }
759 part = part->next;
760 file = part->elts;
761 i = 0;
762 }
763
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000764 if (full.len != file[i].name.len) {
Igor Sysoev890fc962003-07-20 21:15:59 +0000765 continue;
766 }
767
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000768 if (ngx_strcmp(full.data, file[i].name.data) == 0) {
Igor Sysoev890fc962003-07-20 21:15:59 +0000769 return &file[i];
770 }
771 }
772 }
773
Igor Sysoevc1571722005-03-19 12:38:37 +0000774 file = ngx_list_push(&cycle->open_files);
775 if (file == NULL) {
Igor Sysoev369145c2004-05-28 15:49:23 +0000776 return NULL;
777 }
778
Igor Sysoev890fc962003-07-20 21:15:59 +0000779 if (name) {
Igor Sysoev4bed15b2004-09-30 19:44:38 +0000780 file->fd = NGX_INVALID_FILE;
Igor Sysoev6d2a14a2004-09-27 16:03:21 +0000781 file->name = full;
782
Igor Sysoev980a9242004-09-05 19:54:02 +0000783 } else {
Igor Sysoevaad1b892004-10-03 20:02:06 +0000784 file->fd = ngx_stderr_fileno;
Igor Sysoev980a9242004-09-05 19:54:02 +0000785 file->name.len = 0;
786 file->name.data = NULL;
Igor Sysoev890fc962003-07-20 21:15:59 +0000787 }
788
Igor Sysoev697d1ae2005-10-27 15:46:13 +0000789 file->buffer = NULL;
790
Igor Sysoev890fc962003-07-20 21:15:59 +0000791 return file;
792}
793
794
Igor Sysoev697d1ae2005-10-27 15:46:13 +0000795static void
796ngx_conf_flush_files(ngx_cycle_t *cycle)
797{
798 ngx_uint_t i;
799 ngx_list_part_t *part;
800 ngx_open_file_t *file;
801
802 ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "flush files");
803
804 part = &cycle->open_files.part;
805 file = part->elts;
806
807 for (i = 0; /* void */ ; i++) {
808
809 if (i >= part->nelts) {
810 if (part->next == NULL) {
811 break;
812 }
813 part = part->next;
814 file = part->elts;
815 i = 0;
816 }
817
818 if (file[i].buffer == NULL || file[i].pos - file[i].buffer == 0) {
819 continue;
820 }
821
822 ngx_write_fd(file[i].fd, file[i].buffer, file[i].pos - file[i].buffer);
823 }
824}
825
826
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000827void ngx_cdecl
828ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf, ngx_err_t err,
829 char *fmt, ...)
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000830{
Igor Sysoev1b735832004-11-11 14:07:14 +0000831 u_char errstr[NGX_MAX_CONF_ERRSTR], *buf, *last;
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000832 va_list args;
833
Igor Sysoev1b735832004-11-11 14:07:14 +0000834 last = errstr + NGX_MAX_CONF_ERRSTR;
835
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000836 va_start(args, fmt);
Igor Sysoev1b735832004-11-11 14:07:14 +0000837 buf = ngx_vsnprintf(errstr, last - errstr, fmt, args);
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000838 va_end(args);
839
Igor Sysoev1b735832004-11-11 14:07:14 +0000840 *buf = '\0';
841
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000842 if (err) {
Igor Sysoev1b735832004-11-11 14:07:14 +0000843 buf = ngx_snprintf(buf, last - buf - 1, " (%d: ", err);
844 buf = ngx_strerror_r(err, buf, last - buf - 1);
845 *buf++ = ')';
846 *buf = '\0';
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000847 }
848
Igor Sysoev305a9d82005-12-26 17:07:48 +0000849 if (cf->conf_file == NULL) {
850 ngx_log_error(level, cf->log, 0, "%s", errstr);
851 return;
852 }
853
Igor Sysoev02f742b2005-04-08 15:18:55 +0000854 ngx_log_error(level, cf->log, 0, "%s in %s:%ui",
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000855 errstr, cf->conf_file->file.name.data, cf->conf_file->line);
856}
857
858
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000859char *
860ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000861{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000862 char *p = conf;
863
Igor Sysoev85080d02004-09-22 16:18:21 +0000864 ngx_str_t *value;
865 ngx_flag_t *fp;
866 ngx_conf_post_t *post;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000867
Igor Sysoev85080d02004-09-22 16:18:21 +0000868 fp = (ngx_flag_t *) (p + cmd->offset);
Igor Sysoevf1079102003-10-23 06:13:16 +0000869
Igor Sysoev85080d02004-09-22 16:18:21 +0000870 if (*fp != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000871 return "is duplicate";
872 }
873
Igor Sysoeva3677242004-04-14 05:57:36 +0000874 value = cf->args->elts;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000875
Igor Sysoev722231f2007-02-14 18:51:19 +0000876 if (ngx_strcasecmp(value[1].data, (u_char *) "on") == 0) {
Igor Sysoev85080d02004-09-22 16:18:21 +0000877 *fp = 1;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000878
Igor Sysoev722231f2007-02-14 18:51:19 +0000879 } else if (ngx_strcasecmp(value[1].data, (u_char *) "off") == 0) {
Igor Sysoev85080d02004-09-22 16:18:21 +0000880 *fp = 0;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000881
882 } else {
Igor Sysoev890fc962003-07-20 21:15:59 +0000883 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
884 "invalid value \"%s\" in \"%s\" directive, "
885 "it must be \"on\" or \"off\"",
886 value[1].data, cmd->name.data);
887 return NGX_CONF_ERROR;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000888 }
889
Igor Sysoev85080d02004-09-22 16:18:21 +0000890 if (cmd->post) {
891 post = cmd->post;
892 return post->post_handler(cf, post, fp);
893 }
Igor Sysoev6a644c62003-03-04 06:33:48 +0000894
895 return NGX_CONF_OK;
896}
897
898
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000899char *
900ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000901{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000902 char *p = conf;
903
Igor Sysoev13836ce2004-08-31 15:32:52 +0000904 ngx_str_t *field, *value;
905 ngx_conf_post_t *post;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000906
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000907 field = (ngx_str_t *) (p + cmd->offset);
Igor Sysoev1c13c662003-05-20 15:37:55 +0000908
Igor Sysoev6253ca12003-05-27 12:18:54 +0000909 if (field->data) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000910 return "is duplicate";
911 }
912
Igor Sysoeva3677242004-04-14 05:57:36 +0000913 value = cf->args->elts;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000914
Igor Sysoevdc9dd432003-10-22 16:38:26 +0000915 *field = value[1];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000916
Igor Sysoev13836ce2004-08-31 15:32:52 +0000917 if (cmd->post) {
918 post = cmd->post;
919 return post->post_handler(cf, post, field);
920 }
921
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000922 return NGX_CONF_OK;
923}
924
925
Igor Sysoev4d656dc2005-03-22 16:02:46 +0000926char *
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000927ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev899b44e2005-05-12 14:58:06 +0000928{
929 char *p = conf;
930
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000931 ngx_str_t *value, *s;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000932 ngx_array_t **a;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000933 ngx_conf_post_t *post;
934
935 a = (ngx_array_t **) (p + cmd->offset);
936
937 if (*a == NULL) {
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000938 *a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
Igor Sysoev899b44e2005-05-12 14:58:06 +0000939 if (*a == NULL) {
940 return NGX_CONF_ERROR;
941 }
942 }
943
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000944 s = ngx_array_push(*a);
945 if (s == NULL) {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000946 return NGX_CONF_ERROR;
947 }
948
949 value = cf->args->elts;
950
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000951 *s = value[1];
Igor Sysoev899b44e2005-05-12 14:58:06 +0000952
953 if (cmd->post) {
954 post = cmd->post;
Igor Sysoev3338cfd2006-05-11 14:43:47 +0000955 return post->post_handler(cf, post, s);
956 }
957
958 return NGX_CONF_OK;
959}
960
961
962char *
963ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
964{
965 char *p = conf;
966
967 ngx_str_t *value;
968 ngx_array_t **a;
969 ngx_keyval_t *kv;
970 ngx_conf_post_t *post;
971
972 a = (ngx_array_t **) (p + cmd->offset);
973
974 if (*a == NULL) {
975 *a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
976 if (*a == NULL) {
977 return NGX_CONF_ERROR;
978 }
979 }
980
981 kv = ngx_array_push(*a);
982 if (kv == NULL) {
983 return NGX_CONF_ERROR;
984 }
985
986 value = cf->args->elts;
987
988 kv->key = value[1];
989 kv->value = value[2];
990
991 if (cmd->post) {
992 post = cmd->post;
993 return post->post_handler(cf, post, kv);
Igor Sysoev899b44e2005-05-12 14:58:06 +0000994 }
995
996 return NGX_CONF_OK;
997}
998
999
1000char *
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001001ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001002{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001003 char *p = conf;
1004
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001005 ngx_int_t *np;
Igor Sysoev12b4b002003-10-24 06:53:41 +00001006 ngx_str_t *value;
1007 ngx_conf_post_t *post;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001008
Igor Sysoevf1079102003-10-23 06:13:16 +00001009
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001010 np = (ngx_int_t *) (p + cmd->offset);
Igor Sysoevf1079102003-10-23 06:13:16 +00001011
1012 if (*np != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +00001013 return "is duplicate";
1014 }
1015
Igor Sysoeva3677242004-04-14 05:57:36 +00001016 value = cf->args->elts;
Igor Sysoevf1079102003-10-23 06:13:16 +00001017 *np = ngx_atoi(value[1].data, value[1].len);
1018 if (*np == NGX_ERROR) {
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001019 return "invalid number";
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001020 }
1021
Igor Sysoev12b4b002003-10-24 06:53:41 +00001022 if (cmd->post) {
1023 post = cmd->post;
1024 return post->post_handler(cf, post, np);
Igor Sysoevf1079102003-10-23 06:13:16 +00001025 }
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001026
1027 return NGX_CONF_OK;
1028}
1029
1030
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001031char *
1032ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +00001033{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001034 char *p = conf;
1035
Igor Sysoev10a543a2004-03-16 07:10:12 +00001036 size_t *sp;
Igor Sysoev12b4b002003-10-24 06:53:41 +00001037 ngx_str_t *value;
1038 ngx_conf_post_t *post;
Igor Sysoev960ffa42002-12-26 07:24:21 +00001039
Igor Sysoevf1079102003-10-23 06:13:16 +00001040
Igor Sysoev10a543a2004-03-16 07:10:12 +00001041 sp = (size_t *) (p + cmd->offset);
1042 if (*sp != NGX_CONF_UNSET_SIZE) {
Igor Sysoev1c13c662003-05-20 15:37:55 +00001043 return "is duplicate";
1044 }
1045
Igor Sysoeva3677242004-04-14 05:57:36 +00001046 value = cf->args->elts;
Igor Sysoev960ffa42002-12-26 07:24:21 +00001047
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001048 *sp = ngx_parse_size(&value[1]);
Igor Sysoev10a543a2004-03-16 07:10:12 +00001049 if (*sp == (size_t) NGX_ERROR) {
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001050 return "invalid value";
Igor Sysoev960ffa42002-12-26 07:24:21 +00001051 }
Igor Sysoev88092572002-12-19 07:08:55 +00001052
Igor Sysoev12b4b002003-10-24 06:53:41 +00001053 if (cmd->post) {
1054 post = cmd->post;
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001055 return post->post_handler(cf, post, sp);
Igor Sysoevf1079102003-10-23 06:13:16 +00001056 }
Igor Sysoev960ffa42002-12-26 07:24:21 +00001057
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001058 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +00001059}
1060
Igor Sysoev88092572002-12-19 07:08:55 +00001061
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001062char *
Igor Sysoev1765f472006-07-07 16:33:19 +00001063ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1064{
1065 char *p = conf;
1066
1067 off_t *op;
1068 ngx_str_t *value;
1069 ngx_conf_post_t *post;
1070
1071
1072 op = (off_t *) (p + cmd->offset);
1073 if (*op != NGX_CONF_UNSET) {
1074 return "is duplicate";
1075 }
1076
1077 value = cf->args->elts;
1078
1079 *op = ngx_parse_offset(&value[1]);
1080 if (*op == (off_t) NGX_ERROR) {
1081 return "invalid value";
1082 }
1083
1084 if (cmd->post) {
1085 post = cmd->post;
1086 return post->post_handler(cf, post, op);
1087 }
1088
1089 return NGX_CONF_OK;
1090}
1091
1092
1093char *
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001094ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +00001095{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001096 char *p = conf;
1097
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001098 ngx_msec_t *msp;
Igor Sysoev12b4b002003-10-24 06:53:41 +00001099 ngx_str_t *value;
1100 ngx_conf_post_t *post;
Igor Sysoev960ffa42002-12-26 07:24:21 +00001101
Igor Sysoevf1079102003-10-23 06:13:16 +00001102
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001103 msp = (ngx_msec_t *) (p + cmd->offset);
Igor Sysoev10a543a2004-03-16 07:10:12 +00001104 if (*msp != NGX_CONF_UNSET_MSEC) {
Igor Sysoev1c13c662003-05-20 15:37:55 +00001105 return "is duplicate";
1106 }
1107
Igor Sysoeva3677242004-04-14 05:57:36 +00001108 value = cf->args->elts;
Igor Sysoev960ffa42002-12-26 07:24:21 +00001109
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001110 *msp = ngx_parse_time(&value[1], 0);
1111 if (*msp == (ngx_msec_t) NGX_ERROR) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001112 return "invalid value";
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +00001113 }
1114
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001115 if (*msp == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001116 return "value must be less than 597 hours";
1117 }
Igor Sysoevf1079102003-10-23 06:13:16 +00001118
Igor Sysoev12b4b002003-10-24 06:53:41 +00001119 if (cmd->post) {
1120 post = cmd->post;
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001121 return post->post_handler(cf, post, msp);
Igor Sysoevf1079102003-10-23 06:13:16 +00001122 }
Igor Sysoev960ffa42002-12-26 07:24:21 +00001123
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001124 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +00001125}
Igor Sysoev6a644c62003-03-04 06:33:48 +00001126
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001127
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001128char *
1129ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001130{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001131 char *p = conf;
1132
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001133 time_t *sp;
Igor Sysoev12b4b002003-10-24 06:53:41 +00001134 ngx_str_t *value;
1135 ngx_conf_post_t *post;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001136
Igor Sysoevf1079102003-10-23 06:13:16 +00001137
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001138 sp = (time_t *) (p + cmd->offset);
1139 if (*sp != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +00001140 return "is duplicate";
1141 }
1142
Igor Sysoeva3677242004-04-14 05:57:36 +00001143 value = cf->args->elts;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001144
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001145 *sp = ngx_parse_time(&value[1], 1);
1146 if (*sp == NGX_ERROR) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001147 return "invalid value";
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001148 }
1149
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001150 if (*sp == NGX_PARSE_LARGE_TIME) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001151 return "value must be less than 68 years";
1152 }
Igor Sysoevf1079102003-10-23 06:13:16 +00001153
Igor Sysoev12b4b002003-10-24 06:53:41 +00001154 if (cmd->post) {
1155 post = cmd->post;
Igor Sysoev0ee5d3c2004-02-20 16:48:59 +00001156 return post->post_handler(cf, post, sp);
Igor Sysoevf1079102003-10-23 06:13:16 +00001157 }
Igor Sysoev3d09c8d2003-05-06 17:03:16 +00001158
1159 return NGX_CONF_OK;
1160}
1161
1162
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001163char *
1164ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev3ae32482003-10-08 15:32:54 +00001165{
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001166 char *p = conf;
Igor Sysoev3ae32482003-10-08 15:32:54 +00001167
Igor Sysoev3ae32482003-10-08 15:32:54 +00001168 ngx_str_t *value;
1169 ngx_bufs_t *bufs;
1170
1171
1172 bufs = (ngx_bufs_t *) (p + cmd->offset);
Igor Sysoev3ae32482003-10-08 15:32:54 +00001173 if (bufs->num) {
1174 return "is duplicate";
1175 }
1176
Igor Sysoeva3677242004-04-14 05:57:36 +00001177 value = cf->args->elts;
Igor Sysoev3ae32482003-10-08 15:32:54 +00001178
1179 bufs->num = ngx_atoi(value[1].data, value[1].len);
1180 if (bufs->num == NGX_ERROR || bufs->num == 0) {
1181 return "invalid value";
1182 }
1183
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001184 bufs->size = ngx_parse_size(&value[2]);
Igor Sysoevb5910d42003-10-30 16:51:33 +00001185 if (bufs->size == (size_t) NGX_ERROR || bufs->size == 0) {
Igor Sysoev3ae32482003-10-08 15:32:54 +00001186 return "invalid value";
1187 }
1188
Igor Sysoev3ae32482003-10-08 15:32:54 +00001189 return NGX_CONF_OK;
1190}
1191
1192
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001193char *
1194ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoeva3677242004-04-14 05:57:36 +00001195{
1196 char *p = conf;
1197
1198 ngx_uint_t *np, i;
1199 ngx_str_t *value;
1200 ngx_conf_enum_t *e;
1201
1202 np = (ngx_uint_t *) (p + cmd->offset);
1203
1204 if (*np != NGX_CONF_UNSET_UINT) {
1205 return "is duplicate";
1206 }
1207
1208 value = cf->args->elts;
1209 e = cmd->post;
1210
1211 for (i = 0; e[i].name.len != 0; i++) {
1212 if (e[i].name.len != value[1].len
1213 || ngx_strcasecmp(e[i].name.data, value[1].data) != 0)
1214 {
1215 continue;
1216 }
1217
1218 *np = e[i].value;
1219
1220 return NGX_CONF_OK;
1221 }
1222
1223 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1224 "invalid value \"%s\"", value[1].data);
1225
1226 return NGX_CONF_ERROR;
1227}
1228
1229
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001230char *
1231ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001232{
1233 char *p = conf;
1234
Igor Sysoev10a543a2004-03-16 07:10:12 +00001235 ngx_uint_t *np, i, m;
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001236 ngx_str_t *value;
1237 ngx_conf_bitmask_t *mask;
1238
1239
Igor Sysoev10a543a2004-03-16 07:10:12 +00001240 np = (ngx_uint_t *) (p + cmd->offset);
Igor Sysoeva3677242004-04-14 05:57:36 +00001241 value = cf->args->elts;
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001242 mask = cmd->post;
1243
1244 for (i = 1; i < cf->args->nelts; i++) {
1245 for (m = 0; mask[m].name.len != 0; m++) {
1246
1247 if (mask[m].name.len != value[i].len
Igor Sysoeva3677242004-04-14 05:57:36 +00001248 || ngx_strcasecmp(mask[m].name.data, value[i].data) != 0)
Igor Sysoev68ee8f12003-10-30 08:51:06 +00001249 {
1250 continue;
1251 }
1252
1253 if (*np & mask[m].mask) {
1254 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1255 "duplicate value \"%s\"", value[i].data);
1256
1257 } else {
1258 *np |= mask[m].mask;
1259 }
1260
1261 break;
1262 }
1263
1264 if (mask[m].name.len == 0) {
1265 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1266 "invalid value \"%s\"", value[i].data);
1267
1268 return NGX_CONF_ERROR;
1269 }
1270 }
1271
1272 return NGX_CONF_OK;
1273}
1274
1275
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001276char *
1277ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +00001278{
1279 return "unsupported on this platform";
1280}
Igor Sysoevf1079102003-10-23 06:13:16 +00001281
1282
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001283char *
Igor Sysoevc31a9bb2005-11-26 10:11:11 +00001284ngx_conf_deprecated(ngx_conf_t *cf, void *post, void *data)
1285{
1286 ngx_conf_deprecated_t *d = post;
1287
1288 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1289 "the \"%s\" directive is deprecated, "
1290 "use the \"%s\" directive instead",
1291 d->old_name, d->new_name);
1292
1293 return NGX_CONF_OK;
1294}
1295
1296
1297char *
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001298ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data)
Igor Sysoevf1079102003-10-23 06:13:16 +00001299{
Igor Sysoev369145c2004-05-28 15:49:23 +00001300 ngx_conf_num_bounds_t *bounds = post;
1301 ngx_int_t *np = data;
Igor Sysoevf1079102003-10-23 06:13:16 +00001302
Igor Sysoevcf80a702003-11-03 22:20:44 +00001303 if (bounds->high == -1) {
1304 if (*np >= bounds->low) {
1305 return NGX_CONF_OK;
1306 }
1307
1308 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev02f742b2005-04-08 15:18:55 +00001309 "value must be equal or more than %i", bounds->low);
Igor Sysoevcf80a702003-11-03 22:20:44 +00001310
1311 return NGX_CONF_ERROR;
1312 }
1313
1314 if (*np >= bounds->low && *np <= bounds->high) {
Igor Sysoevf1079102003-10-23 06:13:16 +00001315 return NGX_CONF_OK;
Igor Sysoevf1079102003-10-23 06:13:16 +00001316 }
1317
Igor Sysoevcf80a702003-11-03 22:20:44 +00001318 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev02f742b2005-04-08 15:18:55 +00001319 "value must be between %i and %i",
Igor Sysoevcf80a702003-11-03 22:20:44 +00001320 bounds->low, bounds->high);
1321
1322 return NGX_CONF_ERROR;
Igor Sysoevf1079102003-10-23 06:13:16 +00001323}