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

📄 mod_include.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 5 页
字号:
            if (c == term) {    /* Only if */                *(--t) = c;     /* Replace backslash ONLY for terminator */            }        }        else if (c == term) {            break;        }        *(t++) = c;    }    *t = '\0';    if (dodecode) {        decodehtml(tag_val);    }    return ap_pstrdup(p, tag_val);}static int get_directive(FILE *in, char *dest, size_t len, pool *p){    char *d = dest;    char c;    /* make room for nul terminator */    --len;    /* skip initial whitespace */    while (1) {        GET_CHAR(in, c, 1, p);        if (!ap_isspace(c)) {            break;        }    }    /* now get directive */    while (1) {	if (d - dest == len) {	    return 1;	}        *d++ = ap_tolower(c);        GET_CHAR(in, c, 1, p);        if (ap_isspace(c)) {            break;        }    }    *d = '\0';    return 0;}/* * Do variable substitution on strings */static void parse_string(request_rec *r, const char *in, char *out,			size_t length, int leave_name){    char ch;    char *next = out;    char *end_out;    /* leave room for nul terminator */    end_out = out + length - 1;    while ((ch = *in++) != '\0') {        switch (ch) {        case '\\':	    if (next == end_out) {		/* truncated */		*next = '\0';		return;	    }            if (*in == '$') {                *next++ = *in++;            }            else {                *next++ = ch;            }            break;        case '$':            {		char var[MAX_STRING_LEN];		const char *start_of_var_name;		const char *end_of_var_name;	/* end of var name + 1 */		const char *expansion;		const char *val;		size_t l;		/* guess that the expansion won't happen */		expansion = in - 1;		if (*in == '{') {		    ++in;		    start_of_var_name = in;		    in = strchr(in, '}');		    if (in == NULL) {                        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,				    r, "Missing '}' on variable \"%s\"",				    expansion);                        *next = '\0';                        return;                    }		    end_of_var_name = in;		    ++in;		}		else {		    start_of_var_name = in;		    while (ap_isalnum(*in) || *in == '_') {			++in;		    }		    end_of_var_name = in;		}		/* what a pain, too bad there's no table_getn where you can		 * pass a non-nul terminated string */		l = end_of_var_name - start_of_var_name;		if (l != 0) {		    l = (l > sizeof(var) - 1) ? (sizeof(var) - 1) : l;		    memcpy(var, start_of_var_name, l);		    var[l] = '\0';		    val = ap_table_get(r->subprocess_env, var);		    if (val) {			expansion = val;			l = strlen(expansion);		    }		    else if (leave_name) {			l = in - expansion;		    }		    else {			break;	/* no expansion to be done */		    }		}		else {		    /* zero-length variable name causes just the $ to be copied */		    l = 1;		}		l = (l > end_out - next) ? (end_out - next) : l;		memcpy(next, expansion, l);		next += l;                break;            }        default:	    if (next == end_out) {		/* truncated */		*next = '\0';		return;	    }            *next++ = ch;            break;        }    }    *next = '\0';    return;}/* --------------------------- Action handlers ---------------------------- */static int include_cgi(char *s, request_rec *r){    request_rec *rr = ap_sub_req_lookup_uri(s, r);    int rr_status;    if (rr->status != HTTP_OK) {        return -1;    }    /* No hardwired path info or query allowed */    if ((rr->path_info && rr->path_info[0]) || rr->args) {        return -1;    }    if (rr->finfo.st_mode == 0) {        return -1;    }    /* Script gets parameters of the *document*, for back compatibility */    rr->path_info = r->path_info;       /* hard to get right; see mod_cgi.c */    rr->args = r->args;    /* Force sub_req to be treated as a CGI request, even if ordinary     * typing rules would have called it something else.     */    rr->content_type = CGI_MAGIC_TYPE;    /* Run it. */    rr_status = ap_run_sub_req(rr);    if (ap_is_HTTP_REDIRECT(rr_status)) {        const char *location = ap_table_get(rr->headers_out, "Location");        location = ap_escape_html(rr->pool, location);        ap_rvputs(r, "<A HREF=\"", location, "\">", location, "</A>", NULL);    }    ap_destroy_sub_req(rr);#ifndef WIN32    ap_chdir_file(r->filename);#endif    return 0;}/* ensure that path is relative, and does not contain ".." elements * ensentially ensure that it does not match the regex: * (^/|(^|/)\.\.(/|$)) * XXX: this needs os abstraction... consider c:..\foo in win32 */static int is_only_below(const char *path){#if WIN32    if (path[1] == ':')	return 0;#endif    if (path[0] == '/') {	return 0;    }    if (path[0] == '.' && path[1] == '.'	&& (path[2] == '\0' || path[2] == '/')) {	return 0;    }    while (*path) {	if (*path == '/' && path[1] == '.' && path[2] == '.'	    && (path[3] == '\0' || path[3] == '/')) {	    return 0;	}	++path;    }    return 1;}static int handle_include(FILE *in, request_rec *r, const char *error, int noexec){    char tag[MAX_STRING_LEN];    char parsed_string[MAX_STRING_LEN];    char *tag_val;    while (1) {        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {            return 1;        }        if (!strcmp(tag, "file") || !strcmp(tag, "virtual")) {            request_rec *rr = NULL;            char *error_fmt = NULL;            parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 0);            if (tag[0] == 'f') {                /* be safe; only files in this directory or below allowed */		if (!is_only_below(parsed_string)) {                    error_fmt = "unable to include file \"%s\" "                        "in parsed file %s";                }                else {                    rr = ap_sub_req_lookup_file(parsed_string, r);                }            }            else {                rr = ap_sub_req_lookup_uri(parsed_string, r);            }            if (!error_fmt && rr->status != HTTP_OK) {                error_fmt = "unable to include \"%s\" in parsed file %s";            }            if (!error_fmt && noexec && rr->content_type                && (strncmp(rr->content_type, "text/", 5))) {                error_fmt = "unable to include potential exec \"%s\" "                    "in parsed file %s";            }            if (error_fmt == NULL) {                request_rec *p;                for (p = r; p != NULL; p = p->main) {                    if (strcmp(p->filename, rr->filename) == 0) {                        break;                    }                }                if (p != NULL) {                    error_fmt = "Recursive include of \"%s\" "                        "in parsed file %s";                }            }	    /* see the Kludge in send_parsed_file for why */	    if (rr) 		ap_set_module_config(rr->request_config, &includes_module, r);            if (!error_fmt && ap_run_sub_req(rr)) {                error_fmt = "unable to include \"%s\" in parsed file %s";            }#ifndef WIN32            ap_chdir_file(r->filename);#endif            if (error_fmt) {                ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,			    r, error_fmt, tag_val, r->filename);                ap_rputs(error, r);            }	    /* destroy the sub request if it's not a nested include */            if (rr != NULL		&& ap_get_module_config(rr->request_config, &includes_module)		    != NESTED_INCLUDE_MAGIC) {		ap_destroy_sub_req(rr);            }        }        else if (!strcmp(tag, "done")) {            return 0;        }        else {            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,                        "unknown parameter \"%s\" to tag include in %s",                        tag, r->filename);            ap_rputs(error, r);        }    }}typedef struct {    request_rec *r;    char *s;} include_cmd_arg;static int include_cmd_child(void *arg, child_info *pinfo){    request_rec *r = ((include_cmd_arg *) arg)->r;    char *s = ((include_cmd_arg *) arg)->s;    table *env = r->subprocess_env;    int child_pid = 0;#ifdef DEBUG_INCLUDE_CMD#ifdef OS2    /* under OS/2 /dev/tty is referenced as con */    FILE *dbg = fopen("con", "w");#else    FILE *dbg = fopen("/dev/tty", "w");#endif#endif#ifndef WIN32    char err_string[MAX_STRING_LEN];#endif#ifdef DEBUG_INCLUDE_CMD    fprintf(dbg, "Attempting to include command '%s'\n", s);#endif    if (r->path_info && r->path_info[0] != '\0') {        request_rec *pa_req;        ap_table_setn(env, "PATH_INFO", ap_escape_shell_cmd(r->pool, r->path_info));        pa_req = ap_sub_req_lookup_uri(escape_uri(r->pool, r->path_info), r);        if (pa_req->filename) {            ap_table_setn(env, "PATH_TRANSLATED",                      ap_pstrcat(r->pool, pa_req->filename, pa_req->path_info,                              NULL));        }    }    if (r->args) {        char *arg_copy = ap_pstrdup(r->pool, r->args);        ap_table_setn(env, "QUERY_STRING", r->args);        ap_unescape_url(arg_copy);        ap_table_setn(env, "QUERY_STRING_UNESCAPED",                  ap_escape_shell_cmd(r->pool, arg_copy));    }    ap_error_log2stderr(r->server);#ifdef DEBUG_INCLUDE_CMD    fprintf(dbg, "Attempting to exec '%s'\n", s);#endif    ap_cleanup_for_exec();    /* set shellcmd flag to pass arg to SHELL_PATH */    child_pid = ap_call_exec(r, pinfo, s, ap_create_environment(r->pool, env),			     1);#ifdef WIN32    return (child_pid);#else    /* Oh, drat.  We're still here.  The log file descriptors are closed,     * so we have to whimper a complaint onto stderr...     */#ifdef DEBUG_INCLUDE_CMD    fprintf(dbg, "Exec failed\n");#endif    ap_snprintf(err_string, sizeof(err_string),                "httpd: exec of %s failed, reason: %s (errno = %d)\n",                SHELL_PATH, strerror(errno), errno);    write(STDERR_FILENO, err_string, strlen(err_string));    exit(0);    /* NOT REACHED */    return (child_pid);#endif /* WIN32 */}static int include_cmd(char *s, request_rec *r){    include_cmd_arg arg;    BUFF *script_in;    arg.r = r;    arg.s = s;    if (!ap_bspawn_child(r->pool, include_cmd_child, &arg,			 kill_after_timeout, NULL, &script_in, NULL)) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, r,		     "couldn't spawn include command");        return -1;    }    ap_send_fb(script_in, r);    ap_bclose(script_in);    return 0;}static int handle_exec(FILE *in, request_rec *r, const char *error){    char tag[MAX_STRING_LEN];    char *tag_val;    char *file = r->filename;    char parsed_string[MAX_STRING_LEN];    while (1) {        if (!(tag_val = get_tag(r->pool, in, tag, sizeof(tag), 1))) {            return 1;        }        if (!strcmp(tag, "cmd")) {            parse_string(r, tag_val, parsed_string, sizeof(parsed_string), 1);            if (include_cmd(parsed_string, r) == -1) {                ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,                            "execution failure for parameter \"%s\" "

⌨️ 快捷键说明

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