blob: 5e1f1739a1505222c4d2cb932281acf1a5e829a7 [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 Sysoeva6717c42002-12-23 06:29:22 +000030 fd = ngx_open_file(filename->data, NGX_FILE_RDONLY);
Igor Sysoev88092572002-12-19 07:08:55 +000031 if (fd == NGX_INVALID_FILE) {
32 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +000033 "ngx_conf_file: "
34 ngx_open_file_n " %s failed", filename->data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000035 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +000036 }
37
Igor Sysoeva6717c42002-12-23 06:29:22 +000038 prev = cf->conf_file;
39 ngx_test_null(cf->conf_file,
40 ngx_palloc(cf->pool, sizeof(ngx_conf_file_t)),
Igor Sysoev4e9393a2003-01-09 05:36:00 +000041 NGX_CONF_ERROR);
Igor Sysoev88092572002-12-19 07:08:55 +000042
Igor Sysoeva6717c42002-12-23 06:29:22 +000043 if (ngx_stat_fd(fd, &cf->conf_file->file.info) == -1) {
44 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
45 "ngx_conf_file: "
46 ngx_stat_fd_n " %s failed", filename->data);
47 }
48
49 ngx_test_null(cf->conf_file->hunk,
50 ngx_create_temp_hunk(cf->pool, 1024, 0, 0),
Igor Sysoev4e9393a2003-01-09 05:36:00 +000051 NGX_CONF_ERROR);
Igor Sysoeva6717c42002-12-23 06:29:22 +000052
53 cf->conf_file->file.fd = fd;
54 cf->conf_file->file.name.len = filename->len;
55 cf->conf_file->file.name.data = filename->data;
56 cf->conf_file->file.log = cf->log;;
57 cf->conf_file->line = 1;
Igor Sysoev88092572002-12-19 07:08:55 +000058 }
59
60 for ( ;; ) {
61 rc = ngx_conf_read_token(cf);
62
Igor Sysoev960ffa42002-12-26 07:24:21 +000063 /* NGX_OK, NGX_ERROR, NGX_CONF_FILE_DONE, NGX_CONF_BLOCK_DONE */
Igor Sysoev88092572002-12-19 07:08:55 +000064
Igor Sysoev73009772003-02-06 17:21:13 +000065#if 0
Igor Sysoev4e9393a2003-01-09 05:36:00 +000066ngx_log_debug(cf->log, "token %d" _ rc);
Igor Sysoev73009772003-02-06 17:21:13 +000067#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +000068
69 if (rc == NGX_ERROR) {
70 return NGX_CONF_ERROR;
71 }
72
73 if (rc != NGX_OK) {
74 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +000075 }
76
Igor Sysoev88092572002-12-19 07:08:55 +000077 if (cf->handler) {
78
Igor Sysoev79a80482003-05-14 17:13:13 +000079 rv = (*cf->handler)(cf, NULL, cf->handler_conf);
80 if (rv == NGX_CONF_OK) {
81 continue;
82
83 } else if (rv == NGX_CONF_ERROR) {
84 return NGX_CONF_ERROR;
85
86 } else {
87 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoev6ddfbf02003-05-15 15:42:53 +000088 "%s in %s:%d",
89 rv,
Igor Sysoev79a80482003-05-14 17:13:13 +000090 cf->conf_file->file.name.data,
91 cf->conf_file->line);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000092 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +000093 }
Igor Sysoev88092572002-12-19 07:08:55 +000094 }
95
Igor Sysoev207ed5a2002-12-26 16:26:23 +000096 name = (ngx_str_t *) cf->args->elts;
Igor Sysoev4e9393a2003-01-09 05:36:00 +000097 found = 0;
Igor Sysoev207ed5a2002-12-26 16:26:23 +000098
Igor Sysoev4e9393a2003-01-09 05:36:00 +000099 for (i = 0; !found && ngx_modules[i]; i++) {
Igor Sysoevb2620632003-01-10 06:09:20 +0000100 if (ngx_modules[i]->type != NGX_CONF_MODULE_TYPE
Igor Sysoev79a80482003-05-14 17:13:13 +0000101 && ngx_modules[i]->type != cf->module_type)
Igor Sysoevc1817842002-12-27 16:22:50 +0000102 {
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000103 continue;
104 }
105
106 cmd = ngx_modules[i]->commands;
107 if (cmd == NULL) {
108 continue;
109 }
110
111 while (cmd->name.len) {
112 if (name->len == cmd->name.len
113 && ngx_strcmp(name->data, cmd->name.data) == 0)
114 {
Igor Sysoevc1817842002-12-27 16:22:50 +0000115
Igor Sysoev73009772003-02-06 17:21:13 +0000116#if 0
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000117ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data);
Igor Sysoev73009772003-02-06 17:21:13 +0000118#endif
Igor Sysoevc1817842002-12-27 16:22:50 +0000119
Igor Sysoev79a80482003-05-14 17:13:13 +0000120 if ((cmd->type & cf->cmd_type) == 0) {
121 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
122 "directive \"%s\" in %s:%d "
123 "is not allowed here",
124 name->data,
125 cf->conf_file->file.name.data,
126 cf->conf_file->line);
127 return NGX_CONF_ERROR;
128 }
129
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000130 if (!(cmd->type & NGX_CONF_ANY)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000131 && ((cmd->type & NGX_CONF_FLAG && cf->args->nelts != 2)
132 || (!(cmd->type & NGX_CONF_FLAG)
133 && !(cmd->type
134 & argument_number[cf->args->nelts - 1])
135 )
136 )
137 )
Igor Sysoeve79c6ac2003-01-10 17:45:47 +0000138 {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000139 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
140 "invalid number arguments in "
141 "directive \"%s\" in %s:%d",
142 name->data,
143 cf->conf_file->file.name.data,
144 cf->conf_file->line);
145 return NGX_CONF_ERROR;
146 }
147
148 conf = NULL;
149 if (cf->ctx) {
150 pconf = *(void **) ((char *) cf->ctx + cmd->conf);
151
152 if (pconf) {
Igor Sysoeve2a31542003-04-08 15:40:10 +0000153 conf = pconf[*(int *)(ngx_modules[i]->ctx)];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000154 }
155 }
156
157 rv = cmd->set(cf, cmd, conf);
158
Igor Sysoev73009772003-02-06 17:21:13 +0000159#if 0
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000160ngx_log_debug(cf->log, "rv: %d" _ rv);
Igor Sysoev73009772003-02-06 17:21:13 +0000161#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000162
163 if (rv == NGX_CONF_OK) {
164 found = 1;
165 break;
166
167 } else if (rv == NGX_CONF_ERROR) {
168 return NGX_CONF_ERROR;
169
170 } else {
171 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
Igor Sysoev6a644c62003-03-04 06:33:48 +0000172 "%s %s in %s:%d",
173 name->data, rv,
174 cf->conf_file->file.name.data,
175 cf->conf_file->line);
176
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000177 return NGX_CONF_ERROR;
178 }
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000179 }
180
181 cmd++;
182 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000183 }
Igor Sysoev960ffa42002-12-26 07:24:21 +0000184
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000185 if (!found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000186 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
187 "unknown directive \"%s\" in %s:%d",
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000188 name->data,
189 cf->conf_file->file.name.data,
190 cf->conf_file->line);
191
192 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000193 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000194 }
Igor Sysoev88092572002-12-19 07:08:55 +0000195
196 if (filename) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000197 cf->conf_file = prev;
Igor Sysoev88092572002-12-19 07:08:55 +0000198
199 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
200 ngx_log_error(NGX_LOG_ERR, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +0000201 ngx_close_file_n " %s failed",
202 cf->conf_file->file.name.data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000203 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000204 }
205 }
206
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000207 return NGX_CONF_OK;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000208}
Igor Sysoev88092572002-12-19 07:08:55 +0000209
Igor Sysoev88092572002-12-19 07:08:55 +0000210
Igor Sysoev960ffa42002-12-26 07:24:21 +0000211static int ngx_conf_read_token(ngx_conf_t *cf)
Igor Sysoev88092572002-12-19 07:08:55 +0000212{
213 char *start, ch, *src, *dst;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000214 int len;
215 int found, need_space, last_space, sharp_comment;
216 int quoted, s_quoted, d_quoted;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000217 ssize_t n;
218 ngx_str_t *word;
Igor Sysoev88092572002-12-19 07:08:55 +0000219 ngx_hunk_t *h;
220
Igor Sysoeva6717c42002-12-23 06:29:22 +0000221 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000222 need_space = 0;
223 last_space = 1;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000224 sharp_comment = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000225 quoted = s_quoted = d_quoted = 0;
226
227 cf->args->nelts = 0;
228 h = cf->conf_file->hunk;
Igor Sysoevb7387572003-03-11 20:38:13 +0000229 start = h->pos;
Igor Sysoev88092572002-12-19 07:08:55 +0000230
Igor Sysoev73009772003-02-06 17:21:13 +0000231#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000232ngx_log_debug(cf->log, "TOKEN START");
Igor Sysoev73009772003-02-06 17:21:13 +0000233#endif
Igor Sysoeva6717c42002-12-23 06:29:22 +0000234
Igor Sysoev295bb632002-12-23 18:22:18 +0000235 for ( ;; ) {
Igor Sysoev88092572002-12-19 07:08:55 +0000236
Igor Sysoevb7387572003-03-11 20:38:13 +0000237 if (h->pos >= h->last) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000238 if (cf->conf_file->file.offset
239 >= ngx_file_size(cf->conf_file->file.info)) {
Igor Sysoev960ffa42002-12-26 07:24:21 +0000240 return NGX_CONF_FILE_DONE;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000241 }
242
Igor Sysoevb7387572003-03-11 20:38:13 +0000243 if (h->pos - start) {
244 ngx_memcpy(h->start, start, h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000245 }
246
Igor Sysoeva6717c42002-12-23 06:29:22 +0000247 n = ngx_read_file(&cf->conf_file->file,
Igor Sysoevb7387572003-03-11 20:38:13 +0000248 h->start + (h->pos - start),
249 h->end - (h->start + (h->pos - start)),
Igor Sysoev88092572002-12-19 07:08:55 +0000250 cf->conf_file->file.offset);
251
252 if (n == NGX_ERROR) {
253 return NGX_ERROR;
254 }
255
Igor Sysoevb7387572003-03-11 20:38:13 +0000256 h->pos = h->start + (h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000257 start = h->start;
Igor Sysoevb7387572003-03-11 20:38:13 +0000258 h->last = h->pos + n;
Igor Sysoev88092572002-12-19 07:08:55 +0000259 }
260
Igor Sysoevb7387572003-03-11 20:38:13 +0000261 ch = *h->pos++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000262
Igor Sysoev295bb632002-12-23 18:22:18 +0000263#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000264ngx_log_debug(cf->log, "%d:%d:%d:%d:%d '%c'" _
265 last_space _ need_space _
266 quoted _ s_quoted _ d_quoted _ ch);
Igor Sysoev295bb632002-12-23 18:22:18 +0000267#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000268
269 if (ch == LF) {
270 cf->conf_file->line++;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000271
272 if (sharp_comment) {
273 sharp_comment = 0;
274 }
275 }
276
277 if (sharp_comment) {
278 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000279 }
280
Igor Sysoev295bb632002-12-23 18:22:18 +0000281 if (quoted) {
282 quoted = 0;
283 continue;
284 }
285
Igor Sysoeva6717c42002-12-23 06:29:22 +0000286 if (need_space) {
287 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
288 last_space = 1;
289 need_space = 0;
290 continue;
291 }
292
293 if (ch == ';' || ch == '{') {
294 return NGX_OK;
295 }
296
297 return NGX_ERROR;
298 }
299
Igor Sysoev88092572002-12-19 07:08:55 +0000300 if (last_space) {
Igor Sysoev88092572002-12-19 07:08:55 +0000301 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000302 continue;
303 }
304
Igor Sysoevb7387572003-03-11 20:38:13 +0000305 start = h->pos - 1;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000306
307 switch (ch) {
308
Igor Sysoev295bb632002-12-23 18:22:18 +0000309 case ';':
310 case '{':
Igor Sysoev960ffa42002-12-26 07:24:21 +0000311 if (cf->args->nelts == 0) {
312 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
313 "unexpected '%c' in %s:%d",
314 ch, cf->conf_file->file.name.data,
315 cf->conf_file->line);
316 return NGX_ERROR;
317 }
318
Igor Sysoev295bb632002-12-23 18:22:18 +0000319 return NGX_OK;
320
Igor Sysoev960ffa42002-12-26 07:24:21 +0000321 case '}':
322 if (cf->args->nelts > 0) {
323 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
324 "unexpected '}' in %s:%d",
325 cf->conf_file->file.name.data,
326 cf->conf_file->line);
327 return NGX_ERROR;
328 }
329
330 return NGX_CONF_BLOCK_DONE;
331
332 case '#':
333 sharp_comment = 1;
334 continue;
335
Igor Sysoeva6717c42002-12-23 06:29:22 +0000336 case '\\':
337 quoted = 1;
338 last_space = 0;
339 continue;
340
341 case '"':
Igor Sysoev88092572002-12-19 07:08:55 +0000342 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000343 d_quoted = 1;
344 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000345 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000346
Igor Sysoeva6717c42002-12-23 06:29:22 +0000347 case '\'':
348 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000349 s_quoted = 1;
350 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000351 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000352
Igor Sysoeva6717c42002-12-23 06:29:22 +0000353 default:
354 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000355 }
356
357 } else {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000358 if (ch == '\\') {
359 quoted = 1;
360 continue;
361 }
Igor Sysoev88092572002-12-19 07:08:55 +0000362
Igor Sysoeva6717c42002-12-23 06:29:22 +0000363 if (d_quoted) {
364 if (ch == '"') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000365 d_quoted = 0;
366 need_space = 1;
367 found = 1;
368 }
369
370 } else if (s_quoted) {
371 if (ch == '\'') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000372 s_quoted = 0;
373 need_space = 1;
374 found = 1;
375 }
376
377 } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
378 || ch == ';' || ch == '{') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000379 last_space = 1;
380 found = 1;
381 }
382
383 if (found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000384 ngx_test_null(word, ngx_push_array(cf->args), NGX_ERROR);
Igor Sysoev295bb632002-12-23 18:22:18 +0000385 ngx_test_null(word->data,
Igor Sysoevb7387572003-03-11 20:38:13 +0000386 ngx_palloc(cf->pool, h->pos - start + 1),
Igor Sysoev88092572002-12-19 07:08:55 +0000387 NGX_ERROR);
Igor Sysoev88092572002-12-19 07:08:55 +0000388
Igor Sysoev295bb632002-12-23 18:22:18 +0000389 for (dst = word->data, src = start, len = 0;
Igor Sysoevb7387572003-03-11 20:38:13 +0000390 src < h->pos - 1;
Igor Sysoev295bb632002-12-23 18:22:18 +0000391 len++)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000392 {
393 if (*src == '\\') {
Igor Sysoev88092572002-12-19 07:08:55 +0000394 src++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000395 }
Igor Sysoev88092572002-12-19 07:08:55 +0000396 *dst++ = *src++;
397 }
398 *dst = '\0';
Igor Sysoev295bb632002-12-23 18:22:18 +0000399 word->len = len;
Igor Sysoev88092572002-12-19 07:08:55 +0000400
Igor Sysoev73009772003-02-06 17:21:13 +0000401#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000402ngx_log_debug(cf->log, "FOUND %d:'%s'" _ word->len _ word->data);
Igor Sysoev73009772003-02-06 17:21:13 +0000403#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000404
Igor Sysoeva6717c42002-12-23 06:29:22 +0000405 if (ch == ';' || ch == '{') {
406 return NGX_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000407 }
408
Igor Sysoeva6717c42002-12-23 06:29:22 +0000409 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000410 }
Igor Sysoev88092572002-12-19 07:08:55 +0000411 }
412 }
413}
414
Igor Sysoev88092572002-12-19 07:08:55 +0000415
Igor Sysoev6a644c62003-03-04 06:33:48 +0000416char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
417{
418 int flag;
419 ngx_str_t *value;
420
421 value = (ngx_str_t *) cf->args->elts;
422
423 if (ngx_strcasecmp(value[1].data, "on") == 0) {
424 flag = 1;
425
426 } else if (ngx_strcasecmp(value[1].data, "off") == 0) {
427 flag = 0;
428
429 } else {
430 return "must be \"on\" or \"off\"";
431 }
432
433 *(int *) (conf + cmd->offset) = flag;
434
435 return NGX_CONF_OK;
436}
437
438
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000439char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
440{
441 ngx_str_t *field, *value;
442
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000443 field = (ngx_str_t *) (conf + cmd->offset);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000444 value = (ngx_str_t *) cf->args->elts;
445
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000446 field->len = value[1].len;
447 field->data = value[1].data;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000448
449 return NGX_CONF_OK;
450}
451
452
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000453char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000454{
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000455 int size, len, scale;
456 char last;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000457 ngx_str_t *value;
458
459 value = (ngx_str_t *) cf->args->elts;
460
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000461 len = value[1].len;
462 last = value[1].data[len - 1];
463
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000464 switch (last) {
465 case 'K':
466 case 'k':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000467 len--;
468 scale = 1024;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000469 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000470
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000471 case 'M':
472 case 'm':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000473 len--;
474 scale = 1024 * 1024;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000475 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000476
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000477 default:
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000478 scale = 1;
479 }
480
481 size = ngx_atoi(value[1].data, len);
482 if (size == NGX_ERROR) {
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000483 return "invalid value";
Igor Sysoev960ffa42002-12-26 07:24:21 +0000484 }
Igor Sysoev88092572002-12-19 07:08:55 +0000485
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000486 size *= scale;
487
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000488 *(int *) (conf + cmd->offset) = size;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000489
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000490 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000491}
492
Igor Sysoev88092572002-12-19 07:08:55 +0000493
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000494char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000495{
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000496 int size, total, len, scale;
497 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000498 char last, *start;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000499 ngx_str_t *value;
500
501 value = (ngx_str_t *) cf->args->elts;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000502 start = value[1].data;
503 len = 0;
504 total = 0;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000505
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000506 for (i = 0; /* void */ ; i++) {
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000507
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000508 if (i < value[1].len) {
509 if (value[1].data[i] != ' ') {
510 len++;
511 continue;
512 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000513
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000514 if (value[1].data[i] == ' ' && len == 0) {
515 start = &value[1].data[i + 1];
516 continue;
517 }
518 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000519
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000520 if (len == 0) {
521 break;
522 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000523
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000524 last = value[1].data[i - 1];
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000525
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000526 switch (last) {
527 case 'm':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000528 len--;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000529 max = 35791;
530 scale = 1000 * 60;
531 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000532
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000533 case 'h':
534 len--;
535 max = 596;
536 scale = 1000 * 60 * 60;
537 break;
538
539 case 'd':
540 len--;
541 max = 24;
542 scale = 1000 * 60 * 60 * 24;
543 break;
544
545 case 's':
546 len--;
547 if (value[1].data[i - 2] == 'm') {
548 len--;
549 max = 2147483647;
550 scale = 1;
551 break;
552 }
553 /* fall thru */
554
555 default:
556 max = 2147483;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000557 scale = 1000;
558 }
559
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000560 size = ngx_atoi(start, len);
561 if (size < 0) {
562 return "invalid value";
563 }
564
565 if ((u_int) size > max) {
566 return "value must be less than 597 hours";
567 }
568
569 total += size * scale;
570
571 if (i >= value[1].len) {
572 break;
573 }
574
575 len = 0;
576 start = &value[1].data[i + 1];
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000577 }
578
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000579 *(int *) (conf + cmd->offset) = total;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000580
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000581 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000582}
Igor Sysoev6a644c62003-03-04 06:33:48 +0000583
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000584
585char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
586{
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000587 int size, total, len, scale;
588 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000589 char last, *start;
590 ngx_str_t *value;
591
592 value = (ngx_str_t *) cf->args->elts;
593 start = value[1].data;
594 len = 0;
595 total = 0;
596
597 for (i = 0; /* void */ ; i++) {
598
599 if (i < value[1].len) {
600 if (value[1].data[i] != ' ') {
601 len++;
602 continue;
603 }
604
605 if (value[1].data[i] == ' ' && len == 0) {
606 start = &value[1].data[i + 1];
607 continue;
608 }
609 }
610
611 if (len == 0) {
612 break;
613 }
614
615 last = value[1].data[i - 1];
616
617 switch (last) {
618 case 'm':
619 len--;
620 max = 35791394;
621 scale = 60;
622 break;
623
624 case 'h':
625 len--;
626 max = 596523;
627 scale = 60 * 60;
628 break;
629
630 case 'd':
631 len--;
632 max = 24855;
633 scale = 60 * 60 * 24;
634 break;
635
636 case 'w':
637 len--;
638 max = 3550;
639 scale = 60 * 60 * 24 * 7;
640 break;
641
642 case 'M':
643 len--;
644 max = 828;
645 scale = 60 * 60 * 24 * 30;
646 break;
647
648 case 'y':
649 len--;
650 max = 68;
651 scale = 60 * 60 * 24 * 365;
652 break;
653
654 case 's':
655 len--;
656 /* fall thru */
657
658 default:
659 max = 2147483647;
660 scale = 1;
661 }
662
663 size = ngx_atoi(start, len);
664 if (size < 0) {
665 return "invalid value";
666 }
667
668 if ((u_int) size > max) {
669 return "value must be less than 68 years";
670 }
671
672 total += size * scale;
673
674 if (i >= value[1].len) {
675 break;
676 }
677
678 len = 0;
679 start = &value[1].data[i + 1];
680 }
681
682 *(int *) (conf + cmd->offset) = total;
683
684 return NGX_CONF_OK;
685}
686
687
Igor Sysoev6a644c62003-03-04 06:33:48 +0000688char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
689{
690 return "unsupported on this platform";
691}