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

📄 mod_mime_magic.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
    /*     * try tests in /etc/magic (or surrogate magic file)     */    if (softmagic(r, buf, nb) == 1)        return OK;    /*     * try known keywords, check for ascii-ness too.     */    if (ascmagic(r, buf, nb) == 1)        return OK;    /*     * abandon hope, all ye who remain here     */    return DECLINED;}#define    EATAB {while (apr_isspace(*l))  ++l;}/* * apprentice - load configuration from the magic file r *  API request record */static int apprentice(server_rec *s, apr_pool_t *p){    apr_file_t *f = NULL;    apr_status_t result;    char line[BUFSIZ + 1];    int errs = 0;    int lineno;#if MIME_MAGIC_DEBUG    int rule = 0;    struct magic *m, *prevm;#endif    magic_server_config_rec *conf = (magic_server_config_rec *)                    ap_get_module_config(s->module_config, &mime_magic_module);    const char *fname = ap_server_root_relative(p, conf->magicfile);    if (!fname) {        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s,                     MODNAME ": Invalid magic file path %s", conf->magicfile);        return -1;    }    if ((result = apr_file_open(&f, fname, APR_READ | APR_BUFFERED,                                APR_OS_DEFAULT, p)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR, result, s,                     MODNAME ": can't read magic file %s", fname);        return -1;    }    /* set up the magic list (empty) */    conf->magic = conf->last = NULL;    /* parse it */    for (lineno = 1; apr_file_gets(line, BUFSIZ, f) == APR_SUCCESS; lineno++) {        int ws_offset;        char *last = line + strlen(line) - 1; /* guaranteed that len >= 1 since an                                               * "empty" line contains a '\n'                                               */        /* delete newline and any other trailing whitespace */        while (last >= line               && apr_isspace(*last)) {            *last = '\0';            --last;        }        /* skip leading whitespace */        ws_offset = 0;        while (line[ws_offset] && apr_isspace(line[ws_offset])) {            ws_offset++;        }        /* skip blank lines */        if (line[ws_offset] == 0) {            continue;        }        /* comment, do not parse */        if (line[ws_offset] == '#')            continue;#if MIME_MAGIC_DEBUG        /* if we get here, we're going to use it so count it */        rule++;#endif        /* parse it */        if (parse(s, p, line + ws_offset, lineno) != 0)            ++errs;    }    (void) apr_file_close(f);#if MIME_MAGIC_DEBUG    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                MODNAME ": apprentice conf=%x file=%s m=%s m->next=%s last=%s",                conf,                conf->magicfile ? conf->magicfile : "NULL",                conf->magic ? "set" : "NULL",                (conf->magic && conf->magic->next) ? "set" : "NULL",                conf->last ? "set" : "NULL");    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                MODNAME ": apprentice read %d lines, %d rules, %d errors",                lineno, rule, errs);#endif#if MIME_MAGIC_DEBUG    prevm = 0;    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                MODNAME ": apprentice test");    for (m = conf->magic; m; m = m->next) {        if (apr_isprint((((unsigned long) m) >> 24) & 255) &&            apr_isprint((((unsigned long) m) >> 16) & 255) &&            apr_isprint((((unsigned long) m) >> 8) & 255) &&            apr_isprint(((unsigned long) m) & 255)) {            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                        MODNAME ": apprentice: POINTER CLOBBERED! "                        "m=\"%c%c%c%c\" line=%d",                        (((unsigned long) m) >> 24) & 255,                        (((unsigned long) m) >> 16) & 255,                        (((unsigned long) m) >> 8) & 255,                        ((unsigned long) m) & 255,                        prevm ? prevm->lineno : -1);            break;        }        prevm = m;    }#endif    return (errs ? -1 : 0);}/* * extend the sign bit if the comparison is to be signed */static unsigned long signextend(server_rec *s, struct magic *m, unsigned long v){    if (!(m->flag & UNSIGNED))        switch (m->type) {            /*             * Do not remove the casts below.  They are vital. When later             * compared with the data, the sign extension must have happened.             */        case BYTE:            v = (char) v;            break;        case SHORT:        case BESHORT:        case LESHORT:            v = (short) v;            break;        case DATE:        case BEDATE:        case LEDATE:        case LONG:        case BELONG:        case LELONG:            v = (long) v;            break;        case STRING:            break;        default:            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                        MODNAME ": can't happen: m->type=%d", m->type);            return -1;        }    return v;}/* * parse one line from magic file, put into magic[index++] if valid */static int parse(server_rec *serv, apr_pool_t *p, char *l, int lineno){    struct magic *m;    char *t, *s;    magic_server_config_rec *conf = (magic_server_config_rec *)                    ap_get_module_config(serv->module_config, &mime_magic_module);    /* allocate magic structure entry */    m = (struct magic *) apr_pcalloc(p, sizeof(struct magic));    /* append to linked list */    m->next = NULL;    if (!conf->magic || !conf->last) {        conf->magic = conf->last = m;    }    else {        conf->last->next = m;        conf->last = m;    }    /* set values in magic structure */    m->flag = 0;    m->cont_level = 0;    m->lineno = lineno;    while (*l == '>') {        ++l;  /* step over */        m->cont_level++;    }    if (m->cont_level != 0 && *l == '(') {        ++l;  /* step over */        m->flag |= INDIR;    }    /* get offset, then skip over it */    m->offset = (int) strtol(l, &t, 0);    if (l == t) {        ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv,                    MODNAME ": offset %s invalid", l);    }    l = t;    if (m->flag & INDIR) {        m->in.type = LONG;        m->in.offset = 0;        /*         * read [.lbs][+-]nnnnn)         */        if (*l == '.') {            switch (*++l) {            case 'l':                m->in.type = LONG;                break;            case 's':                m->in.type = SHORT;                break;            case 'b':                m->in.type = BYTE;                break;            default:                ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv,                        MODNAME ": indirect offset type %c invalid", *l);                break;            }            l++;        }        s = l;        if (*l == '+' || *l == '-')            l++;        if (apr_isdigit((unsigned char) *l)) {            m->in.offset = strtol(l, &t, 0);            if (*s == '-')                m->in.offset = -m->in.offset;        }        else            t = l;        if (*t++ != ')') {            ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv,                        MODNAME ": missing ')' in indirect offset");        }        l = t;    }    while (apr_isdigit((unsigned char) *l))        ++l;    EATAB;#define NBYTE           4#define NSHORT          5#define NLONG           4#define NSTRING         6#define NDATE           4#define NBESHORT        7#define NBELONG         6#define NBEDATE         6#define NLESHORT        7#define NLELONG         6#define NLEDATE         6    if (*l == 'u') {        ++l;        m->flag |= UNSIGNED;    }    /* get type, skip it */    if (strncmp(l, "byte", NBYTE) == 0) {        m->type = BYTE;        l += NBYTE;    }    else if (strncmp(l, "short", NSHORT) == 0) {        m->type = SHORT;        l += NSHORT;    }    else if (strncmp(l, "long", NLONG) == 0) {        m->type = LONG;        l += NLONG;    }    else if (strncmp(l, "string", NSTRING) == 0) {        m->type = STRING;        l += NSTRING;    }    else if (strncmp(l, "date", NDATE) == 0) {        m->type = DATE;        l += NDATE;    }    else if (strncmp(l, "beshort", NBESHORT) == 0) {        m->type = BESHORT;        l += NBESHORT;    }    else if (strncmp(l, "belong", NBELONG) == 0) {        m->type = BELONG;        l += NBELONG;    }    else if (strncmp(l, "bedate", NBEDATE) == 0) {        m->type = BEDATE;        l += NBEDATE;    }    else if (strncmp(l, "leshort", NLESHORT) == 0) {        m->type = LESHORT;        l += NLESHORT;    }    else if (strncmp(l, "lelong", NLELONG) == 0) {        m->type = LELONG;        l += NLELONG;    }    else if (strncmp(l, "ledate", NLEDATE) == 0) {        m->type = LEDATE;        l += NLEDATE;    }    else {        ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv,                    MODNAME ": type %s invalid", l);        return -1;    }    /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */    if (*l == '&') {        ++l;        m->mask = signextend(serv, m, strtol(l, &l, 0));    }    else        m->mask = ~0L;    EATAB;    switch (*l) {    case '>':    case '<':        /* Old-style anding: "0 byte &0x80 dynamically linked" */    case '&':    case '^':    case '=':        m->reln = *l;        ++l;        break;    case '!':        if (m->type != STRING) {            m->reln = *l;            ++l;            break;        }        /* FALL THROUGH */    default:        if (*l == 'x' && apr_isspace(l[1])) {            m->reln = *l;            ++l;            goto GetDesc;  /* Bill The Cat */        }        m->reln = '=';        break;    }    EATAB;    if (getvalue(serv, m, &l))        return -1;    /*     * now get last part - the description     */  GetDesc:    EATAB;    if (l[0] == '\b') {        ++l;        m->nospflag = 1;    }    else if ((l[0] == '\\') && (l[1] == 'b')) {        ++l;        ++l;        m->nospflag = 1;    }    else        m->nospflag = 0;    strncpy(m->desc, l, sizeof(m->desc) - 1);    m->desc[sizeof(m->desc) - 1] = '\0';#if MIME_MAGIC_DEBUG    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, serv,                MODNAME ": parse line=%d m=%x next=%x cont=%d desc=%s",                lineno, m, m->next, m->cont_level, m->desc);#endif /* MIME_MAGIC_DEBUG */    return 0;}/* * Read a numeric value from a pointer, into the value union of a magic * pointer, according to the magic type.  Update the string pointer to point * just after the number read.  Return 0 for success, non-zero for failure. */static int getvalue(server_rec *s, struct magic *m, char **p){    int slen;    if (m->type == STRING) {        *p = getstr(s, *p, m->value.s, sizeof(m->value.s), &slen);        m->vallen = slen;    }    else if (m->reln != 'x')        m->value.l = signextend(s, m, strtol(*p, p, 0));    return 0;}/* * Convert a string containing C character escapes.  Stop at an unescaped * space or tab. Copy the converted version to "p", returning its length in * *slen. Return updated scan pointer as function result. */static char *getstr(server_rec *serv, register char *s, register char *p,                    int plen, int *slen){    char *origs = s, *origp = p;    char *pmax = p + plen - 1;    register int c;    register int val;    while ((c = *s++) != '\0') {        if (apr_isspace(c))            break;        if (p >= pmax) {            ap_log_error(APLOG_MARK, APLOG_ERR, 0, serv,                        MODNAME ": string too long: %s", origs);            break;        }        if (c == '\\') {            switch (c = *s++) {            case '\0':                goto out;            default:                *p++ = (char) c;                break;

⌨️ 快捷键说明

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