~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/core/ngx_conf_file.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 
 10 #define NGX_CONF_BUFFER  4096
 11 
 12 static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last);
 13 static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf);
 14 static char *ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 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"),
 22       NGX_ANY_CONF|NGX_CONF_TAKE1,
 23       ngx_conf_include,
 24       0,
 25       0,
 26       NULL },
 27 
 28       ngx_null_command
 29 };
 30 
 31 
 32 ngx_module_t  ngx_conf_module = {
 33     NGX_MODULE_V1,
 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 */
 44     NGX_MODULE_V1_PADDING
 45 };
 46 
 47 
 48 /* The eight fixed arguments */
 49 
 50 static ngx_uint_t argument_number[] = {
 51     NGX_CONF_NOARGS,
 52     NGX_CONF_TAKE1,
 53     NGX_CONF_TAKE2,
 54     NGX_CONF_TAKE3,
 55     NGX_CONF_TAKE4,
 56     NGX_CONF_TAKE5,
 57     NGX_CONF_TAKE6,
 58     NGX_CONF_TAKE7
 59 };
 60 
 61 
 62 char *
 63 ngx_conf_param(ngx_conf_t *cf)
 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 *
102 ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
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) {
126             ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
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) == -1) {
137             ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
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) {
201                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
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) {
212                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
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) {
258             ngx_free(cf->conf_file->buffer->start);
259         }
260 
261         if (ngx_close_file(fd) == NGX_FILE_ERROR) {
262             ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
263                           ngx_close_file_n " %s failed",
264                           cf->conf_file->file.name.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, multi;
285     ngx_str_t      *name;
286     ngx_command_t  *cmd;
287 
288     name = cf->args->elts;
289 
290     multi = 0;
291 
292     for (i = 0; ngx_modules[i]; i++) {
293 
294         /* look up the directive in the appropriate modules */
295 
296         if (ngx_modules[i]->type != NGX_CONF_MODULE
297             && ngx_modules[i]->type != cf->module_type)
298         {
299             continue;
300         }
301 
302         cmd = ngx_modules[i]->commands;
303         if (cmd == NULL) {
304             continue;
305         }
306 
307         for ( /* void */ ; cmd->name.len; cmd++) {
308 
309             if (name->len != cmd->name.len) {
310                 continue;
311             }
312 
313             if (ngx_strcmp(name->data, cmd->name.data) != 0) {
314                 continue;
315             }
316 
317 
318             /* is the directive's location right ? */
319 
320             if (!(cmd->type & cf->cmd_type)) {
321                 if (cmd->type & NGX_CONF_MULTI) {
322                     multi = 1;
323                     continue;
324                 }
325 
326                 goto not_allowed;
327             }
328 
329             if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {
330                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
331                                   "directive \"%s\" is not terminated by \";\"",
332                                   name->data);
333                 return NGX_ERROR;
334             }
335 
336             if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {
337                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
338                                    "directive \"%s\" has no opening \"{\"",
339                                    name->data);
340                 return NGX_ERROR;
341             }
342 
343             /* is the directive's argument count right ? */
344 
345             if (!(cmd->type & NGX_CONF_ANY)) {
346 
347                 if (cmd->type & NGX_CONF_FLAG) {
348 
349                     if (cf->args->nelts != 2) {
350                         goto invalid;
351                     }
352 
353                 } else if (cmd->type & NGX_CONF_1MORE) {
354 
355                     if (cf->args->nelts < 2) {
356                         goto invalid;
357                     }
358 
359                 } else if (cmd->type & NGX_CONF_2MORE) {
360 
361                     if (cf->args->nelts < 3) {
362                         goto invalid;
363                     }
364 
365                 } else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {
366 
367                     goto invalid;
368 
369                 } else if (!(cmd->type & argument_number[cf->args->nelts - 1]))
370                 {
371                     goto invalid;
372                 }
373             }
374 
375             /* set up the directive's configuration context */
376 
377             conf = NULL;
378 
379             if (cmd->type & NGX_DIRECT_CONF) {
380                 conf = ((void **) cf->ctx)[ngx_modules[i]->index];
381 
382             } else if (cmd->type & NGX_MAIN_CONF) {
383                 conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
384 
385             } else if (cf->ctx) {
386                 confp = *(void **) ((char *) cf->ctx + cmd->conf);
387 
388                 if (confp) {
389                     conf = confp[ngx_modules[i]->ctx_index];
390                 }
391             }
392 
393             rv = cmd->set(cf, cmd, conf);
394 
395             if (rv == NGX_CONF_OK) {
396                 return NGX_OK;
397             }
398 
399             if (rv == NGX_CONF_ERROR) {
400                 return NGX_ERROR;
401             }
402 
403             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
404                                "\"%s\" directive %s", name->data, rv);
405 
406             return NGX_ERROR;
407         }
408     }
409 
410     if (multi == 0) {
411         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
412                            "unknown directive \"%s\"", name->data);
413 
414         return NGX_ERROR;
415     }
416 
417 not_allowed:
418 
419     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
420                        "\"%s\" directive is not allowed here", name->data);
421     return NGX_ERROR;
422 
423 invalid:
424 
425     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
426                        "invalid number of arguments in \"%s\" directive",
427                        name->data);
428 
429     return NGX_ERROR;
430 }
431 
432 
433 static ngx_int_t
434 ngx_conf_read_token(ngx_conf_t *cf)
435 {
436     u_char      *start, ch, *src, *dst;
437     off_t        file_size;
438     size_t       len;
439     ssize_t      n, size;
440     ngx_uint_t   found, need_space, last_space, sharp_comment, variable;
441     ngx_uint_t   quoted, s_quoted, d_quoted, start_line;
442     ngx_str_t   *word;
443     ngx_buf_t   *b;
444 
445     found = 0;
446     need_space = 0;
447     last_space = 1;
448     sharp_comment = 0;
449     variable = 0;
450     quoted = 0;
451     s_quoted = 0;
452     d_quoted = 0;
453 
454     cf->args->nelts = 0;
455     b = cf->conf_file->buffer;
456     start = b->pos;
457     start_line = cf->conf_file->line;
458 
459     file_size = ngx_file_size(&cf->conf_file->file.info);
460 
461     for ( ;; ) {
462 
463         if (b->pos >= b->last) {
464 
465             if (cf->conf_file->file.offset >= file_size) {
466 
467                 if (cf->args->nelts > 0) {
468 
469                     if (cf->conf_file->file.fd == NGX_INVALID_FILE) {
470                         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
471                                            "unexpected end of parameter, "
472                                            "expecting \";\"");
473                         return NGX_ERROR;
474                     }
475 
476                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
477                                   "unexpected end of file, "
478                                   "expecting \";\" or \"}\"");
479                     return NGX_ERROR;
480                 }
481 
482                 return NGX_CONF_FILE_DONE;
483             }
484 
485             len = b->pos - start;
486 
487             if (len == NGX_CONF_BUFFER) {
488                 cf->conf_file->line = start_line;
489 
490                 if (d_quoted) {
491                     ch = '"';
492 
493                 } else if (s_quoted) {
494                     ch = '\'';
495 
496                 } else {
497                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
498                                        "too long parameter \"%*s...\" started",
499                                        10, start);
500                     return NGX_ERROR;
501                 }
502 
503                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
504                                    "too long parameter, probably "
505                                    "missing terminating \"%c\" character", ch);
506                 return NGX_ERROR;
507             }
508 
509             if (len) {
510                 ngx_memcpy(b->start, start, len);
511             }
512 
513             size = (ssize_t) (file_size - cf->conf_file->file.offset);
514 
515             if (size > b->end - (b->start + len)) {
516                 size = b->end - (b->start + len);
517             }
518 
519             n = ngx_read_file(&cf->conf_file->file, b->start + len, size,
520                               cf->conf_file->file.offset);
521 
522             if (n == NGX_ERROR) {
523                 return NGX_ERROR;
524             }
525 
526             if (n != size) {
527                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
528                                    ngx_read_file_n " returned "
529                                    "only %z bytes instead of %z",
530                                    n, size);
531                 return NGX_ERROR;
532             }
533 
534             b->pos = b->start + len;
535             b->last = b->pos + n;
536             start = b->start;
537         }
538 
539         ch = *b->pos++;
540 
541         if (ch == LF) {
542             cf->conf_file->line++;
543 
544             if (sharp_comment) {
545                 sharp_comment = 0;
546             }
547         }
548 
549         if (sharp_comment) {
550             continue;
551         }
552 
553         if (quoted) {
554             quoted = 0;
555             continue;
556         }
557 
558         if (need_space) {
559             if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
560                 last_space = 1;
561                 need_space = 0;
562                 continue;
563             }
564 
565             if (ch == ';') {
566                 return NGX_OK;
567             }
568 
569             if (ch == '{') {
570                 return NGX_CONF_BLOCK_START;
571             }
572 
573             if (ch == ')') {
574                 last_space = 1;
575                 need_space = 0;
576 
577             } else {
578                  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
579                                     "unexpected \"%c\"", ch);
580                  return NGX_ERROR;
581             }
582         }
583 
584         if (last_space) {
585             if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
586                 continue;
587             }
588 
589             start = b->pos - 1;
590             start_line = cf->conf_file->line;
591 
592             switch (ch) {
593 
594             case ';':
595             case '{':
596                 if (cf->args->nelts == 0) {
597                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
598                                        "unexpected \"%c\"", ch);
599                     return NGX_ERROR;
600                 }
601 
602                 if (ch == '{') {
603                     return NGX_CONF_BLOCK_START;
604                 }
605 
606                 return NGX_OK;
607 
608             case '}':
609                 if (cf->args->nelts != 0) {
610                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
611                                        "unexpected \"}\"");
612                     return NGX_ERROR;
613                 }
614 
615                 return NGX_CONF_BLOCK_DONE;
616 
617             case '#':
618                 sharp_comment = 1;
619                 continue;
620 
621             case '\\':
622                 quoted = 1;
623                 last_space = 0;
624                 continue;
625 
626             case '"':
627                 start++;
628                 d_quoted = 1;
629                 last_space = 0;
630                 continue;
631 
632             case '\'':
633                 start++;
634                 s_quoted = 1;
635                 last_space = 0;
636                 continue;
637 
638             default:
639                 last_space = 0;
640             }
641 
642         } else {
643             if (ch == '{' && variable) {
644                 continue;
645             }
646 
647             variable = 0;
648 
649             if (ch == '\\') {
650                 quoted = 1;
651                 continue;
652             }
653 
654             if (ch == '$') {
655                 variable = 1;
656                 continue;
657             }
658 
659             if (d_quoted) {
660                 if (ch == '"') {
661                     d_quoted = 0;
662                     need_space = 1;
663                     found = 1;
664                 }
665 
666             } else if (s_quoted) {
667                 if (ch == '\'') {
668                     s_quoted = 0;
669                     need_space = 1;
670                     found = 1;
671                 }
672 
673             } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
674                        || ch == ';' || ch == '{') {
675                 last_space = 1;
676                 found = 1;
677             }
678 
679             if (found) {
680                 word = ngx_array_push(cf->args);
681                 if (word == NULL) {
682                     return NGX_ERROR;
683                 }
684 
685                 word->data = ngx_pnalloc(cf->pool, b->pos - start + 1);
686                 if (word->data == NULL) {
687                     return NGX_ERROR;
688                 }
689 
690                 for (dst = word->data, src = start, len = 0;
691                      src < b->pos - 1;
692                      len++)
693                 {
694                     if (*src == '\\') {
695                         switch (src[1]) {
696                         case '"':
697                         case '\'':
698                         case '\\':
699                             src++;
700                             break;
701 
702                         case 't':
703                             *dst++ = '\t';
704                             src += 2;
705                             continue;
706 
707                         case 'r':
708                             *dst++ = '\r';
709                             src += 2;
710                             continue;
711 
712                         case 'n':
713                             *dst++ = '\n';
714                             src += 2;
715                             continue;
716                         }
717 
718                     }
719                     *dst++ = *src++;
720                 }
721                 *dst = '\0';
722                 word->len = len;
723 
724                 if (ch == ';') {
725                     return NGX_OK;
726                 }
727 
728                 if (ch == '{') {
729                     return NGX_CONF_BLOCK_START;
730                 }
731 
732                 found = 0;
733             }
734         }
735     }
736 }
737 
738 
739 static char *
740 ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
741 {
742     char        *rv;
743     ngx_int_t    n;
744     ngx_str_t   *value, file, name;
745     ngx_glob_t   gl;
746 
747     value = cf->args->elts;
748     file = value[1];
749 
750     ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
751 
752     if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
753         return NGX_CONF_ERROR;
754     }
755 
756     if (strpbrk((char *) file.data, "*?[") == NULL) {
757 
758         ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
759 
760         return ngx_conf_parse(cf, &file);
761     }
762 
763     ngx_memzero(&gl, sizeof(ngx_glob_t));
764 
765     gl.pattern = file.data;
766     gl.log = cf->log;
767     gl.test = 1;
768 
769     if (ngx_open_glob(&gl) != NGX_OK) {
770         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
771                            ngx_open_glob_n " \"%s\" failed", file.data);
772         return NGX_CONF_ERROR;
773     }
774 
775     rv = NGX_CONF_OK;
776 
777     for ( ;; ) {
778         n = ngx_read_glob(&gl, &name);
779 
780         if (n != NGX_OK) {
781             break;
782         }
783 
784         file.len = name.len++;
785         file.data = ngx_pstrdup(cf->pool, &name);
786 
787         ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
788 
789         rv = ngx_conf_parse(cf, &file);
790 
791         if (rv != NGX_CONF_OK) {
792             break;
793         }
794     }
795 
796     ngx_close_glob(&gl);
797 
798     return rv;
799 }
800 
801 
802 ngx_int_t
803 ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
804 {
805     size_t      len;
806     u_char     *p, *n, *prefix;
807     ngx_int_t   rc;
808 
809     rc = ngx_conf_test_full_name(name);
810 
811     if (rc == NGX_OK) {
812         return rc;
813     }
814 
815     if (conf_prefix) {
816         len = cycle->conf_prefix.len;
817         prefix = cycle->conf_prefix.data;
818 
819     } else {
820         len = cycle->prefix.len;
821         prefix = cycle->prefix.data;
822     }
823 
824 #if (NGX_WIN32)
825 
826     if (rc == 2) {
827         len = rc;
828     }
829 
830 #endif
831 
832     n = ngx_pnalloc(cycle->pool, len + name->len + 1);
833     if (n == NULL) {
834         return NGX_ERROR;
835     }
836 
837     p = ngx_cpymem(n, prefix, len);
838     ngx_cpystrn(p, name->data, name->len + 1);
839 
840     name->len += len;
841     name->data = n;
842 
843     return NGX_OK;
844 }
845 
846 
847 static ngx_int_t
848 ngx_conf_test_full_name(ngx_str_t *name)
849 {
850 #if (NGX_WIN32)
851     u_char  c0, c1;
852 
853     c0 = name->data[0];
854 
855     if (name->len < 2) {
856         if (c0 == '/') {
857             return 2;
858         }
859 
860         return NGX_DECLINED;
861     }
862 
863     c1 = name->data[1];
864 
865     if (c1 == ':') {
866         c0 |= 0x20;
867 
868         if ((c0 >= 'a' && c0 <= 'z')) {
869             return NGX_OK;
870         }
871 
872         return NGX_DECLINED;
873     }
874 
875     if (c1 == '/') {
876         return NGX_OK;
877     }
878 
879     if (c0 == '/') {
880         return 2;
881     }
882 
883     return NGX_DECLINED;
884 
885 #else
886 
887     if (name->data[0] == '/') {
888         return NGX_OK;
889     }
890 
891     return NGX_DECLINED;
892 
893 #endif
894 }
895 
896 
897 ngx_open_file_t *
898 ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
899 {
900     ngx_str_t         full;
901     ngx_uint_t        i;
902     ngx_list_part_t  *part;
903     ngx_open_file_t  *file;
904 
905 #if (NGX_SUPPRESS_WARN)
906     full.len = 0;
907     full.data = NULL;
908 #endif
909 
910     if (name->len) {
911         full = *name;
912 
913         if (ngx_conf_full_name(cycle, &full, 0) != NGX_OK) {
914             return NULL;
915         }
916 
917         part = &cycle->open_files.part;
918         file = part->elts;
919 
920         for (i = 0; /* void */ ; i++) {
921 
922             if (i >= part->nelts) {
923                 if (part->next == NULL) {
924                     break;
925                 }
926                 part = part->next;
927                 file = part->elts;
928                 i = 0;
929             }
930 
931             if (full.len != file[i].name.len) {
932                 continue;
933             }
934 
935             if (ngx_strcmp(full.data, file[i].name.data) == 0) {
936                 return &file[i];
937             }
938         }
939     }
940 
941     file = ngx_list_push(&cycle->open_files);
942     if (file == NULL) {
943         return NULL;
944     }
945 
946     if (name->len) {
947         file->fd = NGX_INVALID_FILE;
948         file->name = full;
949 
950     } else {
951         file->fd = ngx_stderr;
952         file->name = *name;
953     }
954 
955     file->buffer = NULL;
956 
957     return file;
958 }
959 
960 
961 static void
962 ngx_conf_flush_files(ngx_cycle_t *cycle)
963 {
964     ssize_t           n, len;
965     ngx_uint_t        i;
966     ngx_list_part_t  *part;
967     ngx_open_file_t  *file;
968 
969     ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "flush files");
970 
971     part = &cycle->open_files.part;
972     file = part->elts;
973 
974     for (i = 0; /* void */ ; i++) {
975 
976         if (i >= part->nelts) {
977             if (part->next == NULL) {
978                 break;
979             }
980             part = part->next;
981             file = part->elts;
982             i = 0;
983         }
984 
985         len = file[i].pos - file[i].buffer;
986 
987         if (file[i].buffer == NULL || len == 0) {
988             continue;
989         }
990 
991         n = ngx_write_fd(file[i].fd, file[i].buffer, len);
992 
993         if (n == NGX_FILE_ERROR) {
994             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
995                           ngx_write_fd_n " to \"%s\" failed",
996                           file[i].name.data);
997 
998         } else if (n != len) {
999             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
1000                           ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
1001                           file[i].name.data, n, len);
1002         }
1003     }
1004 }
1005 
1006 
1007 void ngx_cdecl
1008 ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf, ngx_err_t err,
1009     char *fmt, ...)
1010 {
1011     u_char   errstr[NGX_MAX_CONF_ERRSTR], *p, *last;
1012     va_list  args;
1013 
1014     last = errstr + NGX_MAX_CONF_ERRSTR;
1015 
1016     va_start(args, fmt);
1017     p = ngx_vslprintf(errstr, last, fmt, args);
1018     va_end(args);
1019 
1020     if (err) {
1021         p = ngx_log_errno(p, last, err);
1022     }
1023 
1024     if (cf->conf_file == NULL) {
1025         ngx_log_error(level, cf->log, 0, "%*s", p - errstr, errstr);
1026         return;
1027     }
1028 
1029     if (cf->conf_file->file.fd == NGX_INVALID_FILE) {
1030         ngx_log_error(level, cf->log, 0, "%*s in command line",
1031                       p - errstr, errstr);
1032         return;
1033     }
1034 
1035     ngx_log_error(level, cf->log, 0, "%*s in %s:%ui",
1036                   p - errstr, errstr,
1037                   cf->conf_file->file.name.data, cf->conf_file->line);
1038 }
1039 
1040 
1041 char *
1042 ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1043 {
1044     char  *p = conf;
1045 
1046     ngx_str_t        *value;
1047     ngx_flag_t       *fp;
1048     ngx_conf_post_t  *post;
1049 
1050     fp = (ngx_flag_t *) (p + cmd->offset);
1051 
1052     if (*fp != NGX_CONF_UNSET) {
1053         return "is duplicate";
1054     }
1055 
1056     value = cf->args->elts;
1057 
1058     if (ngx_strcasecmp(value[1].data, (u_char *) "on") == 0) {
1059         *fp = 1;
1060 
1061     } else if (ngx_strcasecmp(value[1].data, (u_char *) "off") == 0) {
1062         *fp = 0;
1063 
1064     } else {
1065         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1066                      "invalid value \"%s\" in \"%s\" directive, "
1067                      "it must be \"on\" or \"off\"",
1068                      value[1].data, cmd->name.data);
1069         return NGX_CONF_ERROR;
1070     }
1071 
1072     if (cmd->post) {
1073         post = cmd->post;
1074         return post->post_handler(cf, post, fp);
1075     }
1076 
1077     return NGX_CONF_OK;
1078 }
1079 
1080 
1081 char *
1082 ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1083 {
1084     char  *p = conf;
1085 
1086     ngx_str_t        *field, *value;
1087     ngx_conf_post_t  *post;
1088 
1089     field = (ngx_str_t *) (p + cmd->offset);
1090 
1091     if (field->data) {
1092         return "is duplicate";
1093     }
1094 
1095     value = cf->args->elts;
1096 
1097     *field = value[1];
1098 
1099     if (cmd->post) {
1100         post = cmd->post;
1101         return post->post_handler(cf, post, field);
1102     }
1103 
1104     return NGX_CONF_OK;
1105 }
1106 
1107 
1108 char *
1109 ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1110 {
1111     char  *p = conf;
1112 
1113     ngx_str_t         *value, *s;
1114     ngx_array_t      **a;
1115     ngx_conf_post_t   *post;
1116 
1117     a = (ngx_array_t **) (p + cmd->offset);
1118 
1119     if (*a == NGX_CONF_UNSET_PTR) {
1120         *a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
1121         if (*a == NULL) {
1122             return NGX_CONF_ERROR;
1123         }
1124     }
1125 
1126     s = ngx_array_push(*a);
1127     if (s == NULL) {
1128         return NGX_CONF_ERROR;
1129     }
1130 
1131     value = cf->args->elts;
1132 
1133     *s = value[1];
1134 
1135     if (cmd->post) {
1136         post = cmd->post;
1137         return post->post_handler(cf, post, s);
1138     }
1139 
1140     return NGX_CONF_OK;
1141 }
1142 
1143 
1144 char *
1145 ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1146 {
1147     char  *p = conf;
1148 
1149     ngx_str_t         *value;
1150     ngx_array_t      **a;
1151     ngx_keyval_t      *kv;
1152     ngx_conf_post_t   *post;
1153 
1154     a = (ngx_array_t **) (p + cmd->offset);
1155 
1156     if (*a == NULL) {
1157         *a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
1158         if (*a == NULL) {
1159             return NGX_CONF_ERROR;
1160         }
1161     }
1162 
1163     kv = ngx_array_push(*a);
1164     if (kv == NULL) {
1165         return NGX_CONF_ERROR;
1166     }
1167 
1168     value = cf->args->elts;
1169 
1170     kv->key = value[1];
1171     kv->value = value[2];
1172 
1173     if (cmd->post) {
1174         post = cmd->post;
1175         return post->post_handler(cf, post, kv);
1176     }
1177 
1178     return NGX_CONF_OK;
1179 }
1180 
1181 
1182 char *
1183 ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1184 {
1185     char  *p = conf;
1186 
1187     ngx_int_t        *np;
1188     ngx_str_t        *value;
1189     ngx_conf_post_t  *post;
1190 
1191 
1192     np = (ngx_int_t *) (p + cmd->offset);
1193 
1194     if (*np != NGX_CONF_UNSET) {
1195         return "is duplicate";
1196     }
1197 
1198     value = cf->args->elts;
1199     *np = ngx_atoi(value[1].data, value[1].len);
1200     if (*np == NGX_ERROR) {
1201         return "invalid number";
1202     }
1203 
1204     if (cmd->post) {
1205         post = cmd->post;
1206         return post->post_handler(cf, post, np);
1207     }
1208 
1209     return NGX_CONF_OK;
1210 }
1211 
1212 
1213 char *
1214 ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1215 {
1216     char  *p = conf;
1217 
1218     size_t           *sp;
1219     ngx_str_t        *value;
1220     ngx_conf_post_t  *post;
1221 
1222 
1223     sp = (size_t *) (p + cmd->offset);
1224     if (*sp != NGX_CONF_UNSET_SIZE) {
1225         return "is duplicate";
1226     }
1227 
1228     value = cf->args->elts;
1229 
1230     *sp = ngx_parse_size(&value[1]);
1231     if (*sp == (size_t) NGX_ERROR) {
1232         return "invalid value";
1233     }
1234 
1235     if (cmd->post) {
1236         post = cmd->post;
1237         return post->post_handler(cf, post, sp);
1238     }
1239 
1240     return NGX_CONF_OK;
1241 }
1242 
1243 
1244 char *
1245 ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1246 {
1247     char  *p = conf;
1248 
1249     off_t            *op;
1250     ngx_str_t        *value;
1251     ngx_conf_post_t  *post;
1252 
1253 
1254     op = (off_t *) (p + cmd->offset);
1255     if (*op != NGX_CONF_UNSET) {
1256         return "is duplicate";
1257     }
1258 
1259     value = cf->args->elts;
1260 
1261     *op = ngx_parse_offset(&value[1]);
1262     if (*op == (off_t) NGX_ERROR) {
1263         return "invalid value";
1264     }
1265 
1266     if (cmd->post) {
1267         post = cmd->post;
1268         return post->post_handler(cf, post, op);
1269     }
1270 
1271     return NGX_CONF_OK;
1272 }
1273 
1274 
1275 char *
1276 ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1277 {
1278     char  *p = conf;
1279 
1280     ngx_msec_t       *msp;
1281     ngx_str_t        *value;
1282     ngx_conf_post_t  *post;
1283 
1284 
1285     msp = (ngx_msec_t *) (p + cmd->offset);
1286     if (*msp != NGX_CONF_UNSET_MSEC) {
1287         return "is duplicate";
1288     }
1289 
1290     value = cf->args->elts;
1291 
1292     *msp = ngx_parse_time(&value[1], 0);
1293     if (*msp == (ngx_msec_t) NGX_ERROR) {
1294         return "invalid value";
1295     }
1296 
1297     if (*msp == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
1298         return "value must be less than 597 hours";
1299     }
1300 
1301     if (cmd->post) {
1302         post = cmd->post;
1303         return post->post_handler(cf, post, msp);
1304     }
1305 
1306     return NGX_CONF_OK;
1307 }
1308 
1309 
1310 char *
1311 ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1312 {
1313     char  *p = conf;
1314 
1315     time_t           *sp;
1316     ngx_str_t        *value;
1317     ngx_conf_post_t  *post;
1318 
1319 
1320     sp = (time_t *) (p + cmd->offset);
1321     if (*sp != NGX_CONF_UNSET) {
1322         return "is duplicate";
1323     }
1324 
1325     value = cf->args->elts;
1326 
1327     *sp = ngx_parse_time(&value[1], 1);
1328     if (*sp == NGX_ERROR) {
1329         return "invalid value";
1330     }
1331 
1332     if (*sp == NGX_PARSE_LARGE_TIME) {
1333         return "value must be less than 68 years";
1334     }
1335 
1336     if (cmd->post) {
1337         post = cmd->post;
1338         return post->post_handler(cf, post, sp);
1339     }
1340 
1341     return NGX_CONF_OK;
1342 }
1343 
1344 
1345 char *
1346 ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1347 {
1348     char *p = conf;
1349 
1350     ngx_str_t   *value;
1351     ngx_bufs_t  *bufs;
1352 
1353 
1354     bufs = (ngx_bufs_t *) (p + cmd->offset);
1355     if (bufs->num) {
1356         return "is duplicate";
1357     }
1358 
1359     value = cf->args->elts;
1360 
1361     bufs->num = ngx_atoi(value[1].data, value[1].len);
1362     if (bufs->num == NGX_ERROR || bufs->num == 0) {
1363         return "invalid value";
1364     }
1365 
1366     bufs->size = ngx_parse_size(&value[2]);
1367     if (bufs->size == (size_t) NGX_ERROR || bufs->size == 0) {
1368         return "invalid value";
1369     }
1370 
1371     return NGX_CONF_OK;
1372 }
1373 
1374 
1375 char *
1376 ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1377 {
1378     char  *p = conf;
1379 
1380     ngx_uint_t       *np, i;
1381     ngx_str_t        *value;
1382     ngx_conf_enum_t  *e;
1383 
1384     np = (ngx_uint_t *) (p + cmd->offset);
1385 
1386     if (*np != NGX_CONF_UNSET_UINT) {
1387         return "is duplicate";
1388     }
1389 
1390     value = cf->args->elts;
1391     e = cmd->post;
1392 
1393     for (i = 0; e[i].name.len != 0; i++) {
1394         if (e[i].name.len != value[1].len
1395             || ngx_strcasecmp(e[i].name.data, value[1].data) != 0)
1396         {
1397             continue;
1398         }
1399 
1400         *np = e[i].value;
1401 
1402         return NGX_CONF_OK;
1403     }
1404 
1405     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1406                        "invalid value \"%s\"", value[1].data);
1407 
1408     return NGX_CONF_ERROR;
1409 }
1410 
1411 
1412 char *
1413 ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1414 {
1415     char  *p = conf;
1416 
1417     ngx_uint_t          *np, i, m;
1418     ngx_str_t           *value;
1419     ngx_conf_bitmask_t  *mask;
1420 
1421 
1422     np = (ngx_uint_t *) (p + cmd->offset);
1423     value = cf->args->elts;
1424     mask = cmd->post;
1425 
1426     for (i = 1; i < cf->args->nelts; i++) {
1427         for (m = 0; mask[m].name.len != 0; m++) {
1428 
1429             if (mask[m].name.len != value[i].len
1430                 || ngx_strcasecmp(mask[m].name.data, value[i].data) != 0)
1431             {
1432                 continue;
1433             }
1434 
1435             if (*np & mask[m].mask) {
1436                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1437                                    "duplicate value \"%s\"", value[i].data);
1438 
1439             } else {
1440                 *np |= mask[m].mask;
1441             }
1442 
1443             break;
1444         }
1445 
1446         if (mask[m].name.len == 0) {
1447             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1448                                "invalid value \"%s\"", value[i].data);
1449 
1450             return NGX_CONF_ERROR;
1451         }
1452     }
1453 
1454     return NGX_CONF_OK;
1455 }
1456 
1457 
1458 char *
1459 ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1460 {
1461     return "unsupported on this platform";
1462 }
1463 
1464 
1465 char *
1466 ngx_conf_deprecated(ngx_conf_t *cf, void *post, void *data)
1467 {
1468     ngx_conf_deprecated_t  *d = post;
1469 
1470     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1471                        "the \"%s\" directive is deprecated, "
1472                        "use the \"%s\" directive instead",
1473                        d->old_name, d->new_name);
1474 
1475     return NGX_CONF_OK;
1476 }
1477 
1478 
1479 char *
1480 ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data)
1481 {
1482     ngx_conf_num_bounds_t  *bounds = post;
1483     ngx_int_t  *np = data;
1484 
1485     if (bounds->high == -1) {
1486         if (*np >= bounds->low) {
1487             return NGX_CONF_OK;
1488         }
1489 
1490         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1491                            "value must be equal or more than %i", bounds->low);
1492 
1493         return NGX_CONF_ERROR;
1494     }
1495 
1496     if (*np >= bounds->low && *np <= bounds->high) {
1497         return NGX_CONF_OK;
1498     }
1499 
1500     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1501                        "value must be between %i and %i",
1502                        bounds->low, bounds->high);
1503 
1504     return NGX_CONF_ERROR;
1505 }
1506 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.