blob: 99ed1cb1b6a3a89a8ca8fb319671d4f9a6964f95 [file] [log] [blame]
Igor Sysoev88092572002-12-19 07:08:55 +00001
2#include <ngx_config.h>
Igor Sysoev88092572002-12-19 07:08:55 +00003#include <ngx_core.h>
Igor Sysoev88092572002-12-19 07:08:55 +00004
5
Igor Sysoev6253ca12003-05-27 12:18:54 +00006
Igor Sysoev890fc962003-07-20 21:15:59 +00007#define MAX_CONF_ERRSTR 256
Igor Sysoev6253ca12003-05-27 12:18:54 +00008
Igor Sysoevdc9dd432003-10-22 16:38:26 +00009/* Ten fixed arguments */
10
Igor Sysoev88092572002-12-19 07:08:55 +000011static int argument_number[] = {
12 NGX_CONF_NOARGS,
13 NGX_CONF_TAKE1,
Igor Sysoevdc9dd432003-10-22 16:38:26 +000014 NGX_CONF_TAKE2,
15 NGX_CONF_TAKE3,
16 NGX_CONF_TAKE4,
17 NGX_CONF_TAKE5,
18 NGX_CONF_TAKE6,
19 NGX_CONF_TAKE7,
20 NGX_CONF_TAKE8,
21 NGX_CONF_TAKE9,
Igor Sysoev88092572002-12-19 07:08:55 +000022};
23
Igor Sysoev960ffa42002-12-26 07:24:21 +000024static int ngx_conf_read_token(ngx_conf_t *cf);
Igor Sysoev960ffa42002-12-26 07:24:21 +000025
Igor Sysoev88092572002-12-19 07:08:55 +000026
Igor Sysoev4e9393a2003-01-09 05:36:00 +000027char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
Igor Sysoev88092572002-12-19 07:08:55 +000028{
Igor Sysoevaa3436c2003-05-30 14:27:59 +000029 int m, rc, found, valid;
Igor Sysoev4e9393a2003-01-09 05:36:00 +000030 char *rv;
Igor Sysoeva9830112003-05-19 16:39:14 +000031 void *conf, **confp;
Igor Sysoev207ed5a2002-12-26 16:26:23 +000032 ngx_str_t *name;
Igor Sysoev960ffa42002-12-26 07:24:21 +000033 ngx_fd_t fd;
Igor Sysoev88092572002-12-19 07:08:55 +000034 ngx_conf_file_t *prev;
Igor Sysoev960ffa42002-12-26 07:24:21 +000035 ngx_command_t *cmd;
Igor Sysoev88092572002-12-19 07:08:55 +000036
Igor Sysoev9d639522003-07-07 06:11:50 +000037#if (NGX_SUPPRESS_WARN)
38 fd = NGX_INVALID_FILE;
39 prev = NULL;
40#endif
41
Igor Sysoev88092572002-12-19 07:08:55 +000042 if (filename) {
43
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000044 /* open configuration file */
45
Igor Sysoev7578ec92003-06-02 15:24:30 +000046 fd = ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN);
Igor Sysoev88092572002-12-19 07:08:55 +000047 if (fd == NGX_INVALID_FILE) {
48 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +000049 ngx_open_file_n " %s failed", filename->data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000050 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +000051 }
52
Igor Sysoeva6717c42002-12-23 06:29:22 +000053 prev = cf->conf_file;
54 ngx_test_null(cf->conf_file,
55 ngx_palloc(cf->pool, sizeof(ngx_conf_file_t)),
Igor Sysoev4e9393a2003-01-09 05:36:00 +000056 NGX_CONF_ERROR);
Igor Sysoev88092572002-12-19 07:08:55 +000057
Igor Sysoeva6717c42002-12-23 06:29:22 +000058 if (ngx_stat_fd(fd, &cf->conf_file->file.info) == -1) {
59 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +000060 ngx_stat_fd_n " %s failed", filename->data);
61 }
62
63 ngx_test_null(cf->conf_file->hunk,
64 ngx_create_temp_hunk(cf->pool, 1024, 0, 0),
Igor Sysoev4e9393a2003-01-09 05:36:00 +000065 NGX_CONF_ERROR);
Igor Sysoeva6717c42002-12-23 06:29:22 +000066
67 cf->conf_file->file.fd = fd;
68 cf->conf_file->file.name.len = filename->len;
69 cf->conf_file->file.name.data = filename->data;
Igor Sysoev9d639522003-07-07 06:11:50 +000070 cf->conf_file->file.offset = 0;
Igor Sysoeva6717c42002-12-23 06:29:22 +000071 cf->conf_file->file.log = cf->log;;
72 cf->conf_file->line = 1;
Igor Sysoev88092572002-12-19 07:08:55 +000073 }
74
75 for ( ;; ) {
76 rc = ngx_conf_read_token(cf);
77
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000078 /* ngx_conf_read_token() returns NGX_OK, NGX_ERROR,
79 NGX_CONF_FILE_DONE or NGX_CONF_BLOCK_DONE */
Igor Sysoev88092572002-12-19 07:08:55 +000080
Igor Sysoev73009772003-02-06 17:21:13 +000081#if 0
Igor Sysoev4e9393a2003-01-09 05:36:00 +000082ngx_log_debug(cf->log, "token %d" _ rc);
Igor Sysoev73009772003-02-06 17:21:13 +000083#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +000084
85 if (rc == NGX_ERROR) {
Igor Sysoev9d639522003-07-07 06:11:50 +000086 break;
Igor Sysoev4e9393a2003-01-09 05:36:00 +000087 }
88
89 if (rc != NGX_OK) {
Igor Sysoev9d639522003-07-07 06:11:50 +000090 break;
Igor Sysoev88092572002-12-19 07:08:55 +000091 }
92
Igor Sysoev88092572002-12-19 07:08:55 +000093 if (cf->handler) {
94
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000095 /* custom handler, i.e. used in http "types { ... }" directive */
96
Igor Sysoev79a80482003-05-14 17:13:13 +000097 rv = (*cf->handler)(cf, NULL, cf->handler_conf);
98 if (rv == NGX_CONF_OK) {
99 continue;
100
101 } else if (rv == NGX_CONF_ERROR) {
Igor Sysoev9d639522003-07-07 06:11:50 +0000102 rc = NGX_ERROR;
103 break;
Igor Sysoev79a80482003-05-14 17:13:13 +0000104
105 } else {
106 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000107 "%s in %s:%d",
108 rv,
Igor Sysoev79a80482003-05-14 17:13:13 +0000109 cf->conf_file->file.name.data,
110 cf->conf_file->line);
Igor Sysoev9d639522003-07-07 06:11:50 +0000111 rc = NGX_ERROR;
112 break;
Igor Sysoev88092572002-12-19 07:08:55 +0000113 }
Igor Sysoev88092572002-12-19 07:08:55 +0000114 }
115
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000116 name = (ngx_str_t *) cf->args->elts;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000117 found = 0;
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000118
Igor Sysoev9d639522003-07-07 06:11:50 +0000119 for (m = 0; rc != NGX_ERROR && !found && ngx_modules[m]; m++) {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000120
121 /* look up the directive in the appropriate modules */
122
Igor Sysoev6253ca12003-05-27 12:18:54 +0000123 if (ngx_modules[m]->type != NGX_CONF_MODULE
124 && ngx_modules[m]->type != cf->module_type)
Igor Sysoevc1817842002-12-27 16:22:50 +0000125 {
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000126 continue;
127 }
128
Igor Sysoev6253ca12003-05-27 12:18:54 +0000129 cmd = ngx_modules[m]->commands;
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000130 if (cmd == NULL) {
131 continue;
132 }
133
134 while (cmd->name.len) {
135 if (name->len == cmd->name.len
136 && ngx_strcmp(name->data, cmd->name.data) == 0)
137 {
Igor Sysoevc1817842002-12-27 16:22:50 +0000138
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000139 found = 1;
Igor Sysoev73009772003-02-06 17:21:13 +0000140#if 0
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000141ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data);
Igor Sysoev73009772003-02-06 17:21:13 +0000142#endif
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000143 /* is the directive's location right ? */
Igor Sysoevc1817842002-12-27 16:22:50 +0000144
Igor Sysoev79a80482003-05-14 17:13:13 +0000145 if ((cmd->type & cf->cmd_type) == 0) {
146 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
147 "directive \"%s\" in %s:%d "
148 "is not allowed here",
149 name->data,
150 cf->conf_file->file.name.data,
151 cf->conf_file->line);
Igor Sysoev9d639522003-07-07 06:11:50 +0000152 rc = NGX_ERROR;
153 break;
Igor Sysoev79a80482003-05-14 17:13:13 +0000154 }
155
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000156 /* is the directive's argument count right ? */
157
Igor Sysoevdc9dd432003-10-22 16:38:26 +0000158 if (cmd->type & NGX_CONF_ANY) {
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000159 valid = 1;
160
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000161 } else if (cmd->type & NGX_CONF_FLAG) {
162
163 if (cf->args->nelts == 2) {
164 valid = 1;
165 } else {
166 valid = 0;
167 }
168
Igor Sysoevdc9dd432003-10-22 16:38:26 +0000169 } else if (cmd->type & NGX_CONF_1MORE) {
170
171 if (cf->args->nelts != 1) {
172 valid = 1;
173 } else {
174 valid = 0;
175 }
176
177 } else if (cf->args->nelts <= 10
178 && (cmd->type
179 & argument_number[cf->args->nelts - 1]))
180 {
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000181 valid = 1;
182
183 } else {
184 valid = 0;
185 }
186
187 if (!valid) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000188 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
189 "invalid number arguments in "
190 "directive \"%s\" in %s:%d",
191 name->data,
192 cf->conf_file->file.name.data,
193 cf->conf_file->line);
Igor Sysoev9d639522003-07-07 06:11:50 +0000194 rc = NGX_ERROR;
195 break;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000196 }
197
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000198 /* set up the directive's configuration context */
199
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000200 conf = NULL;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000201
Igor Sysoev6253ca12003-05-27 12:18:54 +0000202 if (cf->module_type == NGX_CORE_MODULE) {
203 conf = &(((void **) cf->ctx)[ngx_modules[m]->index]);
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000204
205 } else if (cf->ctx) {
Igor Sysoeva9830112003-05-19 16:39:14 +0000206 confp = *(void **) ((char *) cf->ctx + cmd->conf);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000207
Igor Sysoeva9830112003-05-19 16:39:14 +0000208 if (confp) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000209 conf = confp[ngx_modules[m]->ctx_index];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000210 }
211 }
212
213 rv = cmd->set(cf, cmd, conf);
214
Igor Sysoev73009772003-02-06 17:21:13 +0000215#if 0
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000216ngx_log_debug(cf->log, "rv: %d" _ rv);
Igor Sysoev73009772003-02-06 17:21:13 +0000217#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000218
219 if (rv == NGX_CONF_OK) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000220 break;
221
222 } else if (rv == NGX_CONF_ERROR) {
Igor Sysoev9d639522003-07-07 06:11:50 +0000223 rc = NGX_ERROR;
224 break;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000225
226 } else {
Igor Sysoev890fc962003-07-20 21:15:59 +0000227 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
228 "\"%s\" directive %s in %s:%d",
229 name->data, rv,
230 cf->conf_file->file.name.data,
231 cf->conf_file->line);
Igor Sysoev6a644c62003-03-04 06:33:48 +0000232
Igor Sysoev9d639522003-07-07 06:11:50 +0000233 rc = NGX_ERROR;
234 break;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000235 }
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000236 }
237
238 cmd++;
239 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000240 }
Igor Sysoev960ffa42002-12-26 07:24:21 +0000241
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000242 if (!found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000243 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
244 "unknown directive \"%s\" in %s:%d",
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000245 name->data,
246 cf->conf_file->file.name.data,
247 cf->conf_file->line);
248
Igor Sysoev9d639522003-07-07 06:11:50 +0000249 rc = NGX_ERROR;
250 break;
Igor Sysoev88092572002-12-19 07:08:55 +0000251 }
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000252
253 if (rc == NGX_ERROR) {
254 break;
255 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000256 }
Igor Sysoev88092572002-12-19 07:08:55 +0000257
258 if (filename) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000259 cf->conf_file = prev;
Igor Sysoev88092572002-12-19 07:08:55 +0000260
261 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000262 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +0000263 ngx_close_file_n " %s failed",
264 cf->conf_file->file.name.data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000265 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000266 }
267 }
268
Igor Sysoev9d639522003-07-07 06:11:50 +0000269 if (rc == NGX_ERROR) {
270 return NGX_CONF_ERROR;
271 }
272
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000273 return NGX_CONF_OK;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000274}
Igor Sysoev88092572002-12-19 07:08:55 +0000275
Igor Sysoev88092572002-12-19 07:08:55 +0000276
Igor Sysoev960ffa42002-12-26 07:24:21 +0000277static int ngx_conf_read_token(ngx_conf_t *cf)
Igor Sysoev88092572002-12-19 07:08:55 +0000278{
279 char *start, ch, *src, *dst;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000280 int len;
281 int found, need_space, last_space, sharp_comment;
282 int quoted, s_quoted, d_quoted;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000283 ssize_t n;
284 ngx_str_t *word;
Igor Sysoev88092572002-12-19 07:08:55 +0000285 ngx_hunk_t *h;
286
Igor Sysoeva6717c42002-12-23 06:29:22 +0000287 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000288 need_space = 0;
289 last_space = 1;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000290 sharp_comment = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000291 quoted = s_quoted = d_quoted = 0;
292
293 cf->args->nelts = 0;
294 h = cf->conf_file->hunk;
Igor Sysoevb7387572003-03-11 20:38:13 +0000295 start = h->pos;
Igor Sysoev88092572002-12-19 07:08:55 +0000296
Igor Sysoev73009772003-02-06 17:21:13 +0000297#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000298ngx_log_debug(cf->log, "TOKEN START");
Igor Sysoev73009772003-02-06 17:21:13 +0000299#endif
Igor Sysoeva6717c42002-12-23 06:29:22 +0000300
Igor Sysoev295bb632002-12-23 18:22:18 +0000301 for ( ;; ) {
Igor Sysoev88092572002-12-19 07:08:55 +0000302
Igor Sysoevb7387572003-03-11 20:38:13 +0000303 if (h->pos >= h->last) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000304 if (cf->conf_file->file.offset
305 >= ngx_file_size(cf->conf_file->file.info)) {
Igor Sysoev960ffa42002-12-26 07:24:21 +0000306 return NGX_CONF_FILE_DONE;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000307 }
308
Igor Sysoevb7387572003-03-11 20:38:13 +0000309 if (h->pos - start) {
310 ngx_memcpy(h->start, start, h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000311 }
312
Igor Sysoeva6717c42002-12-23 06:29:22 +0000313 n = ngx_read_file(&cf->conf_file->file,
Igor Sysoevb7387572003-03-11 20:38:13 +0000314 h->start + (h->pos - start),
315 h->end - (h->start + (h->pos - start)),
Igor Sysoev88092572002-12-19 07:08:55 +0000316 cf->conf_file->file.offset);
317
318 if (n == NGX_ERROR) {
319 return NGX_ERROR;
320 }
321
Igor Sysoevb7387572003-03-11 20:38:13 +0000322 h->pos = h->start + (h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000323 start = h->start;
Igor Sysoevb7387572003-03-11 20:38:13 +0000324 h->last = h->pos + n;
Igor Sysoev88092572002-12-19 07:08:55 +0000325 }
326
Igor Sysoevb7387572003-03-11 20:38:13 +0000327 ch = *h->pos++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000328
Igor Sysoev295bb632002-12-23 18:22:18 +0000329#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000330ngx_log_debug(cf->log, "%d:%d:%d:%d:%d '%c'" _
331 last_space _ need_space _
332 quoted _ s_quoted _ d_quoted _ ch);
Igor Sysoev295bb632002-12-23 18:22:18 +0000333#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000334
335 if (ch == LF) {
336 cf->conf_file->line++;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000337
338 if (sharp_comment) {
339 sharp_comment = 0;
340 }
341 }
342
343 if (sharp_comment) {
344 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000345 }
346
Igor Sysoev295bb632002-12-23 18:22:18 +0000347 if (quoted) {
348 quoted = 0;
349 continue;
350 }
351
Igor Sysoeva6717c42002-12-23 06:29:22 +0000352 if (need_space) {
353 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
354 last_space = 1;
355 need_space = 0;
356 continue;
357 }
358
359 if (ch == ';' || ch == '{') {
360 return NGX_OK;
361 }
362
363 return NGX_ERROR;
364 }
365
Igor Sysoev88092572002-12-19 07:08:55 +0000366 if (last_space) {
Igor Sysoev88092572002-12-19 07:08:55 +0000367 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000368 continue;
369 }
370
Igor Sysoevb7387572003-03-11 20:38:13 +0000371 start = h->pos - 1;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000372
373 switch (ch) {
374
Igor Sysoev295bb632002-12-23 18:22:18 +0000375 case ';':
376 case '{':
Igor Sysoev960ffa42002-12-26 07:24:21 +0000377 if (cf->args->nelts == 0) {
378 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
379 "unexpected '%c' in %s:%d",
380 ch, cf->conf_file->file.name.data,
381 cf->conf_file->line);
382 return NGX_ERROR;
383 }
384
Igor Sysoev295bb632002-12-23 18:22:18 +0000385 return NGX_OK;
386
Igor Sysoev960ffa42002-12-26 07:24:21 +0000387 case '}':
388 if (cf->args->nelts > 0) {
389 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
390 "unexpected '}' in %s:%d",
391 cf->conf_file->file.name.data,
392 cf->conf_file->line);
393 return NGX_ERROR;
394 }
395
396 return NGX_CONF_BLOCK_DONE;
397
398 case '#':
399 sharp_comment = 1;
400 continue;
401
Igor Sysoeva6717c42002-12-23 06:29:22 +0000402 case '\\':
403 quoted = 1;
404 last_space = 0;
405 continue;
406
407 case '"':
Igor Sysoev88092572002-12-19 07:08:55 +0000408 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000409 d_quoted = 1;
410 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000411 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000412
Igor Sysoeva6717c42002-12-23 06:29:22 +0000413 case '\'':
414 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000415 s_quoted = 1;
416 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000417 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000418
Igor Sysoeva6717c42002-12-23 06:29:22 +0000419 default:
420 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000421 }
422
423 } else {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000424 if (ch == '\\') {
425 quoted = 1;
426 continue;
427 }
Igor Sysoev88092572002-12-19 07:08:55 +0000428
Igor Sysoeva6717c42002-12-23 06:29:22 +0000429 if (d_quoted) {
430 if (ch == '"') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000431 d_quoted = 0;
432 need_space = 1;
433 found = 1;
434 }
435
436 } else if (s_quoted) {
437 if (ch == '\'') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000438 s_quoted = 0;
439 need_space = 1;
440 found = 1;
441 }
442
443 } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
444 || ch == ';' || ch == '{') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000445 last_space = 1;
446 found = 1;
447 }
448
449 if (found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000450 ngx_test_null(word, ngx_push_array(cf->args), NGX_ERROR);
Igor Sysoev295bb632002-12-23 18:22:18 +0000451 ngx_test_null(word->data,
Igor Sysoevb7387572003-03-11 20:38:13 +0000452 ngx_palloc(cf->pool, h->pos - start + 1),
Igor Sysoev88092572002-12-19 07:08:55 +0000453 NGX_ERROR);
Igor Sysoev88092572002-12-19 07:08:55 +0000454
Igor Sysoev295bb632002-12-23 18:22:18 +0000455 for (dst = word->data, src = start, len = 0;
Igor Sysoevb7387572003-03-11 20:38:13 +0000456 src < h->pos - 1;
Igor Sysoev295bb632002-12-23 18:22:18 +0000457 len++)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000458 {
459 if (*src == '\\') {
Igor Sysoev88092572002-12-19 07:08:55 +0000460 src++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000461 }
Igor Sysoev88092572002-12-19 07:08:55 +0000462 *dst++ = *src++;
463 }
464 *dst = '\0';
Igor Sysoev295bb632002-12-23 18:22:18 +0000465 word->len = len;
Igor Sysoev88092572002-12-19 07:08:55 +0000466
Igor Sysoev73009772003-02-06 17:21:13 +0000467#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000468ngx_log_debug(cf->log, "FOUND %d:'%s'" _ word->len _ word->data);
Igor Sysoev73009772003-02-06 17:21:13 +0000469#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000470
Igor Sysoeva6717c42002-12-23 06:29:22 +0000471 if (ch == ';' || ch == '{') {
472 return NGX_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000473 }
474
Igor Sysoeva6717c42002-12-23 06:29:22 +0000475 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000476 }
Igor Sysoev88092572002-12-19 07:08:55 +0000477 }
478 }
479}
480
Igor Sysoev88092572002-12-19 07:08:55 +0000481
Igor Sysoev890fc962003-07-20 21:15:59 +0000482ngx_open_file_t *ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
483{
484 int i;
485 ngx_open_file_t *file;
486
487 if (name) {
488 file = cycle->open_files.elts;
489 for (i = 0; i < cycle->open_files.nelts; i++) {
490 if (name->len != file[i].name.len) {
491 continue;
492 }
493
494 if (ngx_strcmp(name->data, file[i].name.data) == 0) {
495 return &file[i];
496 }
497 }
498 }
499
500 ngx_test_null(file, ngx_push_array(&cycle->open_files), NULL);
501 file->fd = NGX_INVALID_FILE;
502 if (name) {
503 file->name = *name;
504 }
505
506 return file;
507}
508
509
Igor Sysoev8e1fbe62003-07-18 14:44:05 +0000510void ngx_conf_log_error(int level, ngx_conf_t *cf, ngx_err_t err,
511 char *fmt, ...)
512{
513 int len;
514 char errstr[MAX_CONF_ERRSTR];
515 va_list args;
516
517 va_start(args, fmt);
518 len = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args);
519 va_end(args);
520
521 if (err) {
522 len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1,
523 " (%d: ", err);
524 len += ngx_strerror_r(err, errstr + len, sizeof(errstr) - len - 1);
525 errstr[len++] = ')';
526 errstr[len++] = '\0';
527 }
528
529 ngx_log_error(level, cf->log, 0, "%s in %s:%d",
530 errstr, cf->conf_file->file.name.data, cf->conf_file->line);
531}
532
533
Igor Sysoev7f125082003-07-11 15:17:50 +0000534char *ngx_conf_set_core_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd,
535 void *conf)
536{
537 return ngx_conf_set_flag_slot(cf, cmd, *(void **)conf);
538}
539
540
Igor Sysoev6253ca12003-05-27 12:18:54 +0000541char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000542{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000543 char *p = conf;
544
Igor Sysoev6a644c62003-03-04 06:33:48 +0000545 int flag;
546 ngx_str_t *value;
547
Igor Sysoevf1079102003-10-23 06:13:16 +0000548
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000549 if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000550 return "is duplicate";
551 }
552
Igor Sysoev6a644c62003-03-04 06:33:48 +0000553 value = (ngx_str_t *) cf->args->elts;
554
555 if (ngx_strcasecmp(value[1].data, "on") == 0) {
556 flag = 1;
557
558 } else if (ngx_strcasecmp(value[1].data, "off") == 0) {
559 flag = 0;
560
561 } else {
Igor Sysoev890fc962003-07-20 21:15:59 +0000562 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
563 "invalid value \"%s\" in \"%s\" directive, "
564 "it must be \"on\" or \"off\"",
565 value[1].data, cmd->name.data);
566 return NGX_CONF_ERROR;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000567 }
568
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000569 *(int *) (p + cmd->offset) = flag;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000570
571 return NGX_CONF_OK;
572}
573
574
Igor Sysoev6253ca12003-05-27 12:18:54 +0000575char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000576{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000577 char *p = conf;
578
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000579 ngx_str_t *field, *value;
580
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000581 field = (ngx_str_t *) (p + cmd->offset);
Igor Sysoev1c13c662003-05-20 15:37:55 +0000582
Igor Sysoev6253ca12003-05-27 12:18:54 +0000583 if (field->data) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000584 return "is duplicate";
585 }
586
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000587 value = (ngx_str_t *) cf->args->elts;
588
Igor Sysoevdc9dd432003-10-22 16:38:26 +0000589 *field = value[1];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000590
591 return NGX_CONF_OK;
592}
593
594
Igor Sysoev6253ca12003-05-27 12:18:54 +0000595char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000596{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000597 char *p = conf;
598
Igor Sysoevf1079102003-10-23 06:13:16 +0000599 int *np;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000600 ngx_str_t *value;
601
Igor Sysoevf1079102003-10-23 06:13:16 +0000602
603 np = (int *) (p + cmd->offset);
604
605 if (*np != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000606 return "is duplicate";
607 }
608
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000609 value = (ngx_str_t *) cf->args->elts;
Igor Sysoevf1079102003-10-23 06:13:16 +0000610 *np = ngx_atoi(value[1].data, value[1].len);
611 if (*np == NGX_ERROR) {
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000612 return "invalid number";
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000613 }
614
Igor Sysoevf1079102003-10-23 06:13:16 +0000615 if (cmd->bounds) {
616 return cmd->bounds->check(cf, cmd->bounds, np);
617 }
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000618
619 return NGX_CONF_OK;
620}
621
622
Igor Sysoev6253ca12003-05-27 12:18:54 +0000623char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000624{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000625 char *p = conf;
626
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000627 int *np;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000628 ngx_str_t *value;
629
Igor Sysoevf1079102003-10-23 06:13:16 +0000630
631 np = (int *) (p + cmd->offset);
Igor Sysoevf1079102003-10-23 06:13:16 +0000632 if (*np != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000633 return "is duplicate";
634 }
635
Igor Sysoev960ffa42002-12-26 07:24:21 +0000636 value = (ngx_str_t *) cf->args->elts;
637
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000638 *np = ngx_parse_size(&value[1]);
639 if (*np == NGX_ERROR) {
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000640 return "invalid value";
Igor Sysoev960ffa42002-12-26 07:24:21 +0000641 }
Igor Sysoev88092572002-12-19 07:08:55 +0000642
Igor Sysoevf1079102003-10-23 06:13:16 +0000643 if (cmd->bounds) {
644 return cmd->bounds->check(cf, cmd->bounds, np);
645 }
Igor Sysoev960ffa42002-12-26 07:24:21 +0000646
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000647 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000648}
649
Igor Sysoev88092572002-12-19 07:08:55 +0000650
Igor Sysoev6253ca12003-05-27 12:18:54 +0000651char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000652{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000653 char *p = conf;
654
Igor Sysoevf1079102003-10-23 06:13:16 +0000655 int size, total, len, scale, *np;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000656 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000657 char last, *start;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000658 ngx_str_t *value;
659
Igor Sysoevf1079102003-10-23 06:13:16 +0000660
661 np = (int *) (p + cmd->offset);
Igor Sysoevf1079102003-10-23 06:13:16 +0000662 if (*np != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000663 return "is duplicate";
664 }
665
Igor Sysoev960ffa42002-12-26 07:24:21 +0000666 value = (ngx_str_t *) cf->args->elts;
667
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000668 *np = ngx_parse_time(&value[1], 0);
669 if (*np == NGX_ERROR) {
670 return "invalid value";
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000671 }
672
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000673 if (*np == NGX_PARSE_LARGE_TIME) {
674 return "value must be less than 597 hours";
675 }
Igor Sysoevf1079102003-10-23 06:13:16 +0000676
677 if (cmd->bounds) {
678 return cmd->bounds->check(cf, cmd->bounds, np);
679 }
Igor Sysoev960ffa42002-12-26 07:24:21 +0000680
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000681 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000682}
Igor Sysoev6a644c62003-03-04 06:33:48 +0000683
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000684
Igor Sysoev6253ca12003-05-27 12:18:54 +0000685char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000686{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000687 char *p = conf;
688
Igor Sysoevf1079102003-10-23 06:13:16 +0000689 int size, total, len, scale, *np;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000690 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000691 char last, *start;
692 ngx_str_t *value;
693
Igor Sysoevf1079102003-10-23 06:13:16 +0000694
695 np = (int *) (p + cmd->offset);
Igor Sysoevf1079102003-10-23 06:13:16 +0000696 if (*np != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000697 return "is duplicate";
698 }
699
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000700 value = (ngx_str_t *) cf->args->elts;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000701
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000702 *np = ngx_parse_time(&value[1], 1);
703 if (*np == NGX_ERROR) {
704 return "invalid value";
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000705 }
706
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000707 if (*np == NGX_PARSE_LARGE_TIME) {
708 return "value must be less than 68 years";
709 }
Igor Sysoevf1079102003-10-23 06:13:16 +0000710
711 if (cmd->bounds) {
712 return cmd->bounds->check(cf, cmd->bounds, np);
713 }
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000714
715 return NGX_CONF_OK;
716}
717
718
Igor Sysoev3ae32482003-10-08 15:32:54 +0000719char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
720{
721 char *p = conf;
722
Igor Sysoev3ae32482003-10-08 15:32:54 +0000723 ngx_str_t *value;
724 ngx_bufs_t *bufs;
725
726
727 bufs = (ngx_bufs_t *) (p + cmd->offset);
Igor Sysoev3ae32482003-10-08 15:32:54 +0000728 if (bufs->num) {
729 return "is duplicate";
730 }
731
732 value = (ngx_str_t *) cf->args->elts;
733
734 bufs->num = ngx_atoi(value[1].data, value[1].len);
735 if (bufs->num == NGX_ERROR || bufs->num == 0) {
736 return "invalid value";
737 }
738
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000739 bufs->size = ngx_parse_size(&value[2]);
Igor Sysoev3ae32482003-10-08 15:32:54 +0000740 if (bufs->size == NGX_ERROR || bufs->size == 0) {
741 return "invalid value";
742 }
743
Igor Sysoev3ae32482003-10-08 15:32:54 +0000744 return NGX_CONF_OK;
745}
746
747
Igor Sysoev6253ca12003-05-27 12:18:54 +0000748char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000749{
750 return "unsupported on this platform";
751}
Igor Sysoevf1079102003-10-23 06:13:16 +0000752
753
754char *ngx_conf_check_num_bounds(ngx_conf_t *cf, ngx_conf_bounds_t *bounds,
755 void *conf)
756{
757 int *num = conf;
758
759 if (*num >= bounds->type.num.low && *num <= bounds->type.num.high) {
760 return NGX_CONF_OK;
761
762 }
763
764 return "invalid value";
765}