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

📄 mime_magic.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (cur_frag < start_frag)			continue;		/* loop through and collect chars */		for (cur_pos = (cur_frag == start_frag) ? start_pos : 0;			 frag->str[cur_pos];			 cur_pos++) {			if (cur_frag >= start_frag				&& cur_pos >= start_pos				&& res_pos <= len) {				result[res_pos++] = frag->str[cur_pos];				if (res_pos > len) {					break;				}			}		}    }    /* clean up and return */    result[res_pos] = 0;    return result;}/* * magic_process - process input file r        Apache API request record * (formerly called "process" in file command, prefix added for clarity) Opens * the file and reads a fixed-size buffer to begin processing the contents. */static int magic_process(char *filename TSRMLS_DC){	php_stream *stream;    unsigned char buf[HOWMANY + 1];	/* one extra for terminating '\0' */    int nbytes = 0;		/* number of bytes read from a datafile */    int result;    /*     * first try judging the file based on its filesystem status     */    switch ((result = fsmagic(filename TSRMLS_CC))) {    case MIME_MAGIC_DONE:		magic_rsl_putchar('\n');		return MIME_MAGIC_OK;    case MIME_MAGIC_OK:		break;    default:		/* fatal error, bail out */		return result;    }    stream = php_stream_open_wrapper(filename, "rb", IGNORE_PATH | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);    if (stream == NULL) {		/* We can't open it, but we were able to stat it. */		php_error(E_WARNING,					  MODNAME ": can't read `%s'", filename);		/* let some other handler decide what the problem is */		return MIME_MAGIC_DECLINED;    }    /*     * try looking at the first HOWMANY bytes     */    if ((nbytes = php_stream_read(stream, (char *) buf, sizeof(buf) - 1)) == -1) {		php_error(E_WARNING,					  MODNAME ": read failed: %s", filename);		return MIME_MAGIC_ERROR;    }    if (nbytes == 0)		magic_rsl_puts(MIME_TEXT_UNKNOWN);    else {		buf[nbytes++] = '\0';	/* null-terminate it */		tryit(buf, nbytes, 1);     }    (void) php_stream_close(stream);    (void) magic_rsl_putchar('\n');    return MIME_MAGIC_OK;}static void tryit(unsigned char *buf, int nb, int checkzmagic){    /*     * Try compression stuff     */#if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)	if (checkzmagic == 1) {  		if (zmagic(buf, nb) == 1)			return;	}#endif    /*     * try tests in /etc/magic (or surrogate magic file)     */    if (softmagic(buf, nb) == 1)		return;    /*     * try known keywords, check for ascii-ness too.     */    if (ascmagic(buf, nb) == 1)		return;    /*     * abandon hope, all ye who remain here     */    magic_rsl_puts(MIME_BINARY_UNKNOWN);}/* * return MIME_MAGIC_DONE to indicate it's been handled * return MIME_MAGIC_OK to indicate it's a regular file still needing handling * other returns indicate a failure of some sort */static int fsmagic(char *filename TSRMLS_DC){	php_stream_statbuf stat_ssb;	if(!php_stream_stat_path(filename, &stat_ssb)) {		return MIME_MAGIC_OK;	}    switch (stat_ssb.sb.st_mode & S_IFMT) {    case S_IFDIR:		magic_rsl_puts(DIR_MAGIC_TYPE);		return MIME_MAGIC_DONE;    case S_IFCHR:		/*		 * (void) magic_rsl_printf(r,"character special (%d/%d)",		 * major(sb->st_rdev), minor(sb->st_rdev));		 */		(void) magic_rsl_puts(MIME_BINARY_UNKNOWN);		return MIME_MAGIC_DONE;#ifdef S_IFBLK    case S_IFBLK:		/*		 * (void) magic_rsl_printf(r,"block special (%d/%d)",		 * major(sb->st_rdev), minor(sb->st_rdev));		 */		(void) magic_rsl_puts(MIME_BINARY_UNKNOWN);		return MIME_MAGIC_DONE;		/* TODO add code to handle V7 MUX and Blit MUX files */#endif#ifdef    S_IFIFO    case S_IFIFO:		/*		 * magic_rsl_puts(r,"fifo (named pipe)");		 */		(void) magic_rsl_puts(MIME_BINARY_UNKNOWN);		return MIME_MAGIC_DONE;#endif#ifdef    S_IFLNK    case S_IFLNK:		/* We used stat(), the only possible reason for this is that the		 * symlink is broken.		 */		php_error(E_WARNING,					  MODNAME ": broken symlink (%s)", filename);		return MIME_MAGIC_ERROR;#endif#ifdef    S_IFSOCK#ifndef __COHERENT__    case S_IFSOCK:		magic_rsl_puts(MIME_BINARY_UNKNOWN);		return MIME_MAGIC_DONE;#endif#endif    case S_IFREG:		break;	case 0:		break;    default:		php_error(E_WARNING,					  MODNAME ": invalid mode 0%o.", (unsigned int)stat_ssb.sb.st_mode);		return MIME_MAGIC_ERROR;    }    /*     * regular file, check next possibility     */    if (stat_ssb.sb.st_size == 0) {		magic_rsl_puts(MIME_TEXT_UNKNOWN);		return MIME_MAGIC_DONE;    }    return MIME_MAGIC_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(unsigned char *buf, int nbytes){    if (match(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(unsigned char *s, int nbytes){    int cont_level = 0;    int need_separator = 0;    union VALUETYPE p;    magic_server_config_rec *conf = &mime_global;    struct magic *m;    for (m = conf->magic; m; m = m->next) {		/* check if main entry matches */		if (!mget(&p, s, m, nbytes) ||			!mcheck(&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)) {				/*				 * 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 */		/* print the match */		mprint(&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 (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(&p, s, m, nbytes) &&					mcheck(&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(' ');						need_separator = 0;					}					mprint(&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;		}		return 1;		/* all through */    }    return 0;			/* no match at all */}/* an optimization over plain strcmp() */#define    STREQ(a, b)    (*(a) == *(b) && strcmp((a), (b)) == 0)static int ascmagic(unsigned char *buf, int 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;    /* 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 (isspace(*tp))			++tp;		/* skip leading whitespace */		if ((isalnum(*tp) || *tp == '\\') &&			(isalnum(*(tp + 1)) || *tp == '"')) {			magic_rsl_puts("application/x-troff");			return 1;		}    }    if ((*buf == 'c' || *buf == 'C') && isspace(*(buf + 1))) {		/* Fortran */		magic_rsl_puts("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 strtok() will destroy it */    s = (unsigned char *) memcpy(nbuf, buf, small_nbytes);    s[small_nbytes] = '\0';    has_escapes = (memchr(s, '\033', small_nbytes) != NULL);    /* XXX: not multithread safe */    while ((token = strtok((char *) s, " \t\n\r\f")) != NULL) {		s = NULL;		/* make strtok() keep on tokin' */		for (p = names; p < names + NNAMES; p++) {			if (STREQ(p->name, token)) {				magic_rsl_puts(types[p->type]);				if (has_escapes)					magic_rsl_puts(" (with escape sequences)");				return 1;			}		}    }    switch (is_tar(buf, nbytes)) {    case 1:		/* V7 tar archive */		magic_rsl_puts("application/x-tar");		return 1;    case 2:		/* POSIX tar archive */		magic_rsl_puts("application/x-tar");		return 1;    }    /* all else fails, but it is ascii... */    if (has_escapes) {		/* text with escape sequences */		/* we leave this open for further differentiation later */		magic_rsl_puts("text/plain");    }    else {		/* plain text */		magic_rsl_puts("text/plain");    }    return 1;}/* * 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)    ( ((c) >= '0') && ((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 int is_tar(unsigned char *buf, int nbytes){    register union record *header = (union record *) buf;    register int i;    register long sum, recsum;    register char *p;    if (nbytes < sizeof(union record))		return 0;    recsum = from_oct(8, header->header.chksum);    sum = 0;    p = header->charptr;    for (i = sizeof(union record); --i >= 0;) {		/*		 * We can't use unsigned char here because of old compilers, e.g. V7.		 */		sum += 0xFF & *p++;    }    /* Adjust checksum to count the "chksum" field as blanks. */    for (i = sizeof(header->header.chksum); --i >= 0;)		sum -= 0xFF & header->header.chksum[i];    sum += ' ' * sizeof header->header.chksum;    if (sum != recsum)		return 0;		/* Not a tar archive */    if (0 == strcmp(header->header.magic, TMAGIC))		return 2;		/* Unix Standard tar archive */    return 1;			/* Old fashioned tar archive */}/* * Quick and dirty octal conversion. * * Result is -1 if the field is invalid (all blank, or nonoctal). */

⌨️ 快捷键说明

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