⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_include.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
                else if (leave_name) {                    val = p;                    len = ep - p;                }                if (val && len) {                    if (out) {                        memcpy(out, val, (out+len <= eout) ? len : (eout-out));                        out += len;                    }                    else {                        current->len = len;                        current->string = val;                        outlen += len;                    }                }                p = newp;            }        }        if ((out && out >= eout) || (length && outlen >= length)) {            break;        }        /* check the remainder */        if (*p && (span = strcspn(p, "\\$")) > 0) {            if (!out && current->len) {                current->next = apr_palloc(ctx->dpool, sizeof(*current->next));                current = current->next;                current->next = NULL;            }            if (out) {                memcpy(out, p, (out+span <= eout) ? span : (eout-out));                out += span;            }            else {                current->len = span;                current->string = p;                outlen += span;            }            p += span;        }    } while (p < in+inlen);    /* assemble result */    if (out) {        if (out > eout) {            *eout = '\0';        }        else {            *out = '\0';        }    }    else {        const char *ep;        if (length && outlen > length) {            outlen = length - 1;        }        ret = out = apr_palloc(ctx->pool, outlen + 1);        ep = ret + outlen;        do {            if (result->len) {                memcpy(out, result->string, (out+result->len <= ep)                                            ? result->len : (ep-out));                out += result->len;            }            result = result->next;        } while (result && out < ep);        ret[outlen] = '\0';    }    return ret;}/* * +-------------------------------------------------------+ * |                                                       | * |              Conditional Expression Parser * |                                                       | * +-------------------------------------------------------+ */static APR_INLINE int re_check(include_ctx_t *ctx, const char *string,                               const char *rexp){    ap_regex_t *compiled;    backref_t *re = ctx->intern->re;    int rc;    compiled = ap_pregcomp(ctx->dpool, rexp, AP_REG_EXTENDED);    if (!compiled) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->intern->r, "unable to "                      "compile pattern \"%s\"", rexp);        return -1;    }    if (!re) {        re = ctx->intern->re = apr_palloc(ctx->pool, sizeof(*re));    }    re->source = apr_pstrdup(ctx->pool, string);    re->rexp = apr_pstrdup(ctx->pool, rexp);    re->nsub = compiled->re_nsub;    rc = !ap_regexec(compiled, string, AP_MAX_REG_MATCH, re->match, 0);    ap_pregfree(ctx->dpool, compiled);    return rc;}static int get_ptoken(include_ctx_t *ctx, const char **parse, token_t *token, token_t *previous){    const char *p;    apr_size_t shift;    int unmatched;    token->value = NULL;    if (!*parse) {        return 0;    }    /* Skip leading white space */    while (apr_isspace(**parse)) {        ++*parse;    }    if (!**parse) {        *parse = NULL;        return 0;    }    TYPE_TOKEN(token, TOKEN_STRING); /* the default type */    p = *parse;    unmatched = 0;    switch (*(*parse)++) {    case '(':        TYPE_TOKEN(token, TOKEN_LBRACE);        return 0;    case ')':        TYPE_TOKEN(token, TOKEN_RBRACE);        return 0;    case '=':        if (**parse == '=') ++*parse;        TYPE_TOKEN(token, TOKEN_EQ);        return 0;    case '!':        if (**parse == '=') {            TYPE_TOKEN(token, TOKEN_NE);            ++*parse;            return 0;        }        TYPE_TOKEN(token, TOKEN_NOT);        return 0;    case '\'':        unmatched = '\'';        break;    case '/':        /* if last token was ACCESS, this token is STRING */        if (previous != NULL && TOKEN_ACCESS == previous->type) {            break;        }        TYPE_TOKEN(token, TOKEN_RE);        unmatched = '/';        break;    case '|':        if (**parse == '|') {            TYPE_TOKEN(token, TOKEN_OR);            ++*parse;            return 0;        }        break;    case '&':        if (**parse == '&') {            TYPE_TOKEN(token, TOKEN_AND);            ++*parse;            return 0;        }        break;    case '>':        if (**parse == '=') {            TYPE_TOKEN(token, TOKEN_GE);            ++*parse;            return 0;        }        TYPE_TOKEN(token, TOKEN_GT);        return 0;    case '<':        if (**parse == '=') {            TYPE_TOKEN(token, TOKEN_LE);            ++*parse;            return 0;        }        TYPE_TOKEN(token, TOKEN_LT);        return 0;    case '-':        if (**parse == 'A' && (ctx->intern->accessenable)) {            TYPE_TOKEN(token, TOKEN_ACCESS);            ++*parse;            return 0;        }        break;    }    /* It's a string or regex token     * Now search for the next token, which finishes this string     */    shift = 0;    p = *parse = token->value = unmatched ? *parse : p;    for (; **parse; p = ++*parse) {        if (**parse == '\\') {            if (!*(++*parse)) {                p = *parse;                break;            }            ++shift;        }        else {            if (unmatched) {                if (**parse == unmatched) {                    unmatched = 0;                    ++*parse;                    break;                }            } else if (apr_isspace(**parse)) {                break;            }            else {                int found = 0;                switch (**parse) {                case '(':                case ')':                case '=':                case '!':                case '<':                case '>':                    ++found;                    break;                case '|':                case '&':                    if ((*parse)[1] == **parse) {                        ++found;                    }                    break;                }                if (found) {                    break;                }            }        }    }    if (unmatched) {        token->value = apr_pstrdup(ctx->dpool, "");    }    else {        apr_size_t len = p - token->value - shift;        char *c = apr_palloc(ctx->dpool, len + 1);        p = token->value;        token->value = c;        while (shift--) {            const char *e = ap_strchr_c(p, '\\');            memcpy(c, p, e-p);            c   += e-p;            *c++ = *++e;            len -= e-p;            p    = e+1;        }        if (len) {            memcpy(c, p, len);        }        c[len] = '\0';    }    return unmatched;}static int parse_expr(include_ctx_t *ctx, const char *expr, int *was_error){    parse_node_t *new, *root = NULL, *current = NULL;    request_rec *r = ctx->intern->r;    request_rec *rr = NULL;    const char *error = "Invalid expression \"%s\" in file %s";    const char *parse = expr;    int was_unmatched = 0;    unsigned regex = 0;    *was_error = 0;    if (!parse) {        return 0;    }    /* Create Parse Tree */    while (1) {        /* uncomment this to see how the tree a built:         *         * DEBUG_DUMP_TREE(ctx, root);         */        CREATE_NODE(ctx, new);        was_unmatched = get_ptoken(ctx, &parse, &new->token,                         (current != NULL ? &current->token : NULL));        if (!parse) {            break;        }        DEBUG_DUMP_UNMATCHED(ctx, was_unmatched);        DEBUG_DUMP_TOKEN(ctx, &new->token);        if (!current) {            switch (new->token.type) {            case TOKEN_STRING:            case TOKEN_NOT:            case TOKEN_ACCESS:            case TOKEN_LBRACE:                root = current = new;                continue;            default:                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, expr,                              r->filename);                *was_error = 1;                return 0;            }        }        switch (new->token.type) {        case TOKEN_STRING:            switch (current->token.type) {            case TOKEN_STRING:                current->token.value =                    apr_pstrcat(ctx->dpool, current->token.value,                                *current->token.value ? " " : "",                                new->token.value, NULL);                continue;            case TOKEN_RE:            case TOKEN_RBRACE:            case TOKEN_GROUP:                break;            default:                new->parent = current;                current = current->right = new;                continue;            }            break;        case TOKEN_RE:            switch (current->token.type) {            case TOKEN_EQ:            case TOKEN_NE:                new->parent = current;                current = current->right = new;                ++regex;                continue;            default:                break;            }            break;        case TOKEN_AND:        case TOKEN_OR:            switch (current->token.type) {            case TOKEN_STRING:            case TOKEN_RE:            case TOKEN_GROUP:                current = current->parent;                while (current) {                    switch (current->token.type) {                    case TOKEN_AND:                    case TOKEN_OR:                    case TOKEN_LBRACE:                        break;                    default:                        current = current->parent;                        continue;                    }                    break;                }                if (!current) {                    new->left = root;                    root->parent = new;                    current = root = new;                    continue;                }                new->left = current->right;                new->left->parent = new;                new->parent = current;                current = current->right = new;                continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -