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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值