blob: 54d4f387b26cf45b7e16b95a8da1c94423f41794 [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 Sysoevaa3436c2003-05-30 14:27:59 +000023 int m, rc, found, valid;
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 Sysoevaa3436c2003-05-30 14:27:59 +0000142 if (cmd->type & argument_number[cf->args->nelts - 1]) {
143 valid = 1;
144
145 } else if (cmd->type & NGX_CONF_ANY1) {
146
147 if (cf->args->nelts != 1) {
148 valid = 1;
149 } else {
150 valid = 0;
151 }
152
153 } else if (cmd->type & NGX_CONF_FLAG) {
154
155 if (cf->args->nelts == 2) {
156 valid = 1;
157 } else {
158 valid = 0;
159 }
160
161 } else if (cmd->type & NGX_CONF_ANY) {
162 valid = 1;
163
164 } else {
165 valid = 0;
166 }
167
168 if (!valid) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000169 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
170 "invalid number arguments in "
171 "directive \"%s\" in %s:%d",
172 name->data,
173 cf->conf_file->file.name.data,
174 cf->conf_file->line);
175 return NGX_CONF_ERROR;
176 }
177
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000178 /* set up the directive's configuration context */
179
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000180 conf = NULL;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000181
Igor Sysoev6253ca12003-05-27 12:18:54 +0000182 if (cf->module_type == NGX_CORE_MODULE) {
183 conf = &(((void **) cf->ctx)[ngx_modules[m]->index]);
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000184
185 } else if (cf->ctx) {
Igor Sysoeva9830112003-05-19 16:39:14 +0000186 confp = *(void **) ((char *) cf->ctx + cmd->conf);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000187
Igor Sysoeva9830112003-05-19 16:39:14 +0000188 if (confp) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000189 conf = confp[ngx_modules[m]->ctx_index];
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000190 }
191 }
192
193 rv = cmd->set(cf, cmd, conf);
194
Igor Sysoev73009772003-02-06 17:21:13 +0000195#if 0
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000196ngx_log_debug(cf->log, "rv: %d" _ rv);
Igor Sysoev73009772003-02-06 17:21:13 +0000197#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000198
199 if (rv == NGX_CONF_OK) {
200 found = 1;
201 break;
202
203 } else if (rv == NGX_CONF_ERROR) {
204 return NGX_CONF_ERROR;
205
206 } else {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000207 if (rv == ngx_conf_errstr) {
208 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
209 "%s in %s:%d",
210 rv,
211 cf->conf_file->file.name.data,
212 cf->conf_file->line);
213 } else {
214 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
215 "%s %s in %s:%d",
216 name->data, rv,
217 cf->conf_file->file.name.data,
218 cf->conf_file->line);
219 }
Igor Sysoev6a644c62003-03-04 06:33:48 +0000220
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000221 return NGX_CONF_ERROR;
222 }
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000223 }
224
225 cmd++;
226 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000227 }
Igor Sysoev960ffa42002-12-26 07:24:21 +0000228
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000229 if (!found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000230 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
231 "unknown directive \"%s\" in %s:%d",
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000232 name->data,
233 cf->conf_file->file.name.data,
234 cf->conf_file->line);
235
236 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000237 }
Igor Sysoeva6717c42002-12-23 06:29:22 +0000238 }
Igor Sysoev88092572002-12-19 07:08:55 +0000239
240 if (filename) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000241 cf->conf_file = prev;
Igor Sysoev88092572002-12-19 07:08:55 +0000242
243 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000244 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
Igor Sysoeva6717c42002-12-23 06:29:22 +0000245 ngx_close_file_n " %s failed",
246 cf->conf_file->file.name.data);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000247 return NGX_CONF_ERROR;
Igor Sysoev88092572002-12-19 07:08:55 +0000248 }
249 }
250
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000251 return NGX_CONF_OK;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000252}
Igor Sysoev88092572002-12-19 07:08:55 +0000253
Igor Sysoev88092572002-12-19 07:08:55 +0000254
Igor Sysoev960ffa42002-12-26 07:24:21 +0000255static int ngx_conf_read_token(ngx_conf_t *cf)
Igor Sysoev88092572002-12-19 07:08:55 +0000256{
257 char *start, ch, *src, *dst;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000258 int len;
259 int found, need_space, last_space, sharp_comment;
260 int quoted, s_quoted, d_quoted;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000261 ssize_t n;
262 ngx_str_t *word;
Igor Sysoev88092572002-12-19 07:08:55 +0000263 ngx_hunk_t *h;
264
Igor Sysoeva6717c42002-12-23 06:29:22 +0000265 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000266 need_space = 0;
267 last_space = 1;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000268 sharp_comment = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000269 quoted = s_quoted = d_quoted = 0;
270
271 cf->args->nelts = 0;
272 h = cf->conf_file->hunk;
Igor Sysoevb7387572003-03-11 20:38:13 +0000273 start = h->pos;
Igor Sysoev88092572002-12-19 07:08:55 +0000274
Igor Sysoev73009772003-02-06 17:21:13 +0000275#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000276ngx_log_debug(cf->log, "TOKEN START");
Igor Sysoev73009772003-02-06 17:21:13 +0000277#endif
Igor Sysoeva6717c42002-12-23 06:29:22 +0000278
Igor Sysoev295bb632002-12-23 18:22:18 +0000279 for ( ;; ) {
Igor Sysoev88092572002-12-19 07:08:55 +0000280
Igor Sysoevb7387572003-03-11 20:38:13 +0000281 if (h->pos >= h->last) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000282 if (cf->conf_file->file.offset
283 >= ngx_file_size(cf->conf_file->file.info)) {
Igor Sysoev960ffa42002-12-26 07:24:21 +0000284 return NGX_CONF_FILE_DONE;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000285 }
286
Igor Sysoevb7387572003-03-11 20:38:13 +0000287 if (h->pos - start) {
288 ngx_memcpy(h->start, start, h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000289 }
290
Igor Sysoeva6717c42002-12-23 06:29:22 +0000291 n = ngx_read_file(&cf->conf_file->file,
Igor Sysoevb7387572003-03-11 20:38:13 +0000292 h->start + (h->pos - start),
293 h->end - (h->start + (h->pos - start)),
Igor Sysoev88092572002-12-19 07:08:55 +0000294 cf->conf_file->file.offset);
295
296 if (n == NGX_ERROR) {
297 return NGX_ERROR;
298 }
299
Igor Sysoevb7387572003-03-11 20:38:13 +0000300 h->pos = h->start + (h->pos - start);
Igor Sysoev88092572002-12-19 07:08:55 +0000301 start = h->start;
Igor Sysoevb7387572003-03-11 20:38:13 +0000302 h->last = h->pos + n;
Igor Sysoev88092572002-12-19 07:08:55 +0000303 }
304
Igor Sysoevb7387572003-03-11 20:38:13 +0000305 ch = *h->pos++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000306
Igor Sysoev295bb632002-12-23 18:22:18 +0000307#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000308ngx_log_debug(cf->log, "%d:%d:%d:%d:%d '%c'" _
309 last_space _ need_space _
310 quoted _ s_quoted _ d_quoted _ ch);
Igor Sysoev295bb632002-12-23 18:22:18 +0000311#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000312
313 if (ch == LF) {
314 cf->conf_file->line++;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000315
316 if (sharp_comment) {
317 sharp_comment = 0;
318 }
319 }
320
321 if (sharp_comment) {
322 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000323 }
324
Igor Sysoev295bb632002-12-23 18:22:18 +0000325 if (quoted) {
326 quoted = 0;
327 continue;
328 }
329
Igor Sysoeva6717c42002-12-23 06:29:22 +0000330 if (need_space) {
331 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
332 last_space = 1;
333 need_space = 0;
334 continue;
335 }
336
337 if (ch == ';' || ch == '{') {
338 return NGX_OK;
339 }
340
341 return NGX_ERROR;
342 }
343
Igor Sysoev88092572002-12-19 07:08:55 +0000344 if (last_space) {
Igor Sysoev88092572002-12-19 07:08:55 +0000345 if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000346 continue;
347 }
348
Igor Sysoevb7387572003-03-11 20:38:13 +0000349 start = h->pos - 1;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000350
351 switch (ch) {
352
Igor Sysoev295bb632002-12-23 18:22:18 +0000353 case ';':
354 case '{':
Igor Sysoev960ffa42002-12-26 07:24:21 +0000355 if (cf->args->nelts == 0) {
356 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
357 "unexpected '%c' in %s:%d",
358 ch, cf->conf_file->file.name.data,
359 cf->conf_file->line);
360 return NGX_ERROR;
361 }
362
Igor Sysoev295bb632002-12-23 18:22:18 +0000363 return NGX_OK;
364
Igor Sysoev960ffa42002-12-26 07:24:21 +0000365 case '}':
366 if (cf->args->nelts > 0) {
367 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
368 "unexpected '}' in %s:%d",
369 cf->conf_file->file.name.data,
370 cf->conf_file->line);
371 return NGX_ERROR;
372 }
373
374 return NGX_CONF_BLOCK_DONE;
375
376 case '#':
377 sharp_comment = 1;
378 continue;
379
Igor Sysoeva6717c42002-12-23 06:29:22 +0000380 case '\\':
381 quoted = 1;
382 last_space = 0;
383 continue;
384
385 case '"':
Igor Sysoev88092572002-12-19 07:08:55 +0000386 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000387 d_quoted = 1;
388 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000389 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000390
Igor Sysoeva6717c42002-12-23 06:29:22 +0000391 case '\'':
392 start++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000393 s_quoted = 1;
394 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000395 continue;
Igor Sysoev88092572002-12-19 07:08:55 +0000396
Igor Sysoeva6717c42002-12-23 06:29:22 +0000397 default:
398 last_space = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000399 }
400
401 } else {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000402 if (ch == '\\') {
403 quoted = 1;
404 continue;
405 }
Igor Sysoev88092572002-12-19 07:08:55 +0000406
Igor Sysoeva6717c42002-12-23 06:29:22 +0000407 if (d_quoted) {
408 if (ch == '"') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000409 d_quoted = 0;
410 need_space = 1;
411 found = 1;
412 }
413
414 } else if (s_quoted) {
415 if (ch == '\'') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000416 s_quoted = 0;
417 need_space = 1;
418 found = 1;
419 }
420
421 } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
422 || ch == ';' || ch == '{') {
Igor Sysoeva6717c42002-12-23 06:29:22 +0000423 last_space = 1;
424 found = 1;
425 }
426
427 if (found) {
Igor Sysoev88092572002-12-19 07:08:55 +0000428 ngx_test_null(word, ngx_push_array(cf->args), NGX_ERROR);
Igor Sysoev295bb632002-12-23 18:22:18 +0000429 ngx_test_null(word->data,
Igor Sysoevb7387572003-03-11 20:38:13 +0000430 ngx_palloc(cf->pool, h->pos - start + 1),
Igor Sysoev88092572002-12-19 07:08:55 +0000431 NGX_ERROR);
Igor Sysoev88092572002-12-19 07:08:55 +0000432
Igor Sysoev295bb632002-12-23 18:22:18 +0000433 for (dst = word->data, src = start, len = 0;
Igor Sysoevb7387572003-03-11 20:38:13 +0000434 src < h->pos - 1;
Igor Sysoev295bb632002-12-23 18:22:18 +0000435 len++)
Igor Sysoeva6717c42002-12-23 06:29:22 +0000436 {
437 if (*src == '\\') {
Igor Sysoev88092572002-12-19 07:08:55 +0000438 src++;
Igor Sysoeva6717c42002-12-23 06:29:22 +0000439 }
Igor Sysoev88092572002-12-19 07:08:55 +0000440 *dst++ = *src++;
441 }
442 *dst = '\0';
Igor Sysoev295bb632002-12-23 18:22:18 +0000443 word->len = len;
Igor Sysoev88092572002-12-19 07:08:55 +0000444
Igor Sysoev73009772003-02-06 17:21:13 +0000445#if 0
Igor Sysoeva6717c42002-12-23 06:29:22 +0000446ngx_log_debug(cf->log, "FOUND %d:'%s'" _ word->len _ word->data);
Igor Sysoev73009772003-02-06 17:21:13 +0000447#endif
Igor Sysoev88092572002-12-19 07:08:55 +0000448
Igor Sysoeva6717c42002-12-23 06:29:22 +0000449 if (ch == ';' || ch == '{') {
450 return NGX_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000451 }
452
Igor Sysoeva6717c42002-12-23 06:29:22 +0000453 found = 0;
Igor Sysoev88092572002-12-19 07:08:55 +0000454 }
Igor Sysoev88092572002-12-19 07:08:55 +0000455 }
456 }
457}
458
Igor Sysoev88092572002-12-19 07:08:55 +0000459
Igor Sysoev6253ca12003-05-27 12:18:54 +0000460char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000461{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000462 char *p = conf;
463
Igor Sysoev6a644c62003-03-04 06:33:48 +0000464 int flag;
465 ngx_str_t *value;
466
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000467 if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000468 return "is duplicate";
469 }
470
Igor Sysoev6a644c62003-03-04 06:33:48 +0000471 value = (ngx_str_t *) cf->args->elts;
472
473 if (ngx_strcasecmp(value[1].data, "on") == 0) {
474 flag = 1;
475
476 } else if (ngx_strcasecmp(value[1].data, "off") == 0) {
477 flag = 0;
478
479 } else {
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000480 ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1,
481 "invalid value \"%s\", it must be \"on\" or \"off\"",
482 value[1].data);
483 return ngx_conf_errstr;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000484 }
485
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000486 *(int *) (p + cmd->offset) = flag;
Igor Sysoev6a644c62003-03-04 06:33:48 +0000487
488 return NGX_CONF_OK;
489}
490
491
Igor Sysoev6253ca12003-05-27 12:18:54 +0000492char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000493{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000494 char *p = conf;
495
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000496 ngx_str_t *field, *value;
497
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000498 field = (ngx_str_t *) (p + cmd->offset);
Igor Sysoev1c13c662003-05-20 15:37:55 +0000499
Igor Sysoev6253ca12003-05-27 12:18:54 +0000500 if (field->data) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000501 return "is duplicate";
502 }
503
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000504 value = (ngx_str_t *) cf->args->elts;
505
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000506 field->len = value[1].len;
507 field->data = value[1].data;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000508
509 return NGX_CONF_OK;
510}
511
512
Igor Sysoev6253ca12003-05-27 12:18:54 +0000513char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000514{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000515 char *p = conf;
516
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000517 int num, len;
518 ngx_str_t *value;
519
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000520 if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000521 return "is duplicate";
522 }
523
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000524 value = (ngx_str_t *) cf->args->elts;
525
526 len = value[1].len;
527
528 num = ngx_atoi(value[1].data, len);
529 if (num == NGX_ERROR) {
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000530 return "invalid number";
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000531 }
532
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000533 *(int *) (p + cmd->offset) = num;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000534
535 return NGX_CONF_OK;
536}
537
538
Igor Sysoev6253ca12003-05-27 12:18:54 +0000539char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000540{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000541 char *p = conf;
542
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000543 int size, len, scale;
544 char last;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000545 ngx_str_t *value;
546
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000547 if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000548 return "is duplicate";
549 }
550
Igor Sysoev960ffa42002-12-26 07:24:21 +0000551 value = (ngx_str_t *) cf->args->elts;
552
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000553 len = value[1].len;
554 last = value[1].data[len - 1];
555
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000556 switch (last) {
557 case 'K':
558 case 'k':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000559 len--;
560 scale = 1024;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000561 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000562
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000563 case 'M':
564 case 'm':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000565 len--;
566 scale = 1024 * 1024;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000567 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000568
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000569 default:
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000570 scale = 1;
571 }
572
573 size = ngx_atoi(value[1].data, len);
574 if (size == NGX_ERROR) {
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000575 return "invalid value";
Igor Sysoev960ffa42002-12-26 07:24:21 +0000576 }
Igor Sysoev88092572002-12-19 07:08:55 +0000577
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000578 size *= scale;
579
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000580 *(int *) (p + cmd->offset) = size;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000581
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000582 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000583}
584
Igor Sysoev88092572002-12-19 07:08:55 +0000585
Igor Sysoev6253ca12003-05-27 12:18:54 +0000586char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev960ffa42002-12-26 07:24:21 +0000587{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000588 char *p = conf;
589
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000590 int size, total, len, scale;
591 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000592 char last, *start;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000593 ngx_str_t *value;
594
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000595 if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000596 return "is duplicate";
597 }
598
Igor Sysoev960ffa42002-12-26 07:24:21 +0000599 value = (ngx_str_t *) cf->args->elts;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000600 start = value[1].data;
601 len = 0;
602 total = 0;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000603
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000604 for (i = 0; /* void */ ; i++) {
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000605
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000606 if (i < value[1].len) {
607 if (value[1].data[i] != ' ') {
608 len++;
609 continue;
610 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000611
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000612 if (value[1].data[i] == ' ' && len == 0) {
613 start = &value[1].data[i + 1];
614 continue;
615 }
616 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000617
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000618 if (len == 0) {
619 break;
620 }
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000621
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000622 last = value[1].data[i - 1];
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000623
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000624 switch (last) {
625 case 'm':
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000626 len--;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000627 max = 35791;
628 scale = 1000 * 60;
629 break;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000630
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000631 case 'h':
632 len--;
633 max = 596;
634 scale = 1000 * 60 * 60;
635 break;
636
637 case 'd':
638 len--;
639 max = 24;
640 scale = 1000 * 60 * 60 * 24;
641 break;
642
643 case 's':
644 len--;
645 if (value[1].data[i - 2] == 'm') {
646 len--;
647 max = 2147483647;
648 scale = 1;
649 break;
650 }
651 /* fall thru */
652
653 default:
654 max = 2147483;
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000655 scale = 1000;
656 }
657
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000658 size = ngx_atoi(start, len);
659 if (size < 0) {
660 return "invalid value";
661 }
662
663 if ((u_int) size > max) {
664 return "value must be less than 597 hours";
665 }
666
667 total += size * scale;
668
669 if (i >= value[1].len) {
670 break;
671 }
672
673 len = 0;
674 start = &value[1].data[i + 1];
Igor Sysoev1d8d9ee2003-04-28 15:06:39 +0000675 }
676
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000677 *(int *) (p + cmd->offset) = total;
Igor Sysoev960ffa42002-12-26 07:24:21 +0000678
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000679 return NGX_CONF_OK;
Igor Sysoev88092572002-12-19 07:08:55 +0000680}
Igor Sysoev6a644c62003-03-04 06:33:48 +0000681
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000682
Igor Sysoev6253ca12003-05-27 12:18:54 +0000683char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000684{
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000685 char *p = conf;
686
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000687 int size, total, len, scale;
688 u_int max, i;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000689 char last, *start;
690 ngx_str_t *value;
691
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000692 if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
Igor Sysoev1c13c662003-05-20 15:37:55 +0000693 return "is duplicate";
694 }
695
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000696 value = (ngx_str_t *) cf->args->elts;
697 start = value[1].data;
698 len = 0;
699 total = 0;
700
701 for (i = 0; /* void */ ; i++) {
702
703 if (i < value[1].len) {
704 if (value[1].data[i] != ' ') {
705 len++;
706 continue;
707 }
708
709 if (value[1].data[i] == ' ' && len == 0) {
710 start = &value[1].data[i + 1];
711 continue;
712 }
713 }
714
715 if (len == 0) {
716 break;
717 }
718
719 last = value[1].data[i - 1];
720
721 switch (last) {
722 case 'm':
723 len--;
724 max = 35791394;
725 scale = 60;
726 break;
727
728 case 'h':
729 len--;
730 max = 596523;
731 scale = 60 * 60;
732 break;
733
734 case 'd':
735 len--;
736 max = 24855;
737 scale = 60 * 60 * 24;
738 break;
739
740 case 'w':
741 len--;
742 max = 3550;
743 scale = 60 * 60 * 24 * 7;
744 break;
745
746 case 'M':
747 len--;
748 max = 828;
749 scale = 60 * 60 * 24 * 30;
750 break;
751
752 case 'y':
753 len--;
754 max = 68;
755 scale = 60 * 60 * 24 * 365;
756 break;
757
758 case 's':
759 len--;
760 /* fall thru */
761
762 default:
763 max = 2147483647;
764 scale = 1;
765 }
766
767 size = ngx_atoi(start, len);
768 if (size < 0) {
769 return "invalid value";
770 }
771
772 if ((u_int) size > max) {
773 return "value must be less than 68 years";
774 }
775
776 total += size * scale;
777
778 if (i >= value[1].len) {
779 break;
780 }
781
782 len = 0;
783 start = &value[1].data[i + 1];
784 }
785
Igor Sysoevaa3436c2003-05-30 14:27:59 +0000786 *(int *) (p + cmd->offset) = total;
Igor Sysoev3d09c8d2003-05-06 17:03:16 +0000787
788 return NGX_CONF_OK;
789}
790
791
Igor Sysoev6253ca12003-05-27 12:18:54 +0000792char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev6a644c62003-03-04 06:33:48 +0000793{
794 return "unsupported on this platform";
795}