Annotation of embedaddon/nginx/src/core/ngx_conf_file.c, revision 1.1.1.1

1.1       misho       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"),
                     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) == NGX_FILE_ERROR) {
                    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:                           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) {
                    324:                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    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) {
                    331:                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    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: 
                    397:             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    398:                                "\"%s\" directive %s", name->data, rv);
                    399: 
                    400:             return NGX_ERROR;
                    401:         }
                    402:     }
                    403: 
                    404:     if (found) {
                    405:         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    406:                            "\"%s\" directive is not allowed here", name->data);
                    407: 
                    408:         return NGX_ERROR;
                    409:     }
                    410: 
                    411:     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    412:                        "unknown directive \"%s\"", name->data);
                    413: 
                    414:     return NGX_ERROR;
                    415: 
                    416: invalid:
                    417: 
                    418:     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    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) {
                    463:                         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    464:                                            "unexpected end of parameter, "
                    465:                                            "expecting \";\"");
                    466:                         return NGX_ERROR;
                    467:                     }
                    468: 
                    469:                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    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 {
                    490:                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    491:                                        "too long parameter \"%*s...\" started",
                    492:                                        10, start);
                    493:                     return NGX_ERROR;
                    494:                 }
                    495: 
                    496:                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    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) {
                    520:                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    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 {
                    571:                  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                    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) {
                    590:                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 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) {
                    603:                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 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 *
                    734: ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                    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) {
                    764:         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
                    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
                    797: ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
                    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: 
                    891: ngx_open_file_t *
                    892: ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
                    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
                    986: ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf, ngx_err_t err,
                    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 *
                   1020: ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 {
                   1043:         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                   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 *
                   1060: ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 *
                   1087: ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 *
                   1123: ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 *
                   1161: ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 *
                   1192: ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 *
                   1223: ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 *
                   1254: ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 *
                   1285: ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 *
                   1316: ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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 *
                   1346: ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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: 
                   1375:     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                   1376:                        "invalid value \"%s\"", value[1].data);
                   1377: 
                   1378:     return NGX_CONF_ERROR;
                   1379: }
                   1380: 
                   1381: 
                   1382: char *
                   1383: ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
                   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) {
                   1406:                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                   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) {
                   1417:             ngx_conf_log_error(NGX_LOG_WARN, cf, 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: 
                   1444:     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                   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: 
                   1464:         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                   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: 
                   1475:     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                   1476:                        "value must be between %i and %i",
                   1477:                        bounds->low, bounds->high);
                   1478: 
                   1479:     return NGX_CONF_ERROR;
                   1480: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>