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

📄 mod_mime_magic.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
            case 'n':                *p++ = '\n';                break;            case 'r':                *p++ = '\r';                break;            case 'b':                *p++ = '\b';                break;            case 't':                *p++ = '\t';                break;            case 'f':                *p++ = '\f';                break;            case 'v':                *p++ = '\v';                break;                /* \ and up to 3 octal digits */            case '0':            case '1':            case '2':            case '3':            case '4':            case '5':            case '6':            case '7':                val = c - '0';                c = *s++;  /* try for 2 */                if (c >= '0' && c <= '7') {                    val = (val << 3) | (c - '0');                    c = *s++;  /* try for 3 */                    if (c >= '0' && c <= '7')                        val = (val << 3) | (c - '0');                    else                        --s;                }                else                    --s;                *p++ = (char) val;                break;                /* \x and up to 3 hex digits */            case 'x':                val = 'x';            /* Default if no digits */                c = hextoint(*s++);   /* Get next char */                if (c >= 0) {                    val = c;                    c = hextoint(*s++);                    if (c >= 0) {                        val = (val << 4) + c;                        c = hextoint(*s++);                        if (c >= 0) {                            val = (val << 4) + c;                        }                        else                            --s;                    }                    else                        --s;                }                else                    --s;                *p++ = (char) val;                break;            }        }        else            *p++ = (char) c;    }  out:    *p = '\0';    *slen = p - origp;    return s;}/* Single hex char to int; -1 if not a hex char. */static int hextoint(int c){    if (apr_isdigit(c))        return c - '0';    if ((c >= 'a') && (c <= 'f'))        return c + 10 - 'a';    if ((c >= 'A') && (c <= 'F'))        return c + 10 - 'A';    return -1;}/* * return DONE to indicate it's been handled * return OK to indicate it's a regular file still needing handling * other returns indicate a failure of some sort */static int fsmagic(request_rec *r, const char *fn){    switch (r->finfo.filetype) {    case APR_DIR:        magic_rsl_puts(r, DIR_MAGIC_TYPE);        return DONE;    case APR_CHR:        /*         * (void) magic_rsl_printf(r,"character special (%d/%d)",         * major(sb->st_rdev), minor(sb->st_rdev));         */        (void) magic_rsl_puts(r, MIME_BINARY_UNKNOWN);        return DONE;    case APR_BLK:        /*         * (void) magic_rsl_printf(r,"block special (%d/%d)",         * major(sb->st_rdev), minor(sb->st_rdev));         */        (void) magic_rsl_puts(r, MIME_BINARY_UNKNOWN);        return DONE;        /* TODO add code to handle V7 MUX and Blit MUX files */    case APR_PIPE:        /*         * magic_rsl_puts(r,"fifo (named pipe)");         */        (void) magic_rsl_puts(r, MIME_BINARY_UNKNOWN);        return DONE;    case APR_LNK:        /* We used stat(), the only possible reason for this is that the         * symlink is broken.         */        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                    MODNAME ": broken symlink (%s)", fn);        return HTTP_INTERNAL_SERVER_ERROR;    case APR_SOCK:        magic_rsl_puts(r, MIME_BINARY_UNKNOWN);        return DONE;    case APR_REG:        break;    default:        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                      MODNAME ": invalid file type %d.", r->finfo.filetype);        return HTTP_INTERNAL_SERVER_ERROR;    }    /*     * regular file, check next possibility     */    if (r->finfo.size == 0) {        magic_rsl_puts(r, MIME_TEXT_UNKNOWN);        return DONE;    }    return OK;}/* * softmagic - lookup one file in database (already read from /etc/magic by * apprentice.c). Passed the name and FILE * of one file to be typed. */                /* ARGSUSED1 *//* nbytes passed for regularity, maybe need later */static int softmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes){    if (match(r, buf, nbytes))        return 1;    return 0;}/* * Go through the whole list, stopping if you find a match.  Process all the * continuations of that match before returning. * * We support multi-level continuations: * * At any time when processing a successful top-level match, there is a current * continuation level; it represents the level of the last successfully * matched continuation. * * Continuations above that level are skipped as, if we see one, it means that * the continuation that controls them - i.e, the lower-level continuation * preceding them - failed to match. * * Continuations below that level are processed as, if we see one, it means * we've finished processing or skipping higher-level continuations under the * control of a successful or unsuccessful lower-level continuation, and are * now seeing the next lower-level continuation and should process it.  The * current continuation level reverts to the level of the one we're seeing. * * Continuations at the current level are processed as, if we see one, there's * no lower-level continuation that may have failed. * * If a continuation matches, we bump the current continuation level so that * higher-level continuations are processed. */static int match(request_rec *r, unsigned char *s, apr_size_t nbytes){#if MIME_MAGIC_DEBUG    int rule_counter = 0;#endif    int cont_level = 0;    int need_separator = 0;    union VALUETYPE p;    magic_server_config_rec *conf = (magic_server_config_rec *)                ap_get_module_config(r->server->module_config, &mime_magic_module);    struct magic *m;#if MIME_MAGIC_DEBUG    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                MODNAME ": match 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");#endif#if MIME_MAGIC_DEBUG    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_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                        MODNAME ": match: POINTER CLOBBERED! "                        "m=\"%c%c%c%c\"",                        (((unsigned long) m) >> 24) & 255,                        (((unsigned long) m) >> 16) & 255,                        (((unsigned long) m) >> 8) & 255,                        ((unsigned long) m) & 255);            break;        }    }#endif    for (m = conf->magic; m; m = m->next) {#if MIME_MAGIC_DEBUG        rule_counter++;        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                    MODNAME ": line=%d desc=%s", m->lineno, m->desc);#endif        /* check if main entry matches */        if (!mget(r, &p, s, m, nbytes) ||            !mcheck(r, &p, m)) {            struct magic *m_cont;            /*             * main entry didn't match, flush its continuations             */            if (!m->next || (m->next->cont_level == 0)) {                continue;            }            m_cont = m->next;            while (m_cont && (m_cont->cont_level != 0)) {#if MIME_MAGIC_DEBUG                rule_counter++;                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                        MODNAME ": line=%d mc=%x mc->next=%x cont=%d desc=%s",                            m_cont->lineno, m_cont,                            m_cont->next, m_cont->cont_level,                            m_cont->desc);#endif                /*                 * this trick allows us to keep *m in sync when the continue                 * advances the pointer                 */                m = m_cont;                m_cont = m_cont->next;            }            continue;        }        /* if we get here, the main entry rule was a match */        /* this will be the last run through the loop */#if MIME_MAGIC_DEBUG        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                    MODNAME ": rule matched, line=%d type=%d %s",                    m->lineno, m->type,                    (m->type == STRING) ? m->value.s : "");#endif        /* print the match */        mprint(r, &p, m);        /*         * If we printed something, we'll need to print a blank before we         * print something else.         */        if (m->desc[0])            need_separator = 1;        /* and any continuations that match */        cont_level++;        /*         * while (m && m->next && m->next->cont_level != 0 && ( m = m->next         * ))         */        m = m->next;        while (m && (m->cont_level != 0)) {#if MIME_MAGIC_DEBUG            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                        MODNAME ": match line=%d cont=%d type=%d %s",                        m->lineno, m->cont_level, m->type,                        (m->type == STRING) ? m->value.s : "");#endif            if (cont_level >= m->cont_level) {                if (cont_level > m->cont_level) {                    /*                     * We're at the end of the level "cont_level"                     * continuations.                     */                    cont_level = m->cont_level;                }                if (mget(r, &p, s, m, nbytes) &&                    mcheck(r, &p, m)) {                    /*                     * This continuation matched. Print its message, with a                     * blank before it if the previous item printed and this                     * item isn't empty.                     */                    /* space if previous printed */                    if (need_separator                        && (m->nospflag == 0)                        && (m->desc[0] != '\0')                        ) {                        (void) magic_rsl_putchar(r, ' ');                        need_separator = 0;                    }                    mprint(r, &p, m);                    if (m->desc[0])                        need_separator = 1;                    /*                     * If we see any continuations at a higher level, process                     * them.                     */                    cont_level++;                }            }            /* move to next continuation record */            m = m->next;        }#if MIME_MAGIC_DEBUG        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                    MODNAME ": matched after %d rules", rule_counter);#endif        return 1;  /* all through */    }#if MIME_MAGIC_DEBUG    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                MODNAME ": failed after %d rules", rule_counter);#endif    return 0;  /* no match at all */}static void mprint(request_rec *r, union VALUETYPE *p, struct magic *m){    char *pp;    unsigned long v;    char time_str[APR_CTIME_LEN];    switch (m->type) {    case BYTE:        v = p->b;        break;    case SHORT:    case BESHORT:    case LESHORT:        v = p->h;        break;    case LONG:    case BELONG:    case LELONG:        v = p->l;        break;    case STRING:        if (m->reln == '=') {            (void) magic_rsl_printf(r, m->desc, m->value.s);        }        else {            (void) magic_rsl_printf(r, m->desc, p->s);        }        return;    case DATE:    case BEDATE:    case LEDATE:        apr_ctime(time_str, apr_time_from_sec(*(time_t *)&p->l));        pp = time_str;        (void) magic_rsl_printf(r, m->desc, pp);        return;    default:        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                    MODNAME ": invalid m->type (%d) in mprint().",                    m->type);        return;    }    v = signextend(r->server, m, v) & m->mask;    (void) magic_rsl_printf(r, m->desc, (unsigned long) v);}/* * Convert the byte order of the data we are looking at */static int mconvert(request_rec *r, union VALUETYPE *p, struct magic *m){    char *rt;    switch (m->type) {    case BYTE:    case SHORT:    case LONG:    case DATE:        return 1;    case STRING:        /* Null terminate and eat the return */        p->s[sizeof(p->s) - 1] = '\0';        if ((rt = strchr(p->s, '\n')) != NULL)            *rt = '\0';        return 1;    case BESHORT:        p->h = (short) ((p->hs[0] << 8) | (p->hs[1]));        return 1;    case BELONG:    case BEDATE:        p->l = (long)            ((p->hl[0] << 24) | (p->hl[1] << 16) | (p->hl[2] << 8) | (p->hl[3]));        return 1;    case LESHORT:        p->h = (short) ((p->hs[1] << 8) | (p->hs[0]));        return 1;    case LELONG:    case LEDATE:        p->l = (long)            ((p->hl[3] << 24) | (p->hl[2] << 16) | (p->hl[1] << 8) | (p->hl[0]));        return 1;    default:        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                    MODNAME ": invalid type %d in mconvert().", m->type);        return 0;

⌨️ 快捷键说明

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