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

📄 softmagic.c

📁 早期freebsd实现
💻 C
字号:
/* * softmagic - interpret variable magic from /etc/magic * * Copyright (c) Ian F. Darwin, 1987. * Written by Ian F. Darwin. * * This software is not subject to any license of the American Telephone * and Telegraph Company or of the Regents of the University of California. * * Permission is granted to anyone to use this software for any purpose on * any computer system, and to alter it and redistribute it freely, subject * to the following restrictions: * * 1. The author is not responsible for the consequences of use of this *    software, no matter how awful, even if they arise from flaws in it. * * 2. The origin of this software must not be misrepresented, either by *    explicit claim or by omission.  Since few users ever read sources, *    credits must appear in the documentation. * * 3. Altered versions must be plainly marked as such, and must not be *    misrepresented as being the original software.  Since few users *    ever read sources, credits must appear in the documentation. * * 4. This notice may not be removed or altered. */#include <stdio.h>#include <string.h>#include <time.h>#include <sys/types.h>#include "file.h"#ifndef	lintstatic char *moduleid = 	"@(#)$Id: softmagic.c,v 1.24 1993/10/27 20:59:05 christos Exp $";#endif	/* lint */static int match	__P((unsigned char *, int));static int mget		__P((union VALUETYPE *,			     unsigned char *, struct magic *, int));static int mcheck	__P((union VALUETYPE *, struct magic *));static void mprint	__P((union VALUETYPE *, struct magic *));static void mdebug	__P((long, char *, int));static int mconvert	__P((union VALUETYPE *, struct magic *));/* * 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 */intsoftmagic(buf, nbytes)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 intmatch(s, nbytes)unsigned char	*s;int nbytes;{	int magindex = 0;	int cont_level = 0;	int need_separator = 0;	union VALUETYPE p;	for (magindex = 0; magindex < nmagic; magindex++) {		/* if main entry matches, print it... */		if (!mget(&p, s, &magic[magindex], nbytes) ||		    !mcheck(&p, &magic[magindex])) {			    /* 			     * main entry didn't match,			     * flush its continuations			     */			    while (magindex < nmagic &&			    	   magic[magindex + 1].cont_level != 0)			    	   magindex++;			    continue;		}		mprint(&p, &magic[magindex]);		/*		 * If we printed something, we'll need to print		 * a blank before we print something else.		 */		if (magic[magindex].desc[0])			need_separator = 1;		/* and any continuations that match */		cont_level++;		while (magic[magindex+1].cont_level != 0 && 		       ++magindex < nmagic) {			if (cont_level >= magic[magindex].cont_level) {				if (cont_level > magic[magindex].cont_level) {					/*					 * We're at the end of the level					 * "cont_level" continuations.					 */					cont_level = magic[magindex].cont_level;				}				if (mget(&p, s, &magic[magindex], nbytes) &&				    mcheck(&p, &magic[magindex])) {					/*					 * 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					   && (magic[magindex].nospflag == 0)					   && (magic[magindex].desc[0] != '\0')					   ) {						(void) putchar(' ');						need_separator = 0;					}					mprint(&p, &magic[magindex]);					if (magic[magindex].desc[0])						need_separator = 1;					/*					 * If we see any continuations					 * at a higher level,					 * process them.					 */					cont_level++;				}			}		}		return 1;		/* all through */	}	return 0;			/* no match at all */}static voidmprint(p, m)union VALUETYPE *p;struct magic *m;{	char *pp, *rt;	unsigned long mask = m->mask ? m->mask : ~0;  	switch (m->type) {  	case BYTE: 		(void) printf(m->desc, (unsigned char) p->b & mask);  		break;  	case SHORT:  	case BESHORT:  	case LESHORT: 		(void) printf(m->desc, (unsigned short) p->h & mask);  		break;  	case LONG:  	case BELONG:  	case LELONG: 		(void) printf(m->desc, (unsigned long) p->l & mask);  		break;  	case STRING:		if (m->reln == '=') {			(void) printf(m->desc, m->value.s);		}		else {			if ((rt = strchr(p->s, '\n')) != NULL)				*rt = '\0';			(void) printf(m->desc, p->s);		}		break;	case DATE:	case BEDATE:	case LEDATE:		pp = ctime((time_t*) &p->l);		if ((rt = strchr(pp, '\n')) != NULL)			*rt = '\0';		(void) printf(m->desc, pp);		break;	default:		error("invalid m->type (%d) in mprint().\n", m->type);		/*NOTREACHED*/	}}/* * Convert the byte order of the data we are looking at */static intmconvert(p, m)union VALUETYPE *p;struct magic *m;{	switch (m->type) {	case BYTE:	case SHORT:	case LONG:	case DATE:	case STRING:		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:		error("invalid type %d in mconvert().\n", m->type);		return 0;	}}static voidmdebug(offset, str, len)long offset;char *str;int len;{	(void) fprintf(stderr, "mget @%d: ", offset);	showstr(stderr, (char *) str, len);	(void) fputc('\n', stderr);	(void) fputc('\n', stderr);}static intmget(p, s, m, nbytes)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 (debug) {		mdebug(offset, (char *) p, sizeof(union VALUETYPE));		mdump(m);	}	if (!mconvert(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 (debug) {			mdebug(offset, (char *) p, sizeof(union VALUETYPE));			mdump(m);		}		if (!mconvert(p, m))			return 0;	}	return 1;}static intmcheck(p, m)union VALUETYPE* p;struct magic *m;{	register long l = m->value.l;	register long v;	if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {		fprintf(stderr, "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:		error("invalid type %d in mcheck().\n", m->type);		return 0;/*NOTREACHED*/	}	if (m->mask != 0L)		v &= m->mask;	switch (m->reln) {	case 'x':		if (debug)			(void) fprintf(stderr, "%d == *any* = 1\n", v);		return 1;	case '!':		if (debug)			(void) fprintf(stderr, "%d != %d = %d\n", v, l, v != l);		return v != l;	case '=':		if (debug)			(void) fprintf(stderr, "%d == %d = %d\n", v, l, v == l);		return v == l;	case '>':		if (debug)			(void) fprintf(stderr, "%d > %d = %d\n", v, l, v > l);		return v > l;	case '<':		if (debug)			(void) fprintf(stderr, "%d < %d = %d\n", v, l, v < l);		return v < l;	case '&':		if (debug)			(void) fprintf(stderr, "((%x & %x) == %x) = %d\n",				       v, l, l, (v & l) == l);		return (v & l) == l;	case '^':		if (debug)			(void) fprintf(stderr, "((%x & %x) != %x) = %d\n",				       v, l, l, (v & l) != l);		return (v & l) != l;	default:		error("mcheck: can't happen: invalid relation %d.\n", m->reln);		return 0;/*NOTREACHED*/	}}

⌨️ 快捷键说明

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