Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_conf_file.c
Go to the documentation of this file.
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 
11 #define NGX_CONF_BUFFER 4096
12 
13 static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last);
14 static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf);
15 static ngx_int_t ngx_conf_test_full_name(ngx_str_t *name);
16 static void ngx_conf_flush_files(ngx_cycle_t *cycle);
17 
18 
19 static ngx_command_t ngx_conf_commands[] = {
20 
21  { ngx_string("include"),
24  0,
25  0,
26  NULL },
27 
29 };
30 
31 
34  NULL, /* module context */
35  ngx_conf_commands, /* module directives */
36  NGX_CONF_MODULE, /* module type */
37  NULL, /* init master */
38  NULL, /* init module */
39  NULL, /* init process */
40  NULL, /* init thread */
41  NULL, /* exit thread */
42  ngx_conf_flush_files, /* exit process */
43  NULL, /* exit master */
45 };
46 
47 
48 /* The eight fixed arguments */
49 
50 static ngx_uint_t argument_number[] = {
59 };
60 
61 
62 char *
64 {
65  char *rv;
66  ngx_str_t *param;
67  ngx_buf_t b;
68  ngx_conf_file_t conf_file;
69 
70  param = &cf->cycle->conf_param;
71 
72  if (param->len == 0) {
73  return NGX_CONF_OK;
74  }
75 
76  ngx_memzero(&conf_file, sizeof(ngx_conf_file_t));
77 
78  ngx_memzero(&b, sizeof(ngx_buf_t));
79 
80  b.start = param->data;
81  b.pos = param->data;
82  b.last = param->data + param->len;
83  b.end = b.last;
84  b.temporary = 1;
85 
86  conf_file.file.fd = NGX_INVALID_FILE;
87  conf_file.file.name.data = NULL;
88  conf_file.line = 0;
89 
90  cf->conf_file = &conf_file;
91  cf->conf_file->buffer = &b;
92 
93  rv = ngx_conf_parse(cf, NULL);
94 
95  cf->conf_file = NULL;
96 
97  return rv;
98 }
99 
100 
101 char *
103 {
104  char *rv;
105  ngx_fd_t fd;
106  ngx_int_t rc;
107  ngx_buf_t buf;
108  ngx_conf_file_t *prev, conf_file;
109  enum {
110  parse_file = 0,
111  parse_block,
112  parse_param
113  } type;
114 
115 #if (NGX_SUPPRESS_WARN)
116  fd = NGX_INVALID_FILE;
117  prev = NULL;
118 #endif
119 
120  if (filename) {
121 
122  /* open configuration file */
123 
124  fd = ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
125  if (fd == NGX_INVALID_FILE) {
127  ngx_open_file_n " \"%s\" failed",
128  filename->data);
129  return NGX_CONF_ERROR;
130  }
131 
132  prev = cf->conf_file;
133 
134  cf->conf_file = &conf_file;
135 
136  if (ngx_fd_info(fd, &cf->conf_file->file.info) == NGX_FILE_ERROR) {
138  ngx_fd_info_n " \"%s\" failed", filename->data);
139  }
140 
141  cf->conf_file->buffer = &buf;
142 
143  buf.start = ngx_alloc(NGX_CONF_BUFFER, cf->log);
144  if (buf.start == NULL) {
145  goto failed;
146  }
147 
148  buf.pos = buf.start;
149  buf.last = buf.start;
150  buf.end = buf.last + NGX_CONF_BUFFER;
151  buf.temporary = 1;
152 
153  cf->conf_file->file.fd = fd;
154  cf->conf_file->file.name.len = filename->len;
155  cf->conf_file->file.name.data = filename->data;
156  cf->conf_file->file.offset = 0;
157  cf->conf_file->file.log = cf->log;
158  cf->conf_file->line = 1;
159 
160  type = parse_file;
161 
162  } else if (cf->conf_file->file.fd != NGX_INVALID_FILE) {
163 
164  type = parse_block;
165 
166  } else {
167  type = parse_param;
168  }
169 
170 
171  for ( ;; ) {
172  rc = ngx_conf_read_token(cf);
173 
174  /*
175  * ngx_conf_read_token() may return
176  *
177  * NGX_ERROR there is error
178  * NGX_OK the token terminated by ";" was found
179  * NGX_CONF_BLOCK_START the token terminated by "{" was found
180  * NGX_CONF_BLOCK_DONE the "}" was found
181  * NGX_CONF_FILE_DONE the configuration file is done
182  */
183 
184  if (rc == NGX_ERROR) {
185  goto done;
186  }
187 
188  if (rc == NGX_CONF_BLOCK_DONE) {
189 
190  if (type != parse_block) {
191  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected \"}\"");
192  goto failed;
193  }
194 
195  goto done;
196  }
197 
198  if (rc == NGX_CONF_FILE_DONE) {
199 
200  if (type == parse_block) {
202  "unexpected end of file, expecting \"}\"");
203  goto failed;
204  }
205 
206  goto done;
207  }
208 
209  if (rc == NGX_CONF_BLOCK_START) {
210 
211  if (type == parse_param) {
213  "block directives are not supported "
214  "in -g option");
215  goto failed;
216  }
217  }
218 
219  /* rc == NGX_OK || rc == NGX_CONF_BLOCK_START */
220 
221  if (cf->handler) {
222 
223  /*
224  * the custom handler, i.e., that is used in the http's
225  * "types { ... }" directive
226  */
227 
228  rv = (*cf->handler)(cf, NULL, cf->handler_conf);
229  if (rv == NGX_CONF_OK) {
230  continue;
231  }
232 
233  if (rv == NGX_CONF_ERROR) {
234  goto failed;
235  }
236 
237  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, rv);
238 
239  goto failed;
240  }
241 
242 
243  rc = ngx_conf_handler(cf, rc);
244 
245  if (rc == NGX_ERROR) {
246  goto failed;
247  }
248  }
249 
250 failed:
251 
252  rc = NGX_ERROR;
253 
254 done:
255 
256  if (filename) {
257  if (cf->conf_file->buffer->start) {
259  }
260 
261  if (ngx_close_file(fd) == NGX_FILE_ERROR) {
263  ngx_close_file_n " %s failed",
264  filename->data);
265  return NGX_CONF_ERROR;
266  }
267 
268  cf->conf_file = prev;
269  }
270 
271  if (rc == NGX_ERROR) {
272  return NGX_CONF_ERROR;
273  }
274 
275  return NGX_CONF_OK;
276 }
277 
278 
279 static ngx_int_t
280 ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
281 {
282  char *rv;
283  void *conf, **confp;
284  ngx_uint_t i, found;
285  ngx_str_t *name;
286  ngx_command_t *cmd;
287 
288  name = cf->args->elts;
289 
290  found = 0;
291 
292  for (i = 0; ngx_modules[i]; i++) {
293 
294  cmd = ngx_modules[i]->commands;
295  if (cmd == NULL) {
296  continue;
297  }
298 
299  for ( /* void */ ; cmd->name.len; cmd++) {
300 
301  if (name->len != cmd->name.len) {
302  continue;
303  }
304 
305  if (ngx_strcmp(name->data, cmd->name.data) != 0) {
306  continue;
307  }
308 
309  found = 1;
310 
311  if (ngx_modules[i]->type != NGX_CONF_MODULE
312  && ngx_modules[i]->type != cf->module_type)
313  {
314  continue;
315  }
316 
317  /* is the directive's location right ? */
318 
319  if (!(cmd->type & cf->cmd_type)) {
320  continue;
321  }
322 
323  if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {
325  "directive \"%s\" is not terminated by \";\"",
326  name->data);
327  return NGX_ERROR;
328  }
329 
330  if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {
332  "directive \"%s\" has no opening \"{\"",
333  name->data);
334  return NGX_ERROR;
335  }
336 
337  /* is the directive's argument count right ? */
338 
339  if (!(cmd->type & NGX_CONF_ANY)) {
340 
341  if (cmd->type & NGX_CONF_FLAG) {
342 
343  if (cf->args->nelts != 2) {
344  goto invalid;
345  }
346 
347  } else if (cmd->type & NGX_CONF_1MORE) {
348 
349  if (cf->args->nelts < 2) {
350  goto invalid;
351  }
352 
353  } else if (cmd->type & NGX_CONF_2MORE) {
354 
355  if (cf->args->nelts < 3) {
356  goto invalid;
357  }
358 
359  } else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {
360 
361  goto invalid;
362 
363  } else if (!(cmd->type & argument_number[cf->args->nelts - 1]))
364  {
365  goto invalid;
366  }
367  }
368 
369  /* set up the directive's configuration context */
370 
371  conf = NULL;
372 
373  if (cmd->type & NGX_DIRECT_CONF) {
374  conf = ((void **) cf->ctx)[ngx_modules[i]->index];
375 
376  } else if (cmd->type & NGX_MAIN_CONF) {
377  conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
378 
379  } else if (cf->ctx) {
380  confp = *(void **) ((char *) cf->ctx + cmd->conf);
381 
382  if (confp) {
383  conf = confp[ngx_modules[i]->ctx_index];
384  }
385  }
386 
387  rv = cmd->set(cf, cmd, conf);
388 
389  if (rv == NGX_CONF_OK) {
390  return NGX_OK;
391  }
392 
393  if (rv == NGX_CONF_ERROR) {
394  return NGX_ERROR;
395  }
396 
398  "\"%s\" directive %s", name->data, rv);
399 
400  return NGX_ERROR;
401  }
402  }
403 
404  if (found) {
406  "\"%s\" directive is not allowed here", name->data);
407 
408  return NGX_ERROR;
409  }
410 
412  "unknown directive \"%s\"", name->data);
413 
414  return NGX_ERROR;
415 
416 invalid:
417 
419  "invalid number of arguments in \"%s\" directive",
420  name->data);
421 
422  return NGX_ERROR;
423 }
424 
425 
426 static ngx_int_t
427 ngx_conf_read_token(ngx_conf_t *cf)
428 {
429  u_char *start, ch, *src, *dst;
430  off_t file_size;
431  size_t len;
432  ssize_t n, size;
433  ngx_uint_t found, need_space, last_space, sharp_comment, variable;
434  ngx_uint_t quoted, s_quoted, d_quoted, start_line;
435  ngx_str_t *word;
436  ngx_buf_t *b;
437 
438  found = 0;
439  need_space = 0;
440  last_space = 1;
441  sharp_comment = 0;
442  variable = 0;
443  quoted = 0;
444  s_quoted = 0;
445  d_quoted = 0;
446 
447  cf->args->nelts = 0;
448  b = cf->conf_file->buffer;
449  start = b->pos;
450  start_line = cf->conf_file->line;
451 
452  file_size = ngx_file_size(&cf->conf_file->file.info);
453 
454  for ( ;; ) {
455 
456  if (b->pos >= b->last) {
457 
458  if (cf->conf_file->file.offset >= file_size) {
459 
460  if (cf->args->nelts > 0 || !last_space) {
461 
462  if (cf->conf_file->file.fd == NGX_INVALID_FILE) {
464  "unexpected end of parameter, "
465  "expecting \";\"");
466  return NGX_ERROR;
467  }
468 
470  "unexpected end of file, "
471  "expecting \";\" or \"}\"");
472  return NGX_ERROR;
473  }
474 
475  return NGX_CONF_FILE_DONE;
476  }
477 
478  len = b->pos - start;
479 
480  if (len == NGX_CONF_BUFFER) {
481  cf->conf_file->line = start_line;
482 
483  if (d_quoted) {
484  ch = '"';
485 
486  } else if (s_quoted) {
487  ch = '\'';
488 
489  } else {
491  "too long parameter \"%*s...\" started",
492  10, start);
493  return NGX_ERROR;
494  }
495 
497  "too long parameter, probably "
498  "missing terminating \"%c\" character", ch);
499  return NGX_ERROR;
500  }
501 
502  if (len) {
503  ngx_memmove(b->start, start, len);
504  }
505 
506  size = (ssize_t) (file_size - cf->conf_file->file.offset);
507 
508  if (size > b->end - (b->start + len)) {
509  size = b->end - (b->start + len);
510  }
511 
512  n = ngx_read_file(&cf->conf_file->file, b->start + len, size,
513  cf->conf_file->file.offset);
514 
515  if (n == NGX_ERROR) {
516  return NGX_ERROR;
517  }
518 
519  if (n != size) {
521  ngx_read_file_n " returned "
522  "only %z bytes instead of %z",
523  n, size);
524  return NGX_ERROR;
525  }
526 
527  b->pos = b->start + len;
528  b->last = b->pos + n;
529  start = b->start;
530  }
531 
532  ch = *b->pos++;
533 
534  if (ch == LF) {
535  cf->conf_file->line++;
536 
537  if (sharp_comment) {
538  sharp_comment = 0;
539  }
540  }
541 
542  if (sharp_comment) {
543  continue;
544  }
545 
546  if (quoted) {
547  quoted = 0;
548  continue;
549  }
550 
551  if (need_space) {
552  if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
553  last_space = 1;
554  need_space = 0;
555  continue;
556  }
557 
558  if (ch == ';') {
559  return NGX_OK;
560  }
561 
562  if (ch == '{') {
563  return NGX_CONF_BLOCK_START;
564  }
565 
566  if (ch == ')') {
567  last_space = 1;
568  need_space = 0;
569 
570  } else {
572  "unexpected \"%c\"", ch);
573  return NGX_ERROR;
574  }
575  }
576 
577  if (last_space) {
578  if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
579  continue;
580  }
581 
582  start = b->pos - 1;
583  start_line = cf->conf_file->line;
584 
585  switch (ch) {
586 
587  case ';':
588  case '{':
589  if (cf->args->nelts == 0) {
591  "unexpected \"%c\"", ch);
592  return NGX_ERROR;
593  }
594 
595  if (ch == '{') {
596  return NGX_CONF_BLOCK_START;
597  }
598 
599  return NGX_OK;
600 
601  case '}':
602  if (cf->args->nelts != 0) {
604  "unexpected \"}\"");
605  return NGX_ERROR;
606  }
607 
608  return NGX_CONF_BLOCK_DONE;
609 
610  case '#':
611  sharp_comment = 1;
612  continue;
613 
614  case '\\':
615  quoted = 1;
616  last_space = 0;
617  continue;
618 
619  case '"':
620  start++;
621  d_quoted = 1;
622  last_space = 0;
623  continue;
624 
625  case '\'':
626  start++;
627  s_quoted = 1;
628  last_space = 0;
629  continue;
630 
631  default:
632  last_space = 0;
633  }
634 
635  } else {
636  if (ch == '{' && variable) {
637  continue;
638  }
639 
640  variable = 0;
641 
642  if (ch == '\\') {
643  quoted = 1;
644  continue;
645  }
646 
647  if (ch == '$') {
648  variable = 1;
649  continue;
650  }
651 
652  if (d_quoted) {
653  if (ch == '"') {
654  d_quoted = 0;
655  need_space = 1;
656  found = 1;
657  }
658 
659  } else if (s_quoted) {
660  if (ch == '\'') {
661  s_quoted = 0;
662  need_space = 1;
663  found = 1;
664  }
665 
666  } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
667  || ch == ';' || ch == '{')
668  {
669  last_space = 1;
670  found = 1;
671  }
672 
673  if (found) {
674  word = ngx_array_push(cf->args);
675  if (word == NULL) {
676  return NGX_ERROR;
677  }
678 
679  word->data = ngx_pnalloc(cf->pool, b->pos - start + 1);
680  if (word->data == NULL) {
681  return NGX_ERROR;
682  }
683 
684  for (dst = word->data, src = start, len = 0;
685  src < b->pos - 1;
686  len++)
687  {
688  if (*src == '\\') {
689  switch (src[1]) {
690  case '"':
691  case '\'':
692  case '\\':
693  src++;
694  break;
695 
696  case 't':
697  *dst++ = '\t';
698  src += 2;
699  continue;
700 
701  case 'r':
702  *dst++ = '\r';
703  src += 2;
704  continue;
705 
706  case 'n':
707  *dst++ = '\n';
708  src += 2;
709  continue;
710  }
711 
712  }
713  *dst++ = *src++;
714  }
715  *dst = '\0';
716  word->len = len;
717 
718  if (ch == ';') {
719  return NGX_OK;
720  }
721 
722  if (ch == '{') {
723  return NGX_CONF_BLOCK_START;
724  }
725 
726  found = 0;
727  }
728  }
729  }
730 }
731 
732 
733 char *
735 {
736  char *rv;
737  ngx_int_t n;
738  ngx_str_t *value, file, name;
739  ngx_glob_t gl;
740 
741  value = cf->args->elts;
742  file = value[1];
743 
744  ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
745 
746  if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
747  return NGX_CONF_ERROR;
748  }
749 
750  if (strpbrk((char *) file.data, "*?[") == NULL) {
751 
752  ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
753 
754  return ngx_conf_parse(cf, &file);
755  }
756 
757  ngx_memzero(&gl, sizeof(ngx_glob_t));
758 
759  gl.pattern = file.data;
760  gl.log = cf->log;
761  gl.test = 1;
762 
763  if (ngx_open_glob(&gl) != NGX_OK) {
765  ngx_open_glob_n " \"%s\" failed", file.data);
766  return NGX_CONF_ERROR;
767  }
768 
769  rv = NGX_CONF_OK;
770 
771  for ( ;; ) {
772  n = ngx_read_glob(&gl, &name);
773 
774  if (n != NGX_OK) {
775  break;
776  }
777 
778  file.len = name.len++;
779  file.data = ngx_pstrdup(cf->pool, &name);
780 
781  ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
782 
783  rv = ngx_conf_parse(cf, &file);
784 
785  if (rv != NGX_CONF_OK) {
786  break;
787  }
788  }
789 
790  ngx_close_glob(&gl);
791 
792  return rv;
793 }
794 
795 
796 ngx_int_t
798 {
799  size_t len;
800  u_char *p, *n, *prefix;
801  ngx_int_t rc;
802 
803  rc = ngx_conf_test_full_name(name);
804 
805  if (rc == NGX_OK) {
806  return rc;
807  }
808 
809  if (conf_prefix) {
810  len = cycle->conf_prefix.len;
811  prefix = cycle->conf_prefix.data;
812 
813  } else {
814  len = cycle->prefix.len;
815  prefix = cycle->prefix.data;
816  }
817 
818 #if (NGX_WIN32)
819 
820  if (rc == 2) {
821  len = rc;
822  }
823 
824 #endif
825 
826  n = ngx_pnalloc(cycle->pool, len + name->len + 1);
827  if (n == NULL) {
828  return NGX_ERROR;
829  }
830 
831  p = ngx_cpymem(n, prefix, len);
832  ngx_cpystrn(p, name->data, name->len + 1);
833 
834  name->len += len;
835  name->data = n;
836 
837  return NGX_OK;
838 }
839 
840 
841 static ngx_int_t
842 ngx_conf_test_full_name(ngx_str_t *name)
843 {
844 #if (NGX_WIN32)
845  u_char c0, c1;
846 
847  c0 = name->data[0];
848 
849  if (name->len < 2) {
850  if (c0 == '/') {
851  return 2;
852  }
853 
854  return NGX_DECLINED;
855  }
856 
857  c1 = name->data[1];
858 
859  if (c1 == ':') {
860  c0 |= 0x20;
861 
862  if ((c0 >= 'a' && c0 <= 'z')) {
863  return NGX_OK;
864  }
865 
866  return NGX_DECLINED;
867  }
868 
869  if (c1 == '/') {
870  return NGX_OK;
871  }
872 
873  if (c0 == '/') {
874  return 2;
875  }
876 
877  return NGX_DECLINED;
878 
879 #else
880 
881  if (name->data[0] == '/') {
882  return NGX_OK;
883  }
884 
885  return NGX_DECLINED;
886 
887 #endif
888 }
889 
890 
893 {
894  ngx_str_t full;
895  ngx_uint_t i;
896  ngx_list_part_t *part;
897  ngx_open_file_t *file;
898 
899 #if (NGX_SUPPRESS_WARN)
900  ngx_str_null(&full);
901 #endif
902 
903  if (name->len) {
904  full = *name;
905 
906  if (ngx_conf_full_name(cycle, &full, 0) != NGX_OK) {
907  return NULL;
908  }
909 
910  part = &cycle->open_files.part;
911  file = part->elts;
912 
913  for (i = 0; /* void */ ; i++) {
914 
915  if (i >= part->nelts) {
916  if (part->next == NULL) {
917  break;
918  }
919  part = part->next;
920  file = part->elts;
921  i = 0;
922  }
923 
924  if (full.len != file[i].name.len) {
925  continue;
926  }
927 
928  if (ngx_strcmp(full.data, file[i].name.data) == 0) {
929  return &file[i];
930  }
931  }
932  }
933 
934  file = ngx_list_push(&cycle->open_files);
935  if (file == NULL) {
936  return NULL;
937  }
938 
939  if (name->len) {
940  file->fd = NGX_INVALID_FILE;
941  file->name = full;
942 
943  } else {
944  file->fd = ngx_stderr;
945  file->name = *name;
946  }
947 
948  file->flush = NULL;
949  file->data = NULL;
950 
951  return file;
952 }
953 
954 
955 static void
956 ngx_conf_flush_files(ngx_cycle_t *cycle)
957 {
958  ngx_uint_t i;
959  ngx_list_part_t *part;
960  ngx_open_file_t *file;
961 
962  ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "flush files");
963 
964  part = &cycle->open_files.part;
965  file = part->elts;
966 
967  for (i = 0; /* void */ ; i++) {
968 
969  if (i >= part->nelts) {
970  if (part->next == NULL) {
971  break;
972  }
973  part = part->next;
974  file = part->elts;
975  i = 0;
976  }
977 
978  if (file[i].flush) {
979  file[i].flush(&file[i], cycle->log);
980  }
981  }
982 }
983 
984 
985 void ngx_cdecl
987  const char *fmt, ...)
988 {
989  u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last;
990  va_list args;
991 
992  last = errstr + NGX_MAX_CONF_ERRSTR;
993 
994  va_start(args, fmt);
995  p = ngx_vslprintf(errstr, last, fmt, args);
996  va_end(args);
997 
998  if (err) {
999  p = ngx_log_errno(p, last, err);
1000  }
1001 
1002  if (cf->conf_file == NULL) {
1003  ngx_log_error(level, cf->log, 0, "%*s", p - errstr, errstr);
1004  return;
1005  }
1006 
1007  if (cf->conf_file->file.fd == NGX_INVALID_FILE) {
1008  ngx_log_error(level, cf->log, 0, "%*s in command line",
1009  p - errstr, errstr);
1010  return;
1011  }
1012 
1013  ngx_log_error(level, cf->log, 0, "%*s in %s:%ui",
1014  p - errstr, errstr,
1015  cf->conf_file->file.name.data, cf->conf_file->line);
1016 }
1017 
1018 
1019 char *
1021 {
1022  char *p = conf;
1023 
1024  ngx_str_t *value;
1025  ngx_flag_t *fp;
1026  ngx_conf_post_t *post;
1027 
1028  fp = (ngx_flag_t *) (p + cmd->offset);
1029 
1030  if (*fp != NGX_CONF_UNSET) {
1031  return "is duplicate";
1032  }
1033 
1034  value = cf->args->elts;
1035 
1036  if (ngx_strcasecmp(value[1].data, (u_char *) "on") == 0) {
1037  *fp = 1;
1038 
1039  } else if (ngx_strcasecmp(value[1].data, (u_char *) "off") == 0) {
1040  *fp = 0;
1041 
1042  } else {
1044  "invalid value \"%s\" in \"%s\" directive, "
1045  "it must be \"on\" or \"off\"",
1046  value[1].data, cmd->name.data);
1047  return NGX_CONF_ERROR;
1048  }
1049 
1050  if (cmd->post) {
1051  post = cmd->post;
1052  return post->post_handler(cf, post, fp);
1053  }
1054 
1055  return NGX_CONF_OK;
1056 }
1057 
1058 
1059 char *
1061 {
1062  char *p = conf;
1063 
1064  ngx_str_t *field, *value;
1065  ngx_conf_post_t *post;
1066 
1067  field = (ngx_str_t *) (p + cmd->offset);
1068 
1069  if (field->data) {
1070  return "is duplicate";
1071  }
1072 
1073  value = cf->args->elts;
1074 
1075  *field = value[1];
1076 
1077  if (cmd->post) {
1078  post = cmd->post;
1079  return post->post_handler(cf, post, field);
1080  }
1081 
1082  return NGX_CONF_OK;
1083 }
1084 
1085 
1086 char *
1088 {
1089  char *p = conf;
1090 
1091  ngx_str_t *value, *s;
1092  ngx_array_t **a;
1093  ngx_conf_post_t *post;
1094 
1095  a = (ngx_array_t **) (p + cmd->offset);
1096 
1097  if (*a == NGX_CONF_UNSET_PTR) {
1098  *a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
1099  if (*a == NULL) {
1100  return NGX_CONF_ERROR;
1101  }
1102  }
1103 
1104  s = ngx_array_push(*a);
1105  if (s == NULL) {
1106  return NGX_CONF_ERROR;
1107  }
1108 
1109  value = cf->args->elts;
1110 
1111  *s = value[1];
1112 
1113  if (cmd->post) {
1114  post = cmd->post;
1115  return post->post_handler(cf, post, s);
1116  }
1117 
1118  return NGX_CONF_OK;
1119 }
1120 
1121 
1122 char *
1124 {
1125  char *p = conf;
1126 
1127  ngx_str_t *value;
1128  ngx_array_t **a;
1129  ngx_keyval_t *kv;
1130  ngx_conf_post_t *post;
1131 
1132  a = (ngx_array_t **) (p + cmd->offset);
1133 
1134  if (*a == NULL) {
1135  *a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
1136  if (*a == NULL) {
1137  return NGX_CONF_ERROR;
1138  }
1139  }
1140 
1141  kv = ngx_array_push(*a);
1142  if (kv == NULL) {
1143  return NGX_CONF_ERROR;
1144  }
1145 
1146  value = cf->args->elts;
1147 
1148  kv->key = value[1];
1149  kv->value = value[2];
1150 
1151  if (cmd->post) {
1152  post = cmd->post;
1153  return post->post_handler(cf, post, kv);
1154  }
1155 
1156  return NGX_CONF_OK;
1157 }
1158 
1159 
1160 char *
1162 {
1163  char *p = conf;
1164 
1165  ngx_int_t *np;
1166  ngx_str_t *value;
1167  ngx_conf_post_t *post;
1168 
1169 
1170  np = (ngx_int_t *) (p + cmd->offset);
1171 
1172  if (*np != NGX_CONF_UNSET) {
1173  return "is duplicate";
1174  }
1175 
1176  value = cf->args->elts;
1177  *np = ngx_atoi(value[1].data, value[1].len);
1178  if (*np == NGX_ERROR) {
1179  return "invalid number";
1180  }
1181 
1182  if (cmd->post) {
1183  post = cmd->post;
1184  return post->post_handler(cf, post, np);
1185  }
1186 
1187  return NGX_CONF_OK;
1188 }
1189 
1190 
1191 char *
1193 {
1194  char *p = conf;
1195 
1196  size_t *sp;
1197  ngx_str_t *value;
1198  ngx_conf_post_t *post;
1199 
1200 
1201  sp = (size_t *) (p + cmd->offset);
1202  if (*sp != NGX_CONF_UNSET_SIZE) {
1203  return "is duplicate";
1204  }
1205 
1206  value = cf->args->elts;
1207 
1208  *sp = ngx_parse_size(&value[1]);
1209  if (*sp == (size_t) NGX_ERROR) {
1210  return "invalid value";
1211  }
1212 
1213  if (cmd->post) {
1214  post = cmd->post;
1215  return post->post_handler(cf, post, sp);
1216  }
1217 
1218  return NGX_CONF_OK;
1219 }
1220 
1221 
1222 char *
1224 {
1225  char *p = conf;
1226 
1227  off_t *op;
1228  ngx_str_t *value;
1229  ngx_conf_post_t *post;
1230 
1231 
1232  op = (off_t *) (p + cmd->offset);
1233  if (*op != NGX_CONF_UNSET) {
1234  return "is duplicate";
1235  }
1236 
1237  value = cf->args->elts;
1238 
1239  *op = ngx_parse_offset(&value[1]);
1240  if (*op == (off_t) NGX_ERROR) {
1241  return "invalid value";
1242  }
1243 
1244  if (cmd->post) {
1245  post = cmd->post;
1246  return post->post_handler(cf, post, op);
1247  }
1248 
1249  return NGX_CONF_OK;
1250 }
1251 
1252 
1253 char *
1255 {
1256  char *p = conf;
1257 
1258  ngx_msec_t *msp;
1259  ngx_str_t *value;
1260  ngx_conf_post_t *post;
1261 
1262 
1263  msp = (ngx_msec_t *) (p + cmd->offset);
1264  if (*msp != NGX_CONF_UNSET_MSEC) {
1265  return "is duplicate";
1266  }
1267 
1268  value = cf->args->elts;
1269 
1270  *msp = ngx_parse_time(&value[1], 0);
1271  if (*msp == (ngx_msec_t) NGX_ERROR) {
1272  return "invalid value";
1273  }
1274 
1275  if (cmd->post) {
1276  post = cmd->post;
1277  return post->post_handler(cf, post, msp);
1278  }
1279 
1280  return NGX_CONF_OK;
1281 }
1282 
1283 
1284 char *
1286 {
1287  char *p = conf;
1288 
1289  time_t *sp;
1290  ngx_str_t *value;
1291  ngx_conf_post_t *post;
1292 
1293 
1294  sp = (time_t *) (p + cmd->offset);
1295  if (*sp != NGX_CONF_UNSET) {
1296  return "is duplicate";
1297  }
1298 
1299  value = cf->args->elts;
1300 
1301  *sp = ngx_parse_time(&value[1], 1);
1302  if (*sp == (time_t) NGX_ERROR) {
1303  return "invalid value";
1304  }
1305 
1306  if (cmd->post) {
1307  post = cmd->post;
1308  return post->post_handler(cf, post, sp);
1309  }
1310 
1311  return NGX_CONF_OK;
1312 }
1313 
1314 
1315 char *
1317 {
1318  char *p = conf;
1319 
1320  ngx_str_t *value;
1321  ngx_bufs_t *bufs;
1322 
1323 
1324  bufs = (ngx_bufs_t *) (p + cmd->offset);
1325  if (bufs->num) {
1326  return "is duplicate";
1327  }
1328 
1329  value = cf->args->elts;
1330 
1331  bufs->num = ngx_atoi(value[1].data, value[1].len);
1332  if (bufs->num == NGX_ERROR || bufs->num == 0) {
1333  return "invalid value";
1334  }
1335 
1336  bufs->size = ngx_parse_size(&value[2]);
1337  if (bufs->size == (size_t) NGX_ERROR || bufs->size == 0) {
1338  return "invalid value";
1339  }
1340 
1341  return NGX_CONF_OK;
1342 }
1343 
1344 
1345 char *
1347 {
1348  char *p = conf;
1349 
1350  ngx_uint_t *np, i;
1351  ngx_str_t *value;
1352  ngx_conf_enum_t *e;
1353 
1354  np = (ngx_uint_t *) (p + cmd->offset);
1355 
1356  if (*np != NGX_CONF_UNSET_UINT) {
1357  return "is duplicate";
1358  }
1359 
1360  value = cf->args->elts;
1361  e = cmd->post;
1362 
1363  for (i = 0; e[i].name.len != 0; i++) {
1364  if (e[i].name.len != value[1].len
1365  || ngx_strcasecmp(e[i].name.data, value[1].data) != 0)
1366  {
1367  continue;
1368  }
1369 
1370  *np = e[i].value;
1371 
1372  return NGX_CONF_OK;
1373  }
1374 
1376  "invalid value \"%s\"", value[1].data);
1377 
1378  return NGX_CONF_ERROR;
1379 }
1380 
1381 
1382 char *
1384 {
1385  char *p = conf;
1386 
1387  ngx_uint_t *np, i, m;
1388  ngx_str_t *value;
1389  ngx_conf_bitmask_t *mask;
1390 
1391 
1392  np = (ngx_uint_t *) (p + cmd->offset);
1393  value = cf->args->elts;
1394  mask = cmd->post;
1395 
1396  for (i = 1; i < cf->args->nelts; i++) {
1397  for (m = 0; mask[m].name.len != 0; m++) {
1398 
1399  if (mask[m].name.len != value[i].len
1400  || ngx_strcasecmp(mask[m].name.data, value[i].data) != 0)
1401  {
1402  continue;
1403  }
1404 
1405  if (*np & mask[m].mask) {
1407  "duplicate value \"%s\"", value[i].data);
1408 
1409  } else {
1410  *np |= mask[m].mask;
1411  }
1412 
1413  break;
1414  }
1415 
1416  if (mask[m].name.len == 0) {
1418  "invalid value \"%s\"", value[i].data);
1419 
1420  return NGX_CONF_ERROR;
1421  }
1422  }
1423 
1424  return NGX_CONF_OK;
1425 }
1426 
1427 
1428 #if 0
1429 
1430 char *
1431 ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1432 {
1433  return "unsupported on this platform";
1434 }
1435 
1436 #endif
1437 
1438 
1439 char *
1440 ngx_conf_deprecated(ngx_conf_t *cf, void *post, void *data)
1441 {
1442  ngx_conf_deprecated_t *d = post;
1443 
1445  "the \"%s\" directive is deprecated, "
1446  "use the \"%s\" directive instead",
1447  d->old_name, d->new_name);
1448 
1449  return NGX_CONF_OK;
1450 }
1451 
1452 
1453 char *
1454 ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data)
1455 {
1456  ngx_conf_num_bounds_t *bounds = post;
1457  ngx_int_t *np = data;
1458 
1459  if (bounds->high == -1) {
1460  if (*np >= bounds->low) {
1461  return NGX_CONF_OK;
1462  }
1463 
1465  "value must be equal to or greater than %i",
1466  bounds->low);
1467 
1468  return NGX_CONF_ERROR;
1469  }
1470 
1471  if (*np >= bounds->low && *np <= bounds->high) {
1472  return NGX_CONF_OK;
1473  }
1474 
1476  "value must be between %i and %i",
1477  bounds->low, bounds->high);
1478 
1479  return NGX_CONF_ERROR;
1480 }