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

📄 mod_include.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ==================================================================== * Copyright (c) 1995-1998 The Apache Group.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the Apache Group *    for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    apache@apache.org. * * 5. Products derived from this software may not be called "Apache" *    nor may "Apache" appear in their names without prior written *    permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the Apache Group *    for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * *//* * http_include.c: Handles the server-parsed HTML documents *  * Original by Rob McCool; substantial fixups by David Robinson; * incorporated into the Apache module framework by rst. *  *//*  * sub key may be anything a Perl*Handler can be: * subroutine name, package name (defaults to package::handler), * Class->method call or anoymous sub {} * * Child <!--#perl sub="sub {print $$}" --> accessed * <!--#perl sub="sub {print ++$Access::Cnt }" --> times. <br> * * <!--#perl arg="one" sub="mymod::includer" --> * * -Doug MacEachern */#ifdef USE_PERL_SSI#include "config.h"#undef VOIDUSED#ifdef USE_SFIO#undef USE_SFIO#define USE_STDIO#endif#include "modules/perl/mod_perl.h"#else#include "httpd.h"#include "http_config.h"#include "http_request.h"#include "http_core.h"#include "http_protocol.h"#include "http_log.h"#include "http_main.h"#include "util_script.h"#endif#define STARTING_SEQUENCE "<!--#"#define ENDING_SEQUENCE "-->"#define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]"#define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z"#define SIZEFMT_BYTES 0#define SIZEFMT_KMG 1#ifdef CHARSET_EBCDIC#define RAW_ASCII_CHAR(ch)  os_toebcdic[(unsigned char)ch]#else /*CHARSET_EBCDIC*/#define RAW_ASCII_CHAR(ch)  (ch)#endif /*CHARSET_EBCDIC*/module MODULE_VAR_EXPORT includes_module;/* just need some arbitrary non-NULL pointer which can't also be a request_rec */#define NESTED_INCLUDE_MAGIC	(&includes_module)/* ------------------------ Environment function -------------------------- *//* XXX: could use ap_table_overlap here */static void add_include_vars(request_rec *r, char *timefmt){#ifndef WIN32    struct passwd *pw;#endif /* ndef WIN32 */    table *e = r->subprocess_env;    char *t;    time_t date = r->request_time;    ap_table_setn(e, "DATE_LOCAL", ap_ht_time(r->pool, date, timefmt, 0));    ap_table_setn(e, "DATE_GMT", ap_ht_time(r->pool, date, timefmt, 1));    ap_table_setn(e, "LAST_MODIFIED",              ap_ht_time(r->pool, r->finfo.st_mtime, timefmt, 0));    ap_table_setn(e, "DOCUMENT_URI", r->uri);    ap_table_setn(e, "DOCUMENT_PATH_INFO", r->path_info);#ifndef WIN32    pw = getpwuid(r->finfo.st_uid);    if (pw) {        ap_table_setn(e, "USER_NAME", ap_pstrdup(r->pool, pw->pw_name));    }    else {        ap_table_setn(e, "USER_NAME", ap_psprintf(r->pool, "user#%lu",                    (unsigned long) r->finfo.st_uid));    }#endif /* ndef WIN32 */    if ((t = strrchr(r->filename, '/'))) {        ap_table_setn(e, "DOCUMENT_NAME", ++t);    }    else {        ap_table_setn(e, "DOCUMENT_NAME", r->uri);    }    if (r->args) {        char *arg_copy = ap_pstrdup(r->pool, r->args);        ap_unescape_url(arg_copy);        ap_table_setn(e, "QUERY_STRING_UNESCAPED",                  ap_escape_shell_cmd(r->pool, arg_copy));    }}/* --------------------------- Parser functions --------------------------- */#define OUTBUFSIZE 4096/* PUT_CHAR and FLUSH_BUF currently only work within the scope of  * find_string(); they are hacks to avoid calling rputc for each and * every character output.  A common set of buffering calls for this  * type of output SHOULD be implemented. */#define PUT_CHAR(c,r) \ { \    outbuf[outind++] = c; \    if (outind == OUTBUFSIZE) { \        FLUSH_BUF(r) \    }; \ }/* there SHOULD be some error checking on the return value of * rwrite, however it is unclear what the API for rwrite returning * errors is and little can really be done to help the error in  * any case. */#define FLUSH_BUF(r) \ { \   ap_rwrite(outbuf, outind, r); \   outind = 0; \ }/* * f: file handle being read from * c: character to read into * ret: return value to use if input fails * r: current request_rec * * This macro is redefined after find_string() for historical reasons * to avoid too many code changes.  This is one of the many things * that should be fixed. */#define GET_CHAR(f,c,ret,r) \ { \   int i = getc(f); \   if (i == EOF) { /* either EOF or error -- needs error handling if latter */ \       if (ferror(f)) { \           fprintf(stderr, "encountered error in GET_CHAR macro, " \                   "mod_include.\n"); \       } \       FLUSH_BUF(r); \       ap_pfclose(r->pool, f); \       return ret; \   } \   c = (char)i; \ }static int find_string(FILE *in, const char *str, request_rec *r, int printing){    int x, l = strlen(str), p;    char outbuf[OUTBUFSIZE];    int outind = 0;    char c;    p = 0;    while (1) {        GET_CHAR(in, c, 1, r);        if (c == str[p]) {            if ((++p) == l) {                FLUSH_BUF(r);                return 0;            }        }        else {            if (printing) {                for (x = 0; x < p; x++) {                    PUT_CHAR(str[x], r);                }                PUT_CHAR(c, r);            }            p = 0;        }    }}#undef FLUSH_BUF#undef PUT_CHAR#undef GET_CHAR#define GET_CHAR(f,c,r,p) \ { \   int i = getc(f); \   if (i == EOF) { /* either EOF or error -- needs error handling if latter */ \       if (ferror(f)) { \           fprintf(stderr, "encountered error in GET_CHAR macro, " \                   "mod_include.\n"); \       } \       ap_pfclose(p, f); \       return r; \   } \   c = (char)i; \ }/* * decodes a string containing html entities or numeric character references. * 's' is overwritten with the decoded string. * If 's' is syntatically incorrect, then the followed fixups will be made: *   unknown entities will be left undecoded; *   references to unused numeric characters will be deleted. *   In particular, &#00; will not be decoded, but will be deleted. * * drtr *//* maximum length of any ISO-LATIN-1 HTML entity name. */#define MAXENTLEN (6)/* The following is a shrinking transformation, therefore safe. */static void decodehtml(char *s){    int val, i, j;    char *p = s;    const char *ents;    static const char * const entlist[MAXENTLEN + 1] =    {        NULL,                   /* 0 */        NULL,                   /* 1 */        "lt\074gt\076",         /* 2 */        "amp\046ETH\320eth\360",        /* 3 */        "quot\042Auml\304Euml\313Iuml\317Ouml\326Uuml\334auml\344euml\353\iuml\357ouml\366uuml\374yuml\377",      /* 4 */        "Acirc\302Aring\305AElig\306Ecirc\312Icirc\316Ocirc\324Ucirc\333\THORN\336szlig\337acirc\342aring\345aelig\346ecirc\352icirc\356ocirc\364\ucirc\373thorn\376",            /* 5 */        "Agrave\300Aacute\301Atilde\303Ccedil\307Egrave\310Eacute\311\Igrave\314Iacute\315Ntilde\321Ograve\322Oacute\323Otilde\325Oslash\330\Ugrave\331Uacute\332Yacute\335agrave\340aacute\341atilde\343ccedil\347\egrave\350eacute\351igrave\354iacute\355ntilde\361ograve\362oacute\363\otilde\365oslash\370ugrave\371uacute\372yacute\375"     /* 6 */    };    for (; *s != '\0'; s++, p++) {        if (*s != '&') {            *p = *s;            continue;        }        /* find end of entity */        for (i = 1; s[i] != ';' && s[i] != '\0'; i++) {            continue;        }        if (s[i] == '\0') {     /* treat as normal data */            *p = *s;            continue;        }        /* is it numeric ? */        if (s[1] == '#') {            for (j = 2, val = 0; j < i && ap_isdigit(s[j]); j++) {                val = val * 10 + s[j] - '0';            }            s += i;            if (j < i || val <= 8 || (val >= 11 && val <= 31) ||                (val >= 127 && val <= 160) || val >= 256) {                p--;            /* no data to output */            }            else {                *p = RAW_ASCII_CHAR(val);            }        }        else {            j = i - 1;            if (j > MAXENTLEN || entlist[j] == NULL) {                /* wrong length */                *p = '&';                continue;       /* skip it */            }            for (ents = entlist[j]; *ents != '\0'; ents += i) {                if (strncmp(s + 1, ents, j) == 0) {                    break;                }            }            if (*ents == '\0') {                *p = '&';       /* unknown */            }            else {                *p = RAW_ASCII_CHAR(((const unsigned char *) ents)[j]);                s += i;            }        }    }    *p = '\0';}/* * extract the next tag name and value. * if there are no more tags, set the tag name to 'done' * the tag value is html decoded if dodecode is non-zero */static char *get_tag(pool *p, FILE *in, char *tag, int tagbuf_len, int dodecode){    char *t = tag, *tag_val, c, term;    /* makes code below a little less cluttered */    --tagbuf_len;    do {                        /* skip whitespace */        GET_CHAR(in, c, NULL, p);    } while (ap_isspace(c));    /* tags can't start with - */    if (c == '-') {        GET_CHAR(in, c, NULL, p);        if (c == '-') {            do {                GET_CHAR(in, c, NULL, p);            } while (ap_isspace(c));            if (c == '>') {                ap_cpystrn(tag, "done", tagbuf_len);                return tag;            }        }        return NULL;            /* failed */    }    /* find end of tag name */    while (1) {        if (t - tag == tagbuf_len) {            *t = '\0';            return NULL;        }        if (c == '=' || ap_isspace(c)) {            break;        }        *(t++) = ap_tolower(c);        GET_CHAR(in, c, NULL, p);    }    *t++ = '\0';    tag_val = t;    while (ap_isspace(c)) {        GET_CHAR(in, c, NULL, p);       /* space before = */    }    if (c != '=') {        ungetc(c, in);        return NULL;    }    do {        GET_CHAR(in, c, NULL, p);       /* space after = */    } while (ap_isspace(c));    /* we should allow a 'name' as a value */    if (c != '"' && c != '\'') {        return NULL;    }    term = c;    while (1) {        GET_CHAR(in, c, NULL, p);        if (t - tag == tagbuf_len) {            *t = '\0';            return NULL;        }/* Want to accept \" as a valid character within a string. */        if (c == '\\') {            *(t++) = c;         /* Add backslash */            GET_CHAR(in, c, NULL, p);

⌨️ 快捷键说明

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