Annotation of embedaddon/lighttpd/src/configfile-glue.c, revision 1.1

1.1     ! misho       1: #include "base.h"
        !             2: #include "buffer.h"
        !             3: #include "array.h"
        !             4: #include "log.h"
        !             5: #include "plugin.h"
        !             6: 
        !             7: #include "configfile.h"
        !             8: 
        !             9: #include <string.h>
        !            10: #include <stdlib.h>
        !            11: 
        !            12: /**
        !            13:  * like all glue code this file contains functions which
        !            14:  * are the external interface of lighttpd. The functions
        !            15:  * are used by the server itself and the plugins.
        !            16:  *
        !            17:  * The main-goal is to have a small library in the end
        !            18:  * which is linked against both and which will define
        !            19:  * the interface itself in the end.
        !            20:  *
        !            21:  */
        !            22: 
        !            23: 
        !            24: /* handle global options */
        !            25: 
        !            26: /* parse config array */
        !            27: int config_insert_values_internal(server *srv, array *ca, const config_values_t cv[]) {
        !            28:        size_t i;
        !            29:        data_unset *du;
        !            30: 
        !            31:        for (i = 0; cv[i].key; i++) {
        !            32: 
        !            33:                if (NULL == (du = array_get_element(ca, cv[i].key))) {
        !            34:                        /* no found */
        !            35: 
        !            36:                        continue;
        !            37:                }
        !            38: 
        !            39:                switch (cv[i].type) {
        !            40:                case T_CONFIG_ARRAY:
        !            41:                        if (du->type == TYPE_ARRAY) {
        !            42:                                size_t j;
        !            43:                                data_array *da = (data_array *)du;
        !            44: 
        !            45:                                for (j = 0; j < da->value->used; j++) {
        !            46:                                        if (da->value->data[j]->type == TYPE_STRING) {
        !            47:                                                data_string *ds = data_string_init();
        !            48: 
        !            49:                                                buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value);
        !            50:                                                if (!da->is_index_key) {
        !            51:                                                        /* the id's were generated automaticly, as we copy now we might have to renumber them
        !            52:                                                         * this is used to prepend server.modules by mod_indexfile as it has to be loaded
        !            53:                                                         * before mod_fastcgi and friends */
        !            54:                                                        buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key);
        !            55:                                                }
        !            56: 
        !            57:                                                array_insert_unique(cv[i].destination, (data_unset *)ds);
        !            58:                                        } else {
        !            59:                                                log_error_write(srv, __FILE__, __LINE__, "sssd",
        !            60:                                                                "the key of an array can only be a string or a integer, variable:",
        !            61:                                                                cv[i].key, "type:", da->value->data[j]->type);
        !            62: 
        !            63:                                                return -1;
        !            64:                                        }
        !            65:                                }
        !            66:                        } else {
        !            67:                                log_error_write(srv, __FILE__, __LINE__, "ss", cv[i].key, "should have been a array of strings like ... = ( \"...\" )");
        !            68: 
        !            69:                                return -1;
        !            70:                        }
        !            71:                        break;
        !            72:                case T_CONFIG_STRING:
        !            73:                        if (du->type == TYPE_STRING) {
        !            74:                                data_string *ds = (data_string *)du;
        !            75: 
        !            76:                                buffer_copy_string_buffer(cv[i].destination, ds->value);
        !            77:                        } else {
        !            78:                                log_error_write(srv, __FILE__, __LINE__, "ssss", cv[i].key, "should have been a string like ... = \"...\"");
        !            79: 
        !            80:                                return -1;
        !            81:                        }
        !            82:                        break;
        !            83:                case T_CONFIG_SHORT:
        !            84:                        switch(du->type) {
        !            85:                        case TYPE_INTEGER: {
        !            86:                                data_integer *di = (data_integer *)du;
        !            87: 
        !            88:                                *((unsigned short *)(cv[i].destination)) = di->value;
        !            89:                                break;
        !            90:                        }
        !            91:                        case TYPE_STRING: {
        !            92:                                data_string *ds = (data_string *)du;
        !            93: 
        !            94:                                /* If the value came from an environment variable, then it is a
        !            95:                                 * data_string, although it may contain a number in ASCII
        !            96:                                 * decimal format.  We try to interpret the string as a decimal
        !            97:                                 * short before giving up, in order to support setting numeric
        !            98:                                 * values with environment variables (eg, port number).
        !            99:                                 */
        !           100:                                if (ds->value->ptr && *ds->value->ptr) {
        !           101:                                        char *e;
        !           102:                                        long l = strtol(ds->value->ptr, &e, 10);
        !           103:                                        if (e != ds->value->ptr && !*e && l >=0 && l <= 65535) {
        !           104:                                                *((unsigned short *)(cv[i].destination)) = l;
        !           105:                                                break;
        !           106:                                        }
        !           107:                                }
        !           108: 
        !           109:                                log_error_write(srv, __FILE__, __LINE__, "ssb", "got a string but expected a short:", cv[i].key, ds->value);
        !           110: 
        !           111:                                return -1;
        !           112:                        }
        !           113:                        default:
        !           114:                                log_error_write(srv, __FILE__, __LINE__, "ssds", "unexpected type for key:", cv[i].key, du->type, "expected a short integer, range 0 ... 65535");
        !           115:                                return -1;
        !           116:                        }
        !           117:                        break;
        !           118:                case T_CONFIG_INT:
        !           119:                        switch(du->type) {
        !           120:                        case TYPE_INTEGER: {
        !           121:                                data_integer *di = (data_integer *)du;
        !           122: 
        !           123:                                *((unsigned int *)(cv[i].destination)) = di->value;
        !           124:                                break;
        !           125:                        }
        !           126:                        case TYPE_STRING: {
        !           127:                                data_string *ds = (data_string *)du;
        !           128: 
        !           129:                                if (ds->value->ptr && *ds->value->ptr) {
        !           130:                                        char *e;
        !           131:                                        long l = strtol(ds->value->ptr, &e, 10);
        !           132:                                        if (e != ds->value->ptr && !*e && l >= 0) {
        !           133:                                                *((unsigned int *)(cv[i].destination)) = l;
        !           134:                                                break;
        !           135:                                        }
        !           136:                                }
        !           137: 
        !           138: 
        !           139:                                log_error_write(srv, __FILE__, __LINE__, "ssb", "got a string but expected an integer:", cv[i].key, ds->value);
        !           140: 
        !           141:                                return -1;
        !           142:                        }
        !           143:                        default:
        !           144:                                log_error_write(srv, __FILE__, __LINE__, "ssds", "unexpected type for key:", cv[i].key, du->type, "expected an integer, range 0 ... 4294967295");
        !           145:                                return -1;
        !           146:                        }
        !           147:                        break;
        !           148:                case T_CONFIG_BOOLEAN:
        !           149:                        if (du->type == TYPE_STRING) {
        !           150:                                data_string *ds = (data_string *)du;
        !           151: 
        !           152:                                if (buffer_is_equal_string(ds->value, CONST_STR_LEN("enable"))) {
        !           153:                                        *((unsigned short *)(cv[i].destination)) = 1;
        !           154:                                } else if (buffer_is_equal_string(ds->value, CONST_STR_LEN("disable"))) {
        !           155:                                        *((unsigned short *)(cv[i].destination)) = 0;
        !           156:                                } else {
        !           157:                                        log_error_write(srv, __FILE__, __LINE__, "ssbs", "ERROR: unexpected value for key:", cv[i].key, ds->value, "(enable|disable)");
        !           158: 
        !           159:                                        return -1;
        !           160:                                }
        !           161:                        } else {
        !           162:                                log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: unexpected type for key:", cv[i].key, "(string)", "\"(enable|disable)\"");
        !           163: 
        !           164:                                return -1;
        !           165:                        }
        !           166:                        break;
        !           167:                case T_CONFIG_LOCAL:
        !           168:                case T_CONFIG_UNSET:
        !           169:                        break;
        !           170:                case T_CONFIG_UNSUPPORTED:
        !           171:                        log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found unsupported key:", cv[i].key, "-", (char *)(cv[i].destination));
        !           172: 
        !           173:                        srv->config_unsupported = 1;
        !           174: 
        !           175:                        break;
        !           176:                case T_CONFIG_DEPRECATED:
        !           177:                        log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found deprecated key:", cv[i].key, "-", (char *)(cv[i].destination));
        !           178: 
        !           179:                        srv->config_deprecated = 1;
        !           180: 
        !           181:                        break;
        !           182:                }
        !           183:        }
        !           184: 
        !           185:        return 0;
        !           186: }
        !           187: 
        !           188: int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) {
        !           189:        size_t i;
        !           190:        data_unset *du;
        !           191: 
        !           192:        for (i = 0; cv[i].key; i++) {
        !           193:                data_string *touched;
        !           194: 
        !           195:                if (NULL == (du = array_get_element(ca, cv[i].key))) {
        !           196:                        /* no found */
        !           197: 
        !           198:                        continue;
        !           199:                }
        !           200: 
        !           201:                /* touched */
        !           202:                touched = data_string_init();
        !           203: 
        !           204:                buffer_copy_string_len(touched->value, CONST_STR_LEN(""));
        !           205:                buffer_copy_string_buffer(touched->key, du->key);
        !           206: 
        !           207:                array_insert_unique(srv->config_touched, (data_unset *)touched);
        !           208:        }
        !           209: 
        !           210:        return config_insert_values_internal(srv, ca, cv);
        !           211: }
        !           212: 
        !           213: static unsigned short sock_addr_get_port(sock_addr *addr) {
        !           214: #ifdef HAVE_IPV6
        !           215:        return ntohs(addr->plain.sa_family ? addr->ipv6.sin6_port : addr->ipv4.sin_port);
        !           216: #else
        !           217:        return ntohs(addr->ipv4.sin_port);
        !           218: #endif
        !           219: }
        !           220: 
        !           221: static cond_result_t config_check_cond_cached(server *srv, connection *con, data_config *dc);
        !           222: 
        !           223: static cond_result_t config_check_cond_nocache(server *srv, connection *con, data_config *dc) {
        !           224:        buffer *l;
        !           225:        server_socket *srv_sock = con->srv_socket;
        !           226: 
        !           227:        /* check parent first */
        !           228:        if (dc->parent && dc->parent->context_ndx) {
        !           229:                /**
        !           230:                 * a nested conditional 
        !           231:                 *
        !           232:                 * if the parent is not decided yet or false, we can't be true either 
        !           233:                 */
        !           234:                if (con->conf.log_condition_handling) {
        !           235:                        log_error_write(srv, __FILE__, __LINE__,  "sb", "go parent", dc->parent->key);
        !           236:                }
        !           237: 
        !           238:                switch (config_check_cond_cached(srv, con, dc->parent)) {
        !           239:                case COND_RESULT_FALSE:
        !           240:                        return COND_RESULT_FALSE;
        !           241:                case COND_RESULT_UNSET:
        !           242:                        return COND_RESULT_UNSET;
        !           243:                default:
        !           244:                        break;
        !           245:                }
        !           246:        }
        !           247: 
        !           248:        if (dc->prev) {
        !           249:                /**
        !           250:                 * a else branch
        !           251:                 *
        !           252:                 * we can only be executed, if all of our previous brothers 
        !           253:                 * are false
        !           254:                 */
        !           255:                if (con->conf.log_condition_handling) {
        !           256:                        log_error_write(srv, __FILE__, __LINE__,  "sb", "go prev", dc->prev->key);
        !           257:                }
        !           258: 
        !           259:                /* make sure prev is checked first */
        !           260:                config_check_cond_cached(srv, con, dc->prev);
        !           261: 
        !           262:                /* one of prev set me to FALSE */
        !           263:                switch (con->cond_cache[dc->context_ndx].result) {
        !           264:                case COND_RESULT_FALSE:
        !           265:                        return con->cond_cache[dc->context_ndx].result;
        !           266:                default:
        !           267:                        break;
        !           268:                }
        !           269:        }
        !           270: 
        !           271:        if (!con->conditional_is_valid[dc->comp]) {
        !           272:                if (con->conf.log_condition_handling) {
        !           273:                        log_error_write(srv, __FILE__, __LINE__,  "dss", 
        !           274:                                dc->comp,
        !           275:                                dc->key->ptr,
        !           276:                                con->conditional_is_valid[dc->comp] ? "yeah" : "nej");
        !           277:                }
        !           278: 
        !           279:                return COND_RESULT_UNSET;
        !           280:        }
        !           281: 
        !           282:        /* pass the rules */
        !           283: 
        !           284:        switch (dc->comp) {
        !           285:        case COMP_HTTP_HOST: {
        !           286:                char *ck_colon = NULL, *val_colon = NULL;
        !           287: 
        !           288:                if (!buffer_is_empty(con->uri.authority)) {
        !           289: 
        !           290:                        /*
        !           291:                         * append server-port to the HTTP_POST if necessary
        !           292:                         */
        !           293: 
        !           294:                        l = con->uri.authority;
        !           295: 
        !           296:                        switch(dc->cond) {
        !           297:                        case CONFIG_COND_NE:
        !           298:                        case CONFIG_COND_EQ:
        !           299:                                ck_colon = strchr(dc->string->ptr, ':');
        !           300:                                val_colon = strchr(l->ptr, ':');
        !           301: 
        !           302:                                if (NULL != ck_colon && NULL == val_colon) {
        !           303:                                        /* condition "host:port" but client send "host" */
        !           304:                                        buffer_copy_string_buffer(srv->cond_check_buf, l);
        !           305:                                        buffer_append_string_len(srv->cond_check_buf, CONST_STR_LEN(":"));
        !           306:                                        buffer_append_long(srv->cond_check_buf, sock_addr_get_port(&(srv_sock->addr)));
        !           307:                                        l = srv->cond_check_buf;
        !           308:                                } else if (NULL != val_colon && NULL == ck_colon) {
        !           309:                                        /* condition "host" but client send "host:port" */
        !           310:                                        buffer_copy_string_len(srv->cond_check_buf, l->ptr, val_colon - l->ptr);
        !           311:                                        l = srv->cond_check_buf;
        !           312:                                }
        !           313:                                break;
        !           314:                        default:
        !           315:                                break;
        !           316:                        }
        !           317: #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT
        !           318:                } else if (!buffer_is_empty(con->tlsext_server_name)) {
        !           319:                        l = con->tlsext_server_name;
        !           320: #endif
        !           321:                } else {
        !           322:                        l = srv->empty_string;
        !           323:                }
        !           324:                break;
        !           325:        }
        !           326:        case COMP_HTTP_REMOTE_IP: {
        !           327:                char *nm_slash;
        !           328:                /* handle remoteip limitations
        !           329:                 *
        !           330:                 * "10.0.0.1" is provided for all comparisions
        !           331:                 *
        !           332:                 * only for == and != we support
        !           333:                 *
        !           334:                 * "10.0.0.1/24"
        !           335:                 */
        !           336: 
        !           337:                if ((dc->cond == CONFIG_COND_EQ ||
        !           338:                     dc->cond == CONFIG_COND_NE) &&
        !           339:                    (con->dst_addr.plain.sa_family == AF_INET) &&
        !           340:                    (NULL != (nm_slash = strchr(dc->string->ptr, '/')))) {
        !           341:                        int nm_bits;
        !           342:                        long nm;
        !           343:                        char *err;
        !           344:                        struct in_addr val_inp;
        !           345: 
        !           346:                        if (*(nm_slash+1) == '\0') {
        !           347:                                log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string);
        !           348: 
        !           349:                                return COND_RESULT_FALSE;
        !           350:                        }
        !           351: 
        !           352:                        nm_bits = strtol(nm_slash + 1, &err, 10);
        !           353: 
        !           354:                        if (*err) {
        !           355:                                log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: non-digit found in netmask:", dc->string, err);
        !           356: 
        !           357:                                return COND_RESULT_FALSE;
        !           358:                        }
        !           359: 
        !           360:                        /* take IP convert to the native */
        !           361:                        buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr);
        !           362: #ifdef __WIN32
        !           363:                        if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) {
        !           364:                                log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);
        !           365: 
        !           366:                                return COND_RESULT_FALSE;
        !           367:                        }
        !           368: 
        !           369: #else
        !           370:                        if (0 == inet_aton(srv->cond_check_buf->ptr, &val_inp)) {
        !           371:                                log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf);
        !           372: 
        !           373:                                return COND_RESULT_FALSE;
        !           374:                        }
        !           375: #endif
        !           376: 
        !           377:                        /* build netmask */
        !           378:                        nm = htonl(~((1 << (32 - nm_bits)) - 1));
        !           379: 
        !           380:                        if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) {
        !           381:                                return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
        !           382:                        } else {
        !           383:                                return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_FALSE : COND_RESULT_TRUE;
        !           384:                        }
        !           385:                } else {
        !           386:                        l = con->dst_addr_buf;
        !           387:                }
        !           388:                break;
        !           389:        }
        !           390:        case COMP_HTTP_SCHEME:
        !           391:                l = con->uri.scheme;
        !           392:                break;
        !           393: 
        !           394:        case COMP_HTTP_URL:
        !           395:                l = con->uri.path;
        !           396:                break;
        !           397: 
        !           398:        case COMP_HTTP_QUERY_STRING:
        !           399:                l = con->uri.query;
        !           400:                break;
        !           401: 
        !           402:        case COMP_SERVER_SOCKET:
        !           403:                l = srv_sock->srv_token;
        !           404:                break;
        !           405: 
        !           406:        case COMP_HTTP_REFERER: {
        !           407:                data_string *ds;
        !           408: 
        !           409:                if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) {
        !           410:                        l = ds->value;
        !           411:                } else {
        !           412:                        l = srv->empty_string;
        !           413:                }
        !           414:                break;
        !           415:        }
        !           416:        case COMP_HTTP_COOKIE: {
        !           417:                data_string *ds;
        !           418:                if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) {
        !           419:                        l = ds->value;
        !           420:                } else {
        !           421:                        l = srv->empty_string;
        !           422:                }
        !           423:                break;
        !           424:        }
        !           425:        case COMP_HTTP_USER_AGENT: {
        !           426:                data_string *ds;
        !           427:                if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "User-Agent"))) {
        !           428:                        l = ds->value;
        !           429:                } else {
        !           430:                        l = srv->empty_string;
        !           431:                }
        !           432:                break;
        !           433:        }
        !           434:        case COMP_HTTP_REQUEST_METHOD: {
        !           435:                const char *method = get_http_method_name(con->request.http_method);
        !           436: 
        !           437:                /* we only have the request method as const char but we need a buffer for comparing */
        !           438: 
        !           439:                buffer_copy_string(srv->tmp_buf, method);
        !           440: 
        !           441:                l = srv->tmp_buf;
        !           442: 
        !           443:                break;
        !           444:        }
        !           445:        case COMP_HTTP_LANGUAGE: {
        !           446:                data_string *ds;
        !           447:                if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Accept-Language"))) {
        !           448:                        l = ds->value;
        !           449:                } else {
        !           450:                        l = srv->empty_string;
        !           451:                }
        !           452:                break;
        !           453:        }
        !           454:        default:
        !           455:                return COND_RESULT_FALSE;
        !           456:        }
        !           457: 
        !           458:        if (NULL == l) {
        !           459:                if (con->conf.log_condition_handling) {
        !           460:                        log_error_write(srv, __FILE__, __LINE__,  "bsbs", dc->comp_key,
        !           461:                                        "(", l, ") compare to NULL");
        !           462:                }
        !           463:                return COND_RESULT_FALSE;
        !           464:        }
        !           465: 
        !           466:        if (con->conf.log_condition_handling) {
        !           467:                log_error_write(srv, __FILE__, __LINE__,  "bsbsb", dc->comp_key,
        !           468:                                "(", l, ") compare to ", dc->string);
        !           469:        }
        !           470:        switch(dc->cond) {
        !           471:        case CONFIG_COND_NE:
        !           472:        case CONFIG_COND_EQ:
        !           473:                if (buffer_is_equal(l, dc->string)) {
        !           474:                        return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
        !           475:                } else {
        !           476:                        return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_FALSE : COND_RESULT_TRUE;
        !           477:                }
        !           478:                break;
        !           479: #ifdef HAVE_PCRE_H
        !           480:        case CONFIG_COND_NOMATCH:
        !           481:        case CONFIG_COND_MATCH: {
        !           482:                cond_cache_t *cache = &con->cond_cache[dc->context_ndx];
        !           483:                int n;
        !           484: 
        !           485: #ifndef elementsof
        !           486: #define elementsof(x) (sizeof(x) / sizeof(x[0]))
        !           487: #endif
        !           488:                n = pcre_exec(dc->regex, dc->regex_study, l->ptr, l->used - 1, 0, 0,
        !           489:                                cache->matches, elementsof(cache->matches));
        !           490: 
        !           491:                cache->patterncount = n;
        !           492:                if (n > 0) {
        !           493:                        cache->comp_value = l;
        !           494:                        cache->comp_type  = dc->comp;
        !           495:                        return (dc->cond == CONFIG_COND_MATCH) ? COND_RESULT_TRUE : COND_RESULT_FALSE;
        !           496:                } else {
        !           497:                        /* cache is already cleared */
        !           498:                        return (dc->cond == CONFIG_COND_MATCH) ? COND_RESULT_FALSE : COND_RESULT_TRUE;
        !           499:                }
        !           500:                break;
        !           501:        }
        !           502: #endif
        !           503:        default:
        !           504:                /* no way */
        !           505:                break;
        !           506:        }
        !           507: 
        !           508:        return COND_RESULT_FALSE;
        !           509: }
        !           510: 
        !           511: static cond_result_t config_check_cond_cached(server *srv, connection *con, data_config *dc) {
        !           512:        cond_cache_t *caches = con->cond_cache;
        !           513: 
        !           514:        if (COND_RESULT_UNSET == caches[dc->context_ndx].result) {
        !           515:                if (COND_RESULT_TRUE == (caches[dc->context_ndx].result = config_check_cond_nocache(srv, con, dc))) {
        !           516:                        if (dc->next) {
        !           517:                                data_config *c;
        !           518:                                if (con->conf.log_condition_handling) {
        !           519:                                        log_error_write(srv, __FILE__, __LINE__, "s",
        !           520:                                                        "setting remains of chaining to false");
        !           521:                                }
        !           522:                                for (c = dc->next; c; c = c->next) {
        !           523:                                        caches[c->context_ndx].result = COND_RESULT_FALSE;
        !           524:                                }
        !           525:                        }
        !           526:                }
        !           527:                caches[dc->context_ndx].comp_type = dc->comp;
        !           528: 
        !           529:                if (con->conf.log_condition_handling) {
        !           530:                        log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
        !           531:                                        "(uncached) result:",
        !           532:                                        caches[dc->context_ndx].result == COND_RESULT_UNSET ? "unknown" :
        !           533:                                                (caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false"));
        !           534:                }
        !           535:        } else {
        !           536:                if (con->conf.log_condition_handling) {
        !           537:                        log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx,
        !           538:                                        "(cached) result:",
        !           539:                                        caches[dc->context_ndx].result == COND_RESULT_UNSET ? "unknown" : 
        !           540:                                                (caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false"));
        !           541:                }
        !           542:        }
        !           543:        return caches[dc->context_ndx].result;
        !           544: }
        !           545: 
        !           546: /**
        !           547:  * reset the config-cache for a named item
        !           548:  *
        !           549:  * if the item is COND_LAST_ELEMENT we reset all items
        !           550:  */
        !           551: void config_cond_cache_reset_item(server *srv, connection *con, comp_key_t item) {
        !           552:        size_t i;
        !           553: 
        !           554:        for (i = 0; i < srv->config_context->used; i++) {
        !           555:                if (item == COMP_LAST_ELEMENT || 
        !           556:                    con->cond_cache[i].comp_type == item) {
        !           557:                        con->cond_cache[i].result = COND_RESULT_UNSET;
        !           558:                        con->cond_cache[i].patterncount = 0;
        !           559:                        con->cond_cache[i].comp_value = NULL;
        !           560:                }
        !           561:        }
        !           562: }
        !           563: 
        !           564: /**
        !           565:  * reset the config cache to its initial state at connection start
        !           566:  */
        !           567: void config_cond_cache_reset(server *srv, connection *con) {
        !           568:        size_t i;
        !           569: 
        !           570:        config_cond_cache_reset_all_items(srv, con);
        !           571: 
        !           572:        for (i = 0; i < COMP_LAST_ELEMENT; i++) {
        !           573:                con->conditional_is_valid[i] = 0;
        !           574:        }
        !           575: }
        !           576: 
        !           577: int config_check_cond(server *srv, connection *con, data_config *dc) {
        !           578:        if (con->conf.log_condition_handling) {
        !           579:                log_error_write(srv, __FILE__, __LINE__,  "s",  "=== start of condition block ===");
        !           580:        }
        !           581:        return (config_check_cond_cached(srv, con, dc) == COND_RESULT_TRUE);
        !           582: }
        !           583: 
        !           584: int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n)
        !           585: {
        !           586:        cond_cache_t *cache = &con->cond_cache[dc->context_ndx];
        !           587:        if (n >= cache->patterncount) {
        !           588:                return 0;
        !           589:        }
        !           590: 
        !           591:        n <<= 1; /* n *= 2 */
        !           592:        buffer_append_string_len(buf,
        !           593:                        cache->comp_value->ptr + cache->matches[n],
        !           594:                        cache->matches[n + 1] - cache->matches[n]);
        !           595:        return 1;
        !           596: }
        !           597: 

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