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

📄 mod_mime_magic.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
    }}static int mget(request_rec *r, union VALUETYPE *p, unsigned char *s,                struct magic *m, apr_size_t nbytes){    long offset = m->offset;    if (offset + sizeof(union VALUETYPE) > nbytes)                  return 0;    memcpy(p, s + offset, sizeof(union VALUETYPE));    if (!mconvert(r, p, m))        return 0;    if (m->flag & INDIR) {        switch (m->in.type) {        case BYTE:            offset = p->b + m->in.offset;            break;        case SHORT:            offset = p->h + m->in.offset;            break;        case LONG:            offset = p->l + m->in.offset;            break;        }        if (offset + sizeof(union VALUETYPE) > nbytes)                      return 0;        memcpy(p, s + offset, sizeof(union VALUETYPE));        if (!mconvert(r, p, m))            return 0;    }    return 1;}static int mcheck(request_rec *r, union VALUETYPE *p, struct magic *m){    register unsigned long l = m->value.l;    register unsigned long v;    int matched;    if ((m->value.s[0] == 'x') && (m->value.s[1] == '\0')) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                    MODNAME ": BOINK");        return 1;    }    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:    case DATE:    case BEDATE:    case LEDATE:        v = p->l;        break;    case STRING:        l = 0;        /*         * What we want here is: v = strncmp(m->value.s, p->s, m->vallen);         * but ignoring any nulls.  bcmp doesn't give -/+/0 and isn't         * universally available anyway.         */        v = 0;        {            register unsigned char *a = (unsigned char *) m->value.s;            register unsigned char *b = (unsigned char *) p->s;            register int len = m->vallen;            while (--len >= 0)                if ((v = *b++ - *a++) != 0)                    break;        }        break;    default:        /*  bogosity, pretend that it just wasn't a match */        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                    MODNAME ": invalid type %d in mcheck().", m->type);        return 0;    }    v = signextend(r->server, m, v) & m->mask;    switch (m->reln) {    case 'x':#if MIME_MAGIC_DEBUG        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                    "%lu == *any* = 1", v);#endif        matched = 1;        break;    case '!':        matched = v != l;#if MIME_MAGIC_DEBUG        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                    "%lu != %lu = %d", v, l, matched);#endif        break;    case '=':        matched = v == l;#if MIME_MAGIC_DEBUG        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                    "%lu == %lu = %d", v, l, matched);#endif        break;    case '>':        if (m->flag & UNSIGNED) {            matched = v > l;#if MIME_MAGIC_DEBUG            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                        "%lu > %lu = %d", v, l, matched);#endif        }        else {            matched = (long) v > (long) l;#if MIME_MAGIC_DEBUG            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                        "%ld > %ld = %d", v, l, matched);#endif        }        break;    case '<':        if (m->flag & UNSIGNED) {            matched = v < l;#if MIME_MAGIC_DEBUG            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                        "%lu < %lu = %d", v, l, matched);#endif        }        else {            matched = (long) v < (long) l;#if MIME_MAGIC_DEBUG            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                        "%ld < %ld = %d", v, l, matched);#endif        }        break;    case '&':        matched = (v & l) == l;#if MIME_MAGIC_DEBUG        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                    "((%lx & %lx) == %lx) = %d", v, l, l, matched);#endif        break;    case '^':        matched = (v & l) != l;#if MIME_MAGIC_DEBUG        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                    "((%lx & %lx) != %lx) = %d", v, l, l, matched);#endif        break;    default:        /* bogosity, pretend it didn't match */        matched = 0;        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                    MODNAME ": mcheck: can't happen: invalid relation %d.",                    m->reln);        break;    }    return matched;}/* an optimization over plain strcmp() */#define    STREQ(a, b)    (*(a) == *(b) && strcmp((a), (b)) == 0)static int ascmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes){    int has_escapes = 0;    unsigned char *s;    char nbuf[HOWMANY + 1];  /* one extra for terminating '\0' */    char *token;    register struct names *p;    int small_nbytes;    char *strtok_state;    /* these are easy, do them first */    /*     * for troff, look for . + letter + letter or .\"; this must be done to     * disambiguate tar archives' ./file and other trash from real troff     * input.     */    if (*buf == '.') {        unsigned char *tp = buf + 1;        while (apr_isspace(*tp))            ++tp;  /* skip leading whitespace */        if ((apr_isalnum(*tp) || *tp == '\\') &&             (apr_isalnum(*(tp + 1)) || *tp == '"')) {            magic_rsl_puts(r, "application/x-troff");            return 1;        }    }    if ((*buf == 'c' || *buf == 'C') && apr_isspace(*(buf + 1))) {        /* Fortran */        magic_rsl_puts(r, "text/plain");        return 1;    }    /* look for tokens from names.h - this is expensive!, so we'll limit     * ourselves to only SMALL_HOWMANY bytes */    small_nbytes = (nbytes > SMALL_HOWMANY) ? SMALL_HOWMANY : nbytes;    /* make a copy of the buffer here because apr_strtok() will destroy it */    s = (unsigned char *) memcpy(nbuf, buf, small_nbytes);    s[small_nbytes] = '\0';    has_escapes = (memchr(s, '\033', small_nbytes) != NULL);    while ((token = apr_strtok((char *) s, " \t\n\r\f", &strtok_state)) != NULL) {        s = NULL;  /* make apr_strtok() keep on tokin' */        for (p = names; p < names + NNAMES; p++) {            if (STREQ(p->name, token)) {                magic_rsl_puts(r, types[p->type]);                if (has_escapes)                    magic_rsl_puts(r, " (with escape sequences)");                return 1;            }        }    }    switch (is_tar(buf, nbytes)) {    case 1:        /* V7 tar archive */        magic_rsl_puts(r, "application/x-tar");        return 1;    case 2:        /* POSIX tar archive */        magic_rsl_puts(r, "application/x-tar");        return 1;    }    /* all else fails, but it is ascii... */    return 0;}/* * compress routines: zmagic() - returns 0 if not recognized, uncompresses * and prints information if recognized uncompress(s, method, old, n, newch) * - uncompress old into new, using method, return sizeof new */static struct {    char *magic;    apr_size_t maglen;    char *argv[3];    int silent;    char *encoding;  /* MUST be lowercase */} compr[] = {    /* we use gzip here rather than uncompress because we have to pass     * it a full filename -- and uncompress only considers filenames     * ending with .Z     */    {        "\037\235", 2, {            "gzip", "-dcq", NULL        }, 0, "x-compress"    },    {        "\037\213", 2, {            "gzip", "-dcq", NULL        }, 1, "x-gzip"    },    /*     * XXX pcat does not work, cause I don't know how to make it read stdin,     * so we use gzip     */    {        "\037\036", 2, {            "gzip", "-dcq", NULL        }, 0, "x-gzip"    },};static int ncompr = sizeof(compr) / sizeof(compr[0]);static int zmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes){    unsigned char *newbuf;    int newsize;    int i;    for (i = 0; i < ncompr; i++) {        if (nbytes < compr[i].maglen)            continue;        if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0)            break;    }    if (i == ncompr)        return 0;    if ((newsize = uncompress(r, i, &newbuf, nbytes)) > 0) {        if (tryit(r, newbuf, newsize, 0) != OK) {            return 0;        }        /* set encoding type in the request record */        r->content_encoding = compr[i].encoding;    }    return 1;}struct uncompress_parms {    request_rec *r;    int method;};static int create_uncompress_child(struct uncompress_parms *parm, apr_pool_t *cntxt,                                   apr_file_t **pipe_in){    int rc = 1;    const char *new_argv[4];    const char *const *env;    request_rec *r = parm->r;    apr_pool_t *child_context = cntxt;    apr_procattr_t *procattr;    apr_proc_t *procnew;    /* XXX missing 1.3 logic:     *     * what happens when !compr[parm->method].silent?     * Should we create the err pipe, read it, and copy to the log?     */    env = (const char *const *)ap_create_environment(child_context, r->subprocess_env);    if ((apr_procattr_create(&procattr, child_context) != APR_SUCCESS) ||        (apr_procattr_io_set(procattr, APR_FULL_BLOCK,                           APR_FULL_BLOCK, APR_NO_PIPE)   != APR_SUCCESS) ||        (apr_procattr_dir_set(procattr, r->filename)        != APR_SUCCESS) ||        (apr_procattr_cmdtype_set(procattr, APR_PROGRAM)    != APR_SUCCESS)) {        /* Something bad happened, tell the world. */        ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_ENOPROC, r,               "couldn't setup child process: %s", r->filename);    }    else {        new_argv[0] = compr[parm->method].argv[0];        new_argv[1] = compr[parm->method].argv[1];        new_argv[2] = r->filename;        new_argv[3] = NULL;        procnew = apr_pcalloc(child_context, sizeof(*procnew));        rc = apr_proc_create(procnew, compr[parm->method].argv[0],                               new_argv, env, procattr, child_context);        if (rc != APR_SUCCESS) {            /* Bad things happened. Everyone should have cleaned up. */            ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_ENOPROC, r,                          MODNAME ": could not execute `%s'.",                          compr[parm->method].argv[0]);        }        else {            apr_pool_note_subprocess(child_context, procnew, APR_KILL_AFTER_TIMEOUT);            *pipe_in = procnew->out;        }    }    return (rc);}static int uncompress(request_rec *r, int method,                      unsigned char **newch, apr_size_t n){    struct uncompress_parms parm;    apr_file_t *pipe_out = NULL;    apr_pool_t *sub_context;    apr_status_t rv;    parm.r = r;    parm.method = method;    /* We make a sub_pool so that we can collect our child early, otherwise     * there are cases (i.e. generating directory indicies with mod_autoindex)     * where we would end up with LOTS of zombies.     */    if (apr_pool_create(&sub_context, r->pool) != APR_SUCCESS)        return -1;    if ((rv = create_uncompress_child(&parm, sub_context, &pipe_out)) != APR_SUCCESS) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,                    MODNAME ": couldn't spawn uncompress process: %s", r->uri);        return -1;    }    *newch = (unsigned char *) apr_palloc(r->pool, n);    rv = apr_file_read(pipe_out, *newch, &n);    if (n == 0) {        apr_pool_destroy(sub_context);        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,            MODNAME ": read failed from uncompress of %s", r->filename);        return -1;    }    apr_pool_destroy(sub_context);    return n;}/* * is_tar() -- figure out whether file is a tar archive. * * Stolen (by author of file utility) from the public domain tar program: Public * Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu). * * @(#)list.c 1.18 9/23/86 Public Domain - gnu $Id: mod_mime_magic.c,v 1.7 * 1997/06/24 00:41:02 ikluft Exp ikluft $ * * Comments changed and some code/comments reformatted for file command by Ian * Darwin. */#define isodigit(c) (((unsigned char)(c) >= '0') && ((unsigned char)(c) <= '7'))/* * Return 0 if the checksum is bad (i.e., probably not a tar archive), 1 for * old UNIX tar file, 2 for Unix Std (POSIX) tar file. */static

⌨️ 快捷键说明

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