blob: 527cbdfe0922e051e71e251b27d9f54d9a121cfe [file] [log] [blame]
Igor Sysoev88092572002-12-19 07:08:55 +00001
2#include <ngx_config.h>
Igor Sysoev86de4cb2003-01-30 07:28:09 +00003
Igor Sysoev88092572002-12-19 07:08:55 +00004#include <ngx_core.h>
Igor Sysoev86de4cb2003-01-30 07:28:09 +00005#include <ngx_files.h>
Igor Sysoevc1817842002-12-27 16:22:50 +00006#include <ngx_conf_file.h>
Igor Sysoev88092572002-12-19 07:08:55 +00007
8
Igor Sysoev6253ca12003-05-27 12:18:54 +00009char ngx_conf_errstr[MAX_CONF_ERRSTR];
10
11
Igor Sysoev88092572002-12-19 07:08:55 +000012static int argument_number[] = {
13 NGX_CONF_NOARGS,
14 NGX_CONF_TAKE1,
15 NGX_CONF_TAKE2
16};
17
Igor Sysoev960ffa42002-12-26 07:24:21 +000018static int ngx_conf_read_token(ngx_conf_t *cf);
Igor Sysoev960ffa42002-12-26 07:24:21 +000019
Igor Sysoev88092572002-12-19 07:08:55 +000020
Igor Sysoev4e9393a2003-01-09 05:36:00 +000021char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
Igor Sysoev88092572002-12-19 07:08:55 +000022{
Igor Sysoev6253ca12003-05-27 12:18:54 +000023 int m, rc, found;
Igor Sysoev4e9393a2003-01-09 05:36:00 +000024 char *rv;
Igor Sysoeva9830112003-05-19 16:39:14 +000025 void *conf, **confp;
Igor Sysoev207ed5a2002-12-26 16:26:23 +000026 ngx_str_t *name;
Igor Sysoev960ffa42002-12-26 07:24:21 +000027 ngx_fd_t fd;
Igor Sysoev88092572002-12-19 07:08:55 +000028 ngx_conf_file_t *prev;
Igor Sysoev960ffa42002-12-26 07:24:21 +000029 ngx_command_t *cmd;
Igor Sysoev88092572002-12-19 07:08:55 +000030
31 if (filename) {
32
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000033 /* open configuration file */
34
Igor Sysoeva6717c42002-12-23 06:29:22 +000035 fd = ngx_open_file(filename->data, NGX_FILE_RDONLY);
Igor Sysoev88092572002-12-19 07:08:55 +000036 if (fd == NGX_INVALID_FILE) {
37 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +000038 ngx_open_file_n " %s failed", filename->data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000039 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +000040 }
41
Igor Sysoeva6717c42002-12-23 06:29:22 +000042 prev = cf->conf_file;
43 ngx_test_null(cf->conf_file,
44 ngx_palloc(cf->pool, sizeof(ngx_conf_file_t)),
Igor Sysoev4e9393a2003-01-09 05:36:00 +000045 NGX_CONF_ERROR);
Igor Sysoev88092572002-12-19 07:08:55 +000046
Igor Sysoeva6717c42002-12-23 06:29:22 +000047 if (ngx_stat_fd(fd, &cf->conf_file->file.info) == -1) {
48 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +000049 ngx_stat_fd_n " %s failed", filename->data);
50 }
51
52 ngx_test_null(cf->conf_file->hunk,
53 ngx_create_temp_hunk(cf->pool, 1024, 0, 0),
Igor Sysoev4e9393a2003-01-09 05:36:00 +000054 NGX_CONF_ERROR);
Igor Sysoeva6717c42002-12-23 06:29:22 +000055
56 cf->conf_file->file.fd = fd;
57 cf->conf_file->file.name.len = filename->len;
58 cf->conf_file->file.name.data = filename->data;
59 cf->conf_file->file.log = cf->log;;
60 cf->conf_file->line = 1;
Igor Sysoev88092572002-12-19 07:08:55 +000061 }
62
63 for ( ;; ) {
64 rc = ngx_conf_read_token(cf);
65
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000066 /* ngx_conf_read_token() returns NGX_OK, NGX_ERROR,
67 NGX_CONF_FILE_DONE or NGX_CONF_BLOCK_DONE */
Igor Sysoev88092572002-12-19 07:08:55 +000068
Igor Sysoev73009772003-02-06 17:21:13 +000069#if 0
Igor Sysoev4e9393a2003-01-09 05:36:00 +000070ngx_log_debug(cf->log, "token %d" _ rc);
Igor Sysoev73009772003-02-06 17:21:13 +000071#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +000072
73 if (rc == NGX_ERROR) {
74 return NGX_CONF_ERROR;
75 }
76
77 if (rc != NGX_OK) {
78 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +000079 }
80
Igor Sysoev88092572002-12-19 07:08:55 +000081 if (cf->handler) {
82
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000083 /* custom handler, i.e. used in http "types { ... }" directive */
84
Igor Sysoev79a80482003-05-14 17:13:13 +000085 rv = (*cf->handler)(cf, NULL, cf->handler_conf);
86 if (rv == NGX_CONF_OK) {
87 continue;
88
89 } else if (rv == NGX_CONF_ERROR) {
90 return NGX_CONF_ERROR;
91
92 } else {
93 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoev6ddfbf02003-05-15 15:42:53 +000094 "%s in %s:%d",
95 rv,
Igor Sysoev79a80482003-05-14 17:13:13 +000096 cf->conf_file->file.name.data,
97 cf->conf_file->line);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000098 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +000099 }
Igor Sysoev88092572002-12-19 07:08:55 +0000100 }
101
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000102 name = (ngx_str_t *) cf->args->elts;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000103 found = 0;
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000104
Igor Sysoev6253ca12003-05-27 12:18:54 +0000105 for (m = 0; !found && ngx_modules[m]; m++) {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000106
107 /* look up the directive in the appropriate modules */
108
Igor Sysoev6253ca12003-05-27 12:18:54 +0000109 if (ngx_modules[m]->type != NGX_CONF_MODULE
110 && ngx_modules[m]->type != cf->module_type)
Igor Sysoevc1817842002-12-27 16:22:50 +0000111 {
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000112 continue;
113 }
114
Igor Sysoev6253ca12003-05-27 12:18:54 +0000115 cmd = ngx_modules[m]->commands;
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000116 if (cmd == NULL) {
117 continue;
118 }
119
120 while (cmd->name.len) {
121 if (name->len == cmd->name.len
122 && ngx_strcmp(name->data, cmd->name.data) == 0)
123 {
Igor Sysoevc1817842002-12-27 16:22:50 +0000124
Igor Sysoev73009772003-02-06 17:21:13 +0000125#if 0
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000126ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data);
Igor Sysoev73009772003-02-06 17:21:13 +0000127#endif
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000128 /* is the directive's location right ? */
Igor Sysoevc1817842002-12-27 16:22:50 +0000129
Igor Sysoev79a80482003-05-14 17:13:13 +0000130 if ((cmd->type & cf->cmd_type) == 0) {
131 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
132 "directive \"%s\" in %s:%d "
133 "is not allowed here",
134 name->data,
135 cf->conf_file->file.name.data,
136 cf->conf_file->line);
137 return NGX_CONF_ERROR;
138 }
139
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000140 /* is the directive's argument count right ? */
141
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000142 if (!(cmd->type & NGX_CONF_ANY)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000143 && ((cmd->type & NGX_CONF_FLAG && cf->args->nelts != 2)
144 || (!(cmd->type & NGX_CONF_FLAG)
145 && !(cmd->type
146 & argument_number[cf->args->nelts - 1])
147 )
148 )
149 )
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000150 {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000151 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
152 "invalid number arguments in "
153 "directive \"%s\" in %s:%d",
154 name->data,
155 cf->conf_file->file.name.data,
156 cf->conf_file->line);
157 return NGX_CONF_ERROR;
158 }
159
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000160 /* set up the directive's configuration context */
161
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000162 conf = NULL;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000163
Igor Sysoev6253ca12003-05-27 12:18:54 +0000164 if (cf->module_type == NGX_CORE_MODULE) {
165 conf = &(((void **) cf->ctx)[ngx_modules[m]->index]);
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000166
167 } else if (cf->ctx) {
Igor Sysoeva9830112003-05-19 16:39:14 +0000168 confp = *(void **) ((char *) cf->ctx + cmd->conf);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000169
Igor Sysoeva9830112003-05-19 16:39:14 +0000170 if (confp) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000171 conf = confp[ngx_modules[m]->ctx_index];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000172 }
173 }
174
175 rv = cmd->set(cf, cmd, conf);
176
Igor Sysoev73009772003-02-06 17:21:13 +0000177#if 0
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000178ngx_log_debug(cf->log, "rv: %d" _ rv);
Igor Sysoev73009772003-02-06 17:21:13 +0000179#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000180
181 if (rv == NGX_CONF_OK) {
182 found = 1;
183 break;
184
185 } else if (rv == NGX_CONF_ERROR) {
186 return NGX_CONF_ERROR;
187
188 } else {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000189 if (rv == ngx_conf_errstr) {
190 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
191 "%s in %s:%d",
192 rv,
193 cf->conf_file->file.name.data,
194 cf->conf_file->line);
195 } else {
196 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
197 "%s %s in %s:%d",
198 name->data, rv,
199 cf->conf_file->file.name.data,
200 cf->conf_file->line);
201 }
Igor Sysoev6a644c62003-03-04 06:33:48 +0000202
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000203 return NGX_CONF_ERROR;
204 }
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000205 }
206
207 cmd++;
208 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000209 }
Igor Sysoev960ffa42002-12-26 07:24:21 +0000210
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000211 if (!found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000212 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
213 "unknown directive \"%s\" in %s:%d",
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000214 name->data,
215 cf->conf_file->file.name.data,
216 cf->conf_file->line);
217
218 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000219 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000220 }
Igor Sysoev88092572002-12-19 07:08:55 +0000221
222 if (filename) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000223 cf->conf_file = prev;
Igor Sysoev88092572002-12-19 07:08:55 +0000224
225 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000226 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +0000227 ngx_close_file_n " %s failed",
228 cf->conf_file->file.name.data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000229 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000230 }
231 }
232
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000233 return NGX_CONF_OK;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000234}
Igor Sysoev88092572002-12-19 07:08:55 +0000235
Igor Sysoev88092572002-12-19 07:08:55 +0000236
Igor Sysoev960ffa42002-12-26 07:24:21 +0000237static int ngx_conf_read_token(ngx_conf_t *cf)
Igor Sysoev88092572002-12-19 07:08:55 +0000238{
239 char *start, ch, *src, *dst;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000240 int len;
241 int found, need_space, last_space, sharp_comment;
242 int quoted, s_quoted, d_quoted;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000243 ssize_t n;
244 ngx_str_t *word;
Igor Sysoev88092572002-12-19 07:08:55 +0000245 ngx_hunk_t *h;
246
Igor Sysoeva6717c42002-12-23 06:29:22 +0000247 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000248 need_space = 0;
249 last_space = 1;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000250 sharp_comment = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000251 quoted = s_quoted = d_quoted = 0;
252
253 cf->args->nelts = 0;
254 h = cf->conf_file->hunk;
Igor Sysoevb7387572003-03-11 20:38:13 +0000255 start = h->pos;
Igor Sysoev88092572002-12-19 07:08:55 +0000256
Igor Sysoev73009772003-02-06 17:21:13 +0000257#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000258ngx_log_debug(cf->log, "TOKEN START");
Igor Sysoev73009772003-02-06 17:21:13 +0000259#endif
Igor Sysoeva6717c42002-12-23 06:29:22 +0000260
Igor Sysoev295bb632002-12-23 18:22:18 +0000261 for ( ;; ) {
Igor Sysoev88092572002-12-19 07:08:55 +0000262
Igor Sysoevb7387572003-03-11 20:38:13 +0000263 if (h->pos >= h->last) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000264 if (cf->conf_file->file.offset
265 >= ngx_file_size(cf->conf_file->file.info)) {
Igor Sysoev960ffa42002-12-26 07:24:21 +0000266 return NGX_CONF_FILE_DONE;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000267 }
268
Igor Sysoevb7387572003-03-11 20:38:13 +0000269 if (h->pos - start) {
270 ngx_memcpy(h->start, start, h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000271 }
272
Igor Sysoeva6717c42002-12-23 06:29:22 +0000273 n = ngx_read_file(&cf->conf_file->file,
Igor Sysoevb7387572003-03-11 20:38:13 +0000274 h->start + (h->pos - start),
275 h->end - (h->start + (h->pos - start)),
Igor Sysoev88092572002-12-19 07:08:55 +0000276 cf->conf_file->file.offset);
277
278 if (n == NGX_ERROR) {
279 return NGX_ERROR;
280 }
281
Igor Sysoevb7387572003-03-11 20:38:13 +0000282 h->pos = h->start + (h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000283 start = h->start;
Igor Sysoevb7387572003-03-11 20:38:13 +0000284 h->last = h->pos + n;
Igor Sysoev88092572002-12-19 07:08:55 +0000285 }
286
Igor Sysoevb7387572003-03-11 20:38:13 +0000287 ch = *h->pos++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000288
Igor Sysoev295bb632002-12-23 18:22:18 +0000289#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000290ngx_log_debug(cf->log, "%d:%d:%d:%d:%d '%c'" _
291 last_space _ need_space _
292 quoted _ s_quoted _ d_quoted _ ch);
Igor Sysoev295bb632002-12-23 18:22:18 +0000293#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000294
295 if (ch == LF) {
296 cf->conf_file->line++;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000297
298 if (sharp_comment) {
299 sharp_comment = 0;
300 }
301 }
302
303 if (sharp_comment) {
304 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000305 }
306
Igor Sysoev295bb632002-12-23 18:22:18 +0000307 if (quoted) {
308 quoted = 0;
309 continue;
310 }
311
Igor Sysoeva6717c42002-12-23 06:29:22 +0000312 if (need_space) {
313 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
314 last_space = 1;
315 need_space = 0;
316 continue;
317 }
318
319 if (ch == ';' || ch == '{') {
320 return NGX_OK;
321 }
322
323 return NGX_ERROR;
324 }
325
Igor Sysoev88092572002-12-19 07:08:55 +0000326 if (last_space) {
Igor Sysoev88092572002-12-19 07:08:55 +0000327 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000328 continue;
329 }
330
Igor Sysoevb7387572003-03-11 20:38:13 +0000331 start = h->pos - 1;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000332
333 switch (ch) {
334
Igor Sysoev295bb632002-12-23 18:22:18 +0000335 case ';':
336 case '{':
Igor Sysoev960ffa42002-12-26 07:24:21 +0000337 if (cf->args->nelts == 0) {
338 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
339 "unexpected '%c' in %s:%d",
340 ch, cf->conf_file->file.name.data,
341 cf->conf_file->line);
342 return NGX_ERROR;
343 }
344
Igor Sysoev295bb632002-12-23 18:22:18 +0000345 return NGX_OK;
346
Igor Sysoev960ffa42002-12-26 07:24:21 +0000347 case '}':
348 if (cf->args->nelts > 0) {
349 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
350 "unexpected '}' in %s:%d",
351 cf->conf_file->file.name.data,
352 cf->conf_file->line);
353 return NGX_ERROR;
354 }
355
356 return NGX_CONF_BLOCK_DONE;
357
358 case '#':
359 sharp_comment = 1;
360 continue;
361
Igor Sysoeva6717c42002-12-23 06:29:22 +0000362 case '\\':
363 quoted = 1;
364 last_space = 0;
365 continue;
366
367 case '"':
Igor Sysoev88092572002-12-19 07:08:55 +0000368 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000369 d_quoted = 1;
370 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000371 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000372
Igor Sysoeva6717c42002-12-23 06:29:22 +0000373 case '\'':
374 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000375 s_quoted = 1;
376 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000377 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000378
Igor Sysoeva6717c42002-12-23 06:29:22 +0000379 default:
380 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000381 }
382
383 } else {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000384 if (ch == '\\') {
385 quoted = 1;
386 continue;
387 }
Igor Sysoev88092572002-12-19 07:08:55 +0000388
Igor Sysoeva6717c42002-12-23 06:29:22 +0000389 if (d_quoted) {
390 if (ch == '"') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000391 d_quoted = 0;
392 need_space = 1;
393 found = 1;
394 }
395
396 } else if (s_quoted) {
397 if (ch == '\'') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000398 s_quoted = 0;
399 need_space = 1;
400 found = 1;
401 }
402
403 } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
404 || ch == ';' || ch == '{') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000405 last_space = 1;
406 found = 1;
407 }
408
409 if (found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000410 ngx_test_null(word, ngx_push_array(cf->args), NGX_ERROR);
Igor Sysoev295bb632002-12-23 18:22:18 +0000411 ngx_test_null(word->data,
Igor Sysoevb7387572003-03-11 20:38:13 +0000412 ngx_palloc(cf->pool, h->pos - start + 1),
Igor Sysoev88092572002-12-19 07:08:55 +0000413 NGX_ERROR);
Igor Sysoev88092572002-12-19 07:08:55 +0000414
Igor Sysoev295bb632002-12-23 18:22:18 +0000415 for (dst = word->data, src = start, len = 0;
Igor Sysoevb7387572003-03-11 20:38:13 +0000416 src < h->pos - 1;
Igor Sysoev295bb632002-12-23 18:22:18 +0000417 len++)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000418 {
419 if (*src == '\\') {
Igor Sysoev88092572002-12-19 07:08:55 +0000420 src++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000421 }
Igor Sysoev88092572002-12-19 07:08:55 +0000422 *dst++ = *src++;
423 }
424 *dst = '\0';
Igor Sysoev295bb632002-12-23 18:22:18 +0000425 word->len = len;
Igor Sysoev88092572002-12-19 07:08:55 +0000426
Igor Sysoev73009772003-02-06 17:21:13 +0000427#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000428ngx_log_debug(cf->log, "FOUND %d:'%s'" _ word->len _ word->data);
Igor Sysoev73009772003-02-06 17:21:13 +0000429#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000430
Igor Sysoeva6717c42002-12-23 06:29:22 +0000431 if (ch == ';' || ch == '{') {
432 return NGX_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000433 }
434
Igor Sysoeva6717c42002-12-23 06:29:22 +0000435 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000436 }
Igor Sysoev88092572002-12-19 07:08:55 +0000437 }
438 }
439}
440
Igor Sysoev88092572002-12-19 07:08:55 +0000441
Igor Sysoev6253ca12003-05-27 12:18:54 +0000442char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000443{
444 int flag;
445 ngx_str_t *value;
446
Igor Sysoev1c13c662003-05-20 15:37:55 +0000447 if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) {
448 return "is duplicate";
449 }
450
Igor Sysoev6a644c62003-03-04 06:33:48 +0000451 value = (ngx_str_t *) cf->args->elts;
452
453 if (ngx_strcasecmp(value[1].data, "on") == 0) {
454 flag = 1;
455
456 } else if (ngx_strcasecmp(value[1].data, "off") == 0) {
457 flag = 0;
458
459 } else {
460 return "must be \"on\" or \"off\"";
461 }
462
463 *(int *) (conf + cmd->offset) = flag;
464
465 return NGX_CONF_OK;
466}
467
468
Igor Sysoev6253ca12003-05-27 12:18:54 +0000469char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000470{
471 ngx_str_t *field, *value;
472
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000473 field = (ngx_str_t *) (conf + cmd->offset);
Igor Sysoev1c13c662003-05-20 15:37:55 +0000474
Igor Sysoev6253ca12003-05-27 12:18:54 +0000475 if (field->data) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000476 return "is duplicate";
477 }
478
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000479 value = (ngx_str_t *) cf->args->elts;
480
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000481 field->len = value[1].len;
482 field->data = value[1].data;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000483
484 return NGX_CONF_OK;
485}
486
487
Igor Sysoev6253ca12003-05-27 12:18:54 +0000488char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000489{
490 int num, len;
491 ngx_str_t *value;
492
Igor Sysoev1c13c662003-05-20 15:37:55 +0000493 if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) {
494 return "is duplicate";
495 }
496
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000497 value = (ngx_str_t *) cf->args->elts;
498
499 len = value[1].len;
500
501 num = ngx_atoi(value[1].data, len);
502 if (num == NGX_ERROR) {
503 return "invalid value";
504 }
505
506 *(int *) (conf + cmd->offset) = num;
507
508 return NGX_CONF_OK;
509}
510
511
Igor Sysoev6253ca12003-05-27 12:18:54 +0000512char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000513{
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000514 int size, len, scale;
515 char last;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000516 ngx_str_t *value;
517
Igor Sysoev1c13c662003-05-20 15:37:55 +0000518 if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) {
519 return "is duplicate";
520 }
521
Igor Sysoev960ffa42002-12-26 07:24:21 +0000522 value = (ngx_str_t *) cf->args->elts;
523
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000524 len = value[1].len;
525 last = value[1].data[len - 1];
526
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000527 switch (last) {
528 case 'K':
529 case 'k':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000530 len--;
531 scale = 1024;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000532 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000533
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000534 case 'M':
535 case 'm':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000536 len--;
537 scale = 1024 * 1024;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000538 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000539
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000540 default:
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000541 scale = 1;
542 }
543
544 size = ngx_atoi(value[1].data, len);
545 if (size == NGX_ERROR) {
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000546 return "invalid value";
Igor Sysoev960ffa42002-12-26 07:24:21 +0000547 }
Igor Sysoev88092572002-12-19 07:08:55 +0000548
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000549 size *= scale;
550
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000551 *(int *) (conf + cmd->offset) = size;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000552
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000553 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000554}
555
Igor Sysoev88092572002-12-19 07:08:55 +0000556
Igor Sysoev6253ca12003-05-27 12:18:54 +0000557char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000558{
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000559 int size, total, len, scale;
560 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000561 char last, *start;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000562 ngx_str_t *value;
563
Igor Sysoev1c13c662003-05-20 15:37:55 +0000564 if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) {
565 return "is duplicate";
566 }
567
Igor Sysoev960ffa42002-12-26 07:24:21 +0000568 value = (ngx_str_t *) cf->args->elts;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000569 start = value[1].data;
570 len = 0;
571 total = 0;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000572
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000573 for (i = 0; /* void */ ; i++) {
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000574
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000575 if (i < value[1].len) {
576 if (value[1].data[i] != ' ') {
577 len++;
578 continue;
579 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000580
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000581 if (value[1].data[i] == ' ' && len == 0) {
582 start = &value[1].data[i + 1];
583 continue;
584 }
585 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000586
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000587 if (len == 0) {
588 break;
589 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000590
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000591 last = value[1].data[i - 1];
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000592
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000593 switch (last) {
594 case 'm':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000595 len--;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000596 max = 35791;
597 scale = 1000 * 60;
598 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000599
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000600 case 'h':
601 len--;
602 max = 596;
603 scale = 1000 * 60 * 60;
604 break;
605
606 case 'd':
607 len--;
608 max = 24;
609 scale = 1000 * 60 * 60 * 24;
610 break;
611
612 case 's':
613 len--;
614 if (value[1].data[i - 2] == 'm') {
615 len--;
616 max = 2147483647;
617 scale = 1;
618 break;
619 }
620 /* fall thru */
621
622 default:
623 max = 2147483;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000624 scale = 1000;
625 }
626
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000627 size = ngx_atoi(start, len);
628 if (size < 0) {
629 return "invalid value";
630 }
631
632 if ((u_int) size > max) {
633 return "value must be less than 597 hours";
634 }
635
636 total += size * scale;
637
638 if (i >= value[1].len) {
639 break;
640 }
641
642 len = 0;
643 start = &value[1].data[i + 1];
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000644 }
645
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000646 *(int *) (conf + cmd->offset) = total;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000647
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000648 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000649}
Igor Sysoev6a644c62003-03-04 06:33:48 +0000650
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000651
Igor Sysoev6253ca12003-05-27 12:18:54 +0000652char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000653{
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000654 int size, total, len, scale;
655 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000656 char last, *start;
657 ngx_str_t *value;
658
Igor Sysoev1c13c662003-05-20 15:37:55 +0000659 if (*(int *) (conf + cmd->offset) != NGX_CONF_UNSET) {
660 return "is duplicate";
661 }
662
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000663 value = (ngx_str_t *) cf->args->elts;
664 start = value[1].data;
665 len = 0;
666 total = 0;
667
668 for (i = 0; /* void */ ; i++) {
669
670 if (i < value[1].len) {
671 if (value[1].data[i] != ' ') {
672 len++;
673 continue;
674 }
675
676 if (value[1].data[i] == ' ' && len == 0) {
677 start = &value[1].data[i + 1];
678 continue;
679 }
680 }
681
682 if (len == 0) {
683 break;
684 }
685
686 last = value[1].data[i - 1];
687
688 switch (last) {
689 case 'm':
690 len--;
691 max = 35791394;
692 scale = 60;
693 break;
694
695 case 'h':
696 len--;
697 max = 596523;
698 scale = 60 * 60;
699 break;
700
701 case 'd':
702 len--;
703 max = 24855;
704 scale = 60 * 60 * 24;
705 break;
706
707 case 'w':
708 len--;
709 max = 3550;
710 scale = 60 * 60 * 24 * 7;
711 break;
712
713 case 'M':
714 len--;
715 max = 828;
716 scale = 60 * 60 * 24 * 30;
717 break;
718
719 case 'y':
720 len--;
721 max = 68;
722 scale = 60 * 60 * 24 * 365;
723 break;
724
725 case 's':
726 len--;
727 /* fall thru */
728
729 default:
730 max = 2147483647;
731 scale = 1;
732 }
733
734 size = ngx_atoi(start, len);
735 if (size < 0) {
736 return "invalid value";
737 }
738
739 if ((u_int) size > max) {
740 return "value must be less than 68 years";
741 }
742
743 total += size * scale;
744
745 if (i >= value[1].len) {
746 break;
747 }
748
749 len = 0;
750 start = &value[1].data[i + 1];
751 }
752
753 *(int *) (conf + cmd->offset) = total;
754
755 return NGX_CONF_OK;
756}
757
758
Igor Sysoev6253ca12003-05-27 12:18:54 +0000759char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000760{
761 return "unsupported on this platform";
762}