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

📄 mod_mime_magic.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 5 页
字号:
		    MODNAME ": broken symlink (%s)", fn);	return HTTP_INTERNAL_SERVER_ERROR;#endif#ifdef    S_IFSOCK#ifndef __COHERENT__    case S_IFSOCK:	magic_rsl_puts(r, MIME_BINARY_UNKNOWN);	return DONE;#endif#endif    case S_IFREG:	break;    default:	ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, r,		    MODNAME ": invalid mode 0%o.", (unsigned int)r->finfo.st_mode);	return HTTP_INTERNAL_SERVER_ERROR;    }    /*     * regular file, check next possibility     */    if (r->finfo.st_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, int 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, int 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_NOERRNO | APLOG_DEBUG, 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 (ap_isprint((((unsigned long) m) >> 24) & 255) &&	    ap_isprint((((unsigned long) m) >> 16) & 255) &&	    ap_isprint((((unsigned long) m) >> 8) & 255) &&	    ap_isprint(((unsigned long) m) & 255)) {	    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 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_NOERRNO | APLOG_DEBUG, 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_NOERRNO | APLOG_DEBUG, 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_NOERRNO | APLOG_DEBUG, 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_NOERRNO | APLOG_DEBUG, 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_NOERRNO | APLOG_DEBUG, r,		    MODNAME ": matched after %d rules", rule_counter);#endif	return 1;		/* all through */    }#if MIME_MAGIC_DEBUG    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 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, *rt;    unsigned long v;    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:	/* XXX: not multithread safe */	pp = ctime((time_t *) & p->l);	if ((rt = strchr(pp, '\n')) != NULL)	    *rt = '\0';	(void) magic_rsl_printf(r, m->desc, pp);	return;    default:	ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_ERR, 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_NOERRNO | APLOG_ERR, r,		    MODNAME ": invalid type %d in mconvert().", m->type);	return 0;    }}static int mget(request_rec *r, union VALUETYPE *p, unsigned char *s,		struct magic *m, int 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_NOERRNO | APLOG_ERR, 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_NOERRNO | APLOG_ERR, 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_NOERRNO | APLOG_DEBUG, r,		    "%lu == *any* = 1", v);#endif	matched = 1;	break;    case '!':	matched = v != l;#if MIME_MAGIC_DEBUG	ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,		    "%lu != %lu = %d", v, l, matched);#endif	break;    case '=':	matched = v == l;#if MIME_MAGIC_DEBUG	ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 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_NOERRNO | APLOG_DEBUG, r,			"%lu > %lu = %d", v, l, matched);#endif	}	else {	    matched = (long) v > (long) l;#if MIME_MAGIC_DEBUG	    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 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_NOERRNO | APLOG_DEBUG, r,			"%lu < %lu = %d", v, l, matched);#endif	}	else {	    matched = (long) v < (long) l;#if MIME_MAGIC_DEBUG	    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, r,			"%ld < %ld = %d", v, l, matched);#endif	}	break;    case '&':	matched = (v & l) == l;#if MIME_MAGIC_DEBUG	ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 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_NOERRNO | APLOG_DEBUG, r,		    "((%lx & %lx) != %lx) = %d", v, l, l, matched);#endif	break;

⌨️ 快捷键说明

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