Annotation of embedaddon/lighttpd/src/configfile-glue.c, revision 1.1.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>