Annotation of embedaddon/nginx/src/core/ngx_conf_file.c, revision 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>