blob: 3d93f02e053aba243cba353c8051790a8d5c286c [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
9static int argument_number[] = {
10 NGX_CONF_NOARGS,
11 NGX_CONF_TAKE1,
12 NGX_CONF_TAKE2
13};
14
Igor Sysoev960ffa42002-12-26 07:24:21 +000015static int ngx_conf_read_token(ngx_conf_t *cf);
Igor Sysoev960ffa42002-12-26 07:24:21 +000016
Igor Sysoev88092572002-12-19 07:08:55 +000017
Igor Sysoev4e9393a2003-01-09 05:36:00 +000018char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
Igor Sysoev88092572002-12-19 07:08:55 +000019{
Igor Sysoev4e9393a2003-01-09 05:36:00 +000020 int i, rc, found;
21 char *rv;
22 void *conf, **pconf;
Igor Sysoev207ed5a2002-12-26 16:26:23 +000023 ngx_str_t *name;
Igor Sysoev960ffa42002-12-26 07:24:21 +000024 ngx_fd_t fd;
Igor Sysoev88092572002-12-19 07:08:55 +000025 ngx_conf_file_t *prev;
Igor Sysoev960ffa42002-12-26 07:24:21 +000026 ngx_command_t *cmd;
Igor Sysoev88092572002-12-19 07:08:55 +000027
28 if (filename) {
29
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000030 /* open configuration file */
31
Igor Sysoeva6717c42002-12-23 06:29:22 +000032 fd = ngx_open_file(filename->data, NGX_FILE_RDONLY);
Igor Sysoev88092572002-12-19 07:08:55 +000033 if (fd == NGX_INVALID_FILE) {
34 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +000035 "ngx_conf_file: "
36 ngx_open_file_n " %s failed", filename->data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000037 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +000038 }
39
Igor Sysoeva6717c42002-12-23 06:29:22 +000040 prev = cf->conf_file;
41 ngx_test_null(cf->conf_file,
42 ngx_palloc(cf->pool, sizeof(ngx_conf_file_t)),
Igor Sysoev4e9393a2003-01-09 05:36:00 +000043 NGX_CONF_ERROR);
Igor Sysoev88092572002-12-19 07:08:55 +000044
Igor Sysoeva6717c42002-12-23 06:29:22 +000045 if (ngx_stat_fd(fd, &cf->conf_file->file.info) == -1) {
46 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
47 "ngx_conf_file: "
48 ngx_stat_fd_n " %s failed", filename->data);
49 }
50
51 ngx_test_null(cf->conf_file->hunk,
52 ngx_create_temp_hunk(cf->pool, 1024, 0, 0),
Igor Sysoev4e9393a2003-01-09 05:36:00 +000053 NGX_CONF_ERROR);
Igor Sysoeva6717c42002-12-23 06:29:22 +000054
55 cf->conf_file->file.fd = fd;
56 cf->conf_file->file.name.len = filename->len;
57 cf->conf_file->file.name.data = filename->data;
58 cf->conf_file->file.log = cf->log;;
59 cf->conf_file->line = 1;
Igor Sysoev88092572002-12-19 07:08:55 +000060 }
61
62 for ( ;; ) {
63 rc = ngx_conf_read_token(cf);
64
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000065 /* ngx_conf_read_token() returns NGX_OK, NGX_ERROR,
66 NGX_CONF_FILE_DONE or NGX_CONF_BLOCK_DONE */
Igor Sysoev88092572002-12-19 07:08:55 +000067
Igor Sysoev73009772003-02-06 17:21:13 +000068#if 0
Igor Sysoev4e9393a2003-01-09 05:36:00 +000069ngx_log_debug(cf->log, "token %d" _ rc);
Igor Sysoev73009772003-02-06 17:21:13 +000070#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +000071
72 if (rc == NGX_ERROR) {
73 return NGX_CONF_ERROR;
74 }
75
76 if (rc != NGX_OK) {
77 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +000078 }
79
Igor Sysoev88092572002-12-19 07:08:55 +000080 if (cf->handler) {
81
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000082 /* custom handler, i.e. used in http "types { ... }" directive */
83
Igor Sysoev79a80482003-05-14 17:13:13 +000084 rv = (*cf->handler)(cf, NULL, cf->handler_conf);
85 if (rv == NGX_CONF_OK) {
86 continue;
87
88 } else if (rv == NGX_CONF_ERROR) {
89 return NGX_CONF_ERROR;
90
91 } else {
92 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoev6ddfbf02003-05-15 15:42:53 +000093 "%s in %s:%d",
94 rv,
Igor Sysoev79a80482003-05-14 17:13:13 +000095 cf->conf_file->file.name.data,
96 cf->conf_file->line);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000097 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +000098 }
Igor Sysoev88092572002-12-19 07:08:55 +000099 }
100
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000101 name = (ngx_str_t *) cf->args->elts;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000102 found = 0;
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000103
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000104 for (i = 0; !found && ngx_modules[i]; i++) {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000105
106 /* look up the directive in the appropriate modules */
107
Igor Sysoevb2620632003-01-10 06:09:20 +0000108 if (ngx_modules[i]->type != NGX_CONF_MODULE_TYPE
Igor Sysoev79a80482003-05-14 17:13:13 +0000109 && ngx_modules[i]->type != cf->module_type)
Igor Sysoevc1817842002-12-27 16:22:50 +0000110 {
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000111 continue;
112 }
113
114 cmd = ngx_modules[i]->commands;
115 if (cmd == NULL) {
116 continue;
117 }
118
119 while (cmd->name.len) {
120 if (name->len == cmd->name.len
121 && ngx_strcmp(name->data, cmd->name.data) == 0)
122 {
Igor Sysoevc1817842002-12-27 16:22:50 +0000123
Igor Sysoev73009772003-02-06 17:21:13 +0000124#if 0
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000125ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data);
Igor Sysoev73009772003-02-06 17:21:13 +0000126#endif
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000127 /* is the directive's location right ? */
Igor Sysoevc1817842002-12-27 16:22:50 +0000128
Igor Sysoev79a80482003-05-14 17:13:13 +0000129 if ((cmd->type & cf->cmd_type) == 0) {
130 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
131 "directive \"%s\" in %s:%d "
132 "is not allowed here",
133 name->data,
134 cf->conf_file->file.name.data,
135 cf->conf_file->line);
136 return NGX_CONF_ERROR;
137 }
138
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000139 /* is the directive's argument count right ? */
140
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000141 if (!(cmd->type & NGX_CONF_ANY)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000142 && ((cmd->type & NGX_CONF_FLAG && cf->args->nelts != 2)
143 || (!(cmd->type & NGX_CONF_FLAG)
144 && !(cmd->type
145 & argument_number[cf->args->nelts - 1])
146 )
147 )
148 )
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000149 {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000150 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
151 "invalid number arguments in "
152 "directive \"%s\" in %s:%d",
153 name->data,
154 cf->conf_file->file.name.data,
155 cf->conf_file->line);
156 return NGX_CONF_ERROR;
157 }
158
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000159 /* set up the directive's configuration context */
160
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000161 conf = NULL;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000162
163 if (cf->module_type == NGX_CORE_MODULE_TYPE) {
164 conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
165
166 } else if (cf->ctx) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000167 pconf = *(void **) ((char *) cf->ctx + cmd->conf);
168
169 if (pconf) {
Igor Sysoeve2a31542003-04-08 15:40:10 +0000170 conf = pconf[*(int *)(ngx_modules[i]->ctx)];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000171 }
172 }
173
174 rv = cmd->set(cf, cmd, conf);
175
Igor Sysoev73009772003-02-06 17:21:13 +0000176#if 0
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000177ngx_log_debug(cf->log, "rv: %d" _ rv);
Igor Sysoev73009772003-02-06 17:21:13 +0000178#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000179
180 if (rv == NGX_CONF_OK) {
181 found = 1;
182 break;
183
184 } else if (rv == NGX_CONF_ERROR) {
185 return NGX_CONF_ERROR;
186
187 } else {
188 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoev6a644c62003-03-04 06:33:48 +0000189 "%s %s in %s:%d",
190 name->data, rv,
191 cf->conf_file->file.name.data,
192 cf->conf_file->line);
193
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000194 return NGX_CONF_ERROR;
195 }
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000196 }
197
198 cmd++;
199 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000200 }
Igor Sysoev960ffa42002-12-26 07:24:21 +0000201
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000202 if (!found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000203 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
204 "unknown directive \"%s\" in %s:%d",
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000205 name->data,
206 cf->conf_file->file.name.data,
207 cf->conf_file->line);
208
209 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000210 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000211 }
Igor Sysoev88092572002-12-19 07:08:55 +0000212
213 if (filename) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000214 cf->conf_file = prev;
Igor Sysoev88092572002-12-19 07:08:55 +0000215
216 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000217 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +0000218 ngx_close_file_n " %s failed",
219 cf->conf_file->file.name.data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000220 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000221 }
222 }
223
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000224 return NGX_CONF_OK;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000225}
Igor Sysoev88092572002-12-19 07:08:55 +0000226
Igor Sysoev88092572002-12-19 07:08:55 +0000227
Igor Sysoev960ffa42002-12-26 07:24:21 +0000228static int ngx_conf_read_token(ngx_conf_t *cf)
Igor Sysoev88092572002-12-19 07:08:55 +0000229{
230 char *start, ch, *src, *dst;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000231 int len;
232 int found, need_space, last_space, sharp_comment;
233 int quoted, s_quoted, d_quoted;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000234 ssize_t n;
235 ngx_str_t *word;
Igor Sysoev88092572002-12-19 07:08:55 +0000236 ngx_hunk_t *h;
237
Igor Sysoeva6717c42002-12-23 06:29:22 +0000238 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000239 need_space = 0;
240 last_space = 1;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000241 sharp_comment = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000242 quoted = s_quoted = d_quoted = 0;
243
244 cf->args->nelts = 0;
245 h = cf->conf_file->hunk;
Igor Sysoevb7387572003-03-11 20:38:13 +0000246 start = h->pos;
Igor Sysoev88092572002-12-19 07:08:55 +0000247
Igor Sysoev73009772003-02-06 17:21:13 +0000248#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000249ngx_log_debug(cf->log, "TOKEN START");
Igor Sysoev73009772003-02-06 17:21:13 +0000250#endif
Igor Sysoeva6717c42002-12-23 06:29:22 +0000251
Igor Sysoev295bb632002-12-23 18:22:18 +0000252 for ( ;; ) {
Igor Sysoev88092572002-12-19 07:08:55 +0000253
Igor Sysoevb7387572003-03-11 20:38:13 +0000254 if (h->pos >= h->last) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000255 if (cf->conf_file->file.offset
256 >= ngx_file_size(cf->conf_file->file.info)) {
Igor Sysoev960ffa42002-12-26 07:24:21 +0000257 return NGX_CONF_FILE_DONE;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000258 }
259
Igor Sysoevb7387572003-03-11 20:38:13 +0000260 if (h->pos - start) {
261 ngx_memcpy(h->start, start, h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000262 }
263
Igor Sysoeva6717c42002-12-23 06:29:22 +0000264 n = ngx_read_file(&cf->conf_file->file,
Igor Sysoevb7387572003-03-11 20:38:13 +0000265 h->start + (h->pos - start),
266 h->end - (h->start + (h->pos - start)),
Igor Sysoev88092572002-12-19 07:08:55 +0000267 cf->conf_file->file.offset);
268
269 if (n == NGX_ERROR) {
270 return NGX_ERROR;
271 }
272
Igor Sysoevb7387572003-03-11 20:38:13 +0000273 h->pos = h->start + (h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000274 start = h->start;
Igor Sysoevb7387572003-03-11 20:38:13 +0000275 h->last = h->pos + n;
Igor Sysoev88092572002-12-19 07:08:55 +0000276 }
277
Igor Sysoevb7387572003-03-11 20:38:13 +0000278 ch = *h->pos++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000279
Igor Sysoev295bb632002-12-23 18:22:18 +0000280#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000281ngx_log_debug(cf->log, "%d:%d:%d:%d:%d '%c'" _
282 last_space _ need_space _
283 quoted _ s_quoted _ d_quoted _ ch);
Igor Sysoev295bb632002-12-23 18:22:18 +0000284#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000285
286 if (ch == LF) {
287 cf->conf_file->line++;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000288
289 if (sharp_comment) {
290 sharp_comment = 0;
291 }
292 }
293
294 if (sharp_comment) {
295 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000296 }
297
Igor Sysoev295bb632002-12-23 18:22:18 +0000298 if (quoted) {
299 quoted = 0;
300 continue;
301 }
302
Igor Sysoeva6717c42002-12-23 06:29:22 +0000303 if (need_space) {
304 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
305 last_space = 1;
306 need_space = 0;
307 continue;
308 }
309
310 if (ch == ';' || ch == '{') {
311 return NGX_OK;
312 }
313
314 return NGX_ERROR;
315 }
316
Igor Sysoev88092572002-12-19 07:08:55 +0000317 if (last_space) {
Igor Sysoev88092572002-12-19 07:08:55 +0000318 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000319 continue;
320 }
321
Igor Sysoevb7387572003-03-11 20:38:13 +0000322 start = h->pos - 1;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000323
324 switch (ch) {
325
Igor Sysoev295bb632002-12-23 18:22:18 +0000326 case ';':
327 case '{':
Igor Sysoev960ffa42002-12-26 07:24:21 +0000328 if (cf->args->nelts == 0) {
329 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
330 "unexpected '%c' in %s:%d",
331 ch, cf->conf_file->file.name.data,
332 cf->conf_file->line);
333 return NGX_ERROR;
334 }
335
Igor Sysoev295bb632002-12-23 18:22:18 +0000336 return NGX_OK;
337
Igor Sysoev960ffa42002-12-26 07:24:21 +0000338 case '}':
339 if (cf->args->nelts > 0) {
340 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
341 "unexpected '}' in %s:%d",
342 cf->conf_file->file.name.data,
343 cf->conf_file->line);
344 return NGX_ERROR;
345 }
346
347 return NGX_CONF_BLOCK_DONE;
348
349 case '#':
350 sharp_comment = 1;
351 continue;
352
Igor Sysoeva6717c42002-12-23 06:29:22 +0000353 case '\\':
354 quoted = 1;
355 last_space = 0;
356 continue;
357
358 case '"':
Igor Sysoev88092572002-12-19 07:08:55 +0000359 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000360 d_quoted = 1;
361 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000362 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000363
Igor Sysoeva6717c42002-12-23 06:29:22 +0000364 case '\'':
365 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000366 s_quoted = 1;
367 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000368 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000369
Igor Sysoeva6717c42002-12-23 06:29:22 +0000370 default:
371 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000372 }
373
374 } else {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000375 if (ch == '\\') {
376 quoted = 1;
377 continue;
378 }
Igor Sysoev88092572002-12-19 07:08:55 +0000379
Igor Sysoeva6717c42002-12-23 06:29:22 +0000380 if (d_quoted) {
381 if (ch == '"') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000382 d_quoted = 0;
383 need_space = 1;
384 found = 1;
385 }
386
387 } else if (s_quoted) {
388 if (ch == '\'') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000389 s_quoted = 0;
390 need_space = 1;
391 found = 1;
392 }
393
394 } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
395 || ch == ';' || ch == '{') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000396 last_space = 1;
397 found = 1;
398 }
399
400 if (found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000401 ngx_test_null(word, ngx_push_array(cf->args), NGX_ERROR);
Igor Sysoev295bb632002-12-23 18:22:18 +0000402 ngx_test_null(word->data,
Igor Sysoevb7387572003-03-11 20:38:13 +0000403 ngx_palloc(cf->pool, h->pos - start + 1),
Igor Sysoev88092572002-12-19 07:08:55 +0000404 NGX_ERROR);
Igor Sysoev88092572002-12-19 07:08:55 +0000405
Igor Sysoev295bb632002-12-23 18:22:18 +0000406 for (dst = word->data, src = start, len = 0;
Igor Sysoevb7387572003-03-11 20:38:13 +0000407 src < h->pos - 1;
Igor Sysoev295bb632002-12-23 18:22:18 +0000408 len++)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000409 {
410 if (*src == '\\') {
Igor Sysoev88092572002-12-19 07:08:55 +0000411 src++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000412 }
Igor Sysoev88092572002-12-19 07:08:55 +0000413 *dst++ = *src++;
414 }
415 *dst = '\0';
Igor Sysoev295bb632002-12-23 18:22:18 +0000416 word->len = len;
Igor Sysoev88092572002-12-19 07:08:55 +0000417
Igor Sysoev73009772003-02-06 17:21:13 +0000418#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000419ngx_log_debug(cf->log, "FOUND %d:'%s'" _ word->len _ word->data);
Igor Sysoev73009772003-02-06 17:21:13 +0000420#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000421
Igor Sysoeva6717c42002-12-23 06:29:22 +0000422 if (ch == ';' || ch == '{') {
423 return NGX_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000424 }
425
Igor Sysoeva6717c42002-12-23 06:29:22 +0000426 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000427 }
Igor Sysoev88092572002-12-19 07:08:55 +0000428 }
429 }
430}
431
Igor Sysoev88092572002-12-19 07:08:55 +0000432
Igor Sysoev6a644c62003-03-04 06:33:48 +0000433char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
434{
435 int flag;
436 ngx_str_t *value;
437
438 value = (ngx_str_t *) cf->args->elts;
439
440 if (ngx_strcasecmp(value[1].data, "on") == 0) {
441 flag = 1;
442
443 } else if (ngx_strcasecmp(value[1].data, "off") == 0) {
444 flag = 0;
445
446 } else {
447 return "must be \"on\" or \"off\"";
448 }
449
450 *(int *) (conf + cmd->offset) = flag;
451
452 return NGX_CONF_OK;
453}
454
455
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000456char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
457{
458 ngx_str_t *field, *value;
459
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000460 field = (ngx_str_t *) (conf + cmd->offset);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000461 value = (ngx_str_t *) cf->args->elts;
462
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000463 field->len = value[1].len;
464 field->data = value[1].data;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000465
466 return NGX_CONF_OK;
467}
468
469
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000470char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
471{
472 int num, len;
473 ngx_str_t *value;
474
475 value = (ngx_str_t *) cf->args->elts;
476
477 len = value[1].len;
478
479 num = ngx_atoi(value[1].data, len);
480 if (num == NGX_ERROR) {
481 return "invalid value";
482 }
483
484 *(int *) (conf + cmd->offset) = num;
485
486 return NGX_CONF_OK;
487}
488
489
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000490char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000491{
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000492 int size, len, scale;
493 char last;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000494 ngx_str_t *value;
495
496 value = (ngx_str_t *) cf->args->elts;
497
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000498 len = value[1].len;
499 last = value[1].data[len - 1];
500
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000501 switch (last) {
502 case 'K':
503 case 'k':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000504 len--;
505 scale = 1024;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000506 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000507
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000508 case 'M':
509 case 'm':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000510 len--;
511 scale = 1024 * 1024;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000512 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000513
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000514 default:
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000515 scale = 1;
516 }
517
518 size = ngx_atoi(value[1].data, len);
519 if (size == NGX_ERROR) {
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000520 return "invalid value";
Igor Sysoev960ffa42002-12-26 07:24:21 +0000521 }
Igor Sysoev88092572002-12-19 07:08:55 +0000522
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000523 size *= scale;
524
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000525 *(int *) (conf + cmd->offset) = size;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000526
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000527 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000528}
529
Igor Sysoev88092572002-12-19 07:08:55 +0000530
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000531char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000532{
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000533 int size, total, len, scale;
534 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000535 char last, *start;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000536 ngx_str_t *value;
537
538 value = (ngx_str_t *) cf->args->elts;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000539 start = value[1].data;
540 len = 0;
541 total = 0;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000542
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000543 for (i = 0; /* void */ ; i++) {
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000544
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000545 if (i < value[1].len) {
546 if (value[1].data[i] != ' ') {
547 len++;
548 continue;
549 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000550
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000551 if (value[1].data[i] == ' ' && len == 0) {
552 start = &value[1].data[i + 1];
553 continue;
554 }
555 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000556
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000557 if (len == 0) {
558 break;
559 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000560
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000561 last = value[1].data[i - 1];
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000562
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000563 switch (last) {
564 case 'm':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000565 len--;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000566 max = 35791;
567 scale = 1000 * 60;
568 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000569
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000570 case 'h':
571 len--;
572 max = 596;
573 scale = 1000 * 60 * 60;
574 break;
575
576 case 'd':
577 len--;
578 max = 24;
579 scale = 1000 * 60 * 60 * 24;
580 break;
581
582 case 's':
583 len--;
584 if (value[1].data[i - 2] == 'm') {
585 len--;
586 max = 2147483647;
587 scale = 1;
588 break;
589 }
590 /* fall thru */
591
592 default:
593 max = 2147483;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000594 scale = 1000;
595 }
596
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000597 size = ngx_atoi(start, len);
598 if (size < 0) {
599 return "invalid value";
600 }
601
602 if ((u_int) size > max) {
603 return "value must be less than 597 hours";
604 }
605
606 total += size * scale;
607
608 if (i >= value[1].len) {
609 break;
610 }
611
612 len = 0;
613 start = &value[1].data[i + 1];
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000614 }
615
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000616 *(int *) (conf + cmd->offset) = total;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000617
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000618 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000619}
Igor Sysoev6a644c62003-03-04 06:33:48 +0000620
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000621
622char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
623{
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000624 int size, total, len, scale;
625 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000626 char last, *start;
627 ngx_str_t *value;
628
629 value = (ngx_str_t *) cf->args->elts;
630 start = value[1].data;
631 len = 0;
632 total = 0;
633
634 for (i = 0; /* void */ ; i++) {
635
636 if (i < value[1].len) {
637 if (value[1].data[i] != ' ') {
638 len++;
639 continue;
640 }
641
642 if (value[1].data[i] == ' ' && len == 0) {
643 start = &value[1].data[i + 1];
644 continue;
645 }
646 }
647
648 if (len == 0) {
649 break;
650 }
651
652 last = value[1].data[i - 1];
653
654 switch (last) {
655 case 'm':
656 len--;
657 max = 35791394;
658 scale = 60;
659 break;
660
661 case 'h':
662 len--;
663 max = 596523;
664 scale = 60 * 60;
665 break;
666
667 case 'd':
668 len--;
669 max = 24855;
670 scale = 60 * 60 * 24;
671 break;
672
673 case 'w':
674 len--;
675 max = 3550;
676 scale = 60 * 60 * 24 * 7;
677 break;
678
679 case 'M':
680 len--;
681 max = 828;
682 scale = 60 * 60 * 24 * 30;
683 break;
684
685 case 'y':
686 len--;
687 max = 68;
688 scale = 60 * 60 * 24 * 365;
689 break;
690
691 case 's':
692 len--;
693 /* fall thru */
694
695 default:
696 max = 2147483647;
697 scale = 1;
698 }
699
700 size = ngx_atoi(start, len);
701 if (size < 0) {
702 return "invalid value";
703 }
704
705 if ((u_int) size > max) {
706 return "value must be less than 68 years";
707 }
708
709 total += size * scale;
710
711 if (i >= value[1].len) {
712 break;
713 }
714
715 len = 0;
716 start = &value[1].data[i + 1];
717 }
718
719 *(int *) (conf + cmd->offset) = total;
720
721 return NGX_CONF_OK;
722}
723
724
Igor Sysoev6a644c62003-03-04 06:33:48 +0000725char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
726{
727 return "unsupported on this platform";
728}