📄 softmagic.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 <stdlib.h>#include <unistd.h>#include "file.h"#ifndef lintstatic char *moduleid ="@(#)/projects/agile/cvs/harvest/src/gatherer/essence/file/softmagic.c,v 1.3 1996/01/05 00:47:59 duane Exp";#endif /* lint */extern char *progname;extern char *magicfile; /* name of current /etc/magic or clone */extern int debug, nmagic;extern FILE *efopen();extern struct magic magic[];static int magindex;#ifdef MAKE_LIBRARY_ONLYstatic char typebuf[BUFSIZ];#endif/* * 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. */#ifdef MAKE_LIBRARY_ONLYchar * softmagic(buf) char *buf;{ magindex = 0; typebuf[0] = '\0'; if (match(buf)) return (typebuf); return (NULL);}#elsesoftmagic(buf) char *buf;{ magindex = 0; if (match(buf)) return 1; return 0;}#endif/* * go through the whole list, stopping if you find a match. * Be sure to process every continuation of this match. */match(s) char *s;{ while (magindex < nmagic) { /* if main entry matches, print it... */ if (mcheck(s, &magic[magindex])) { mprint(&magic[magindex], s); /* and any continuations that match */ while (magic[magindex + 1].contflag && magindex < nmagic) { ++magindex; if (mcheck(s, &magic[magindex])) {#ifndef MAKE_LIBRARY_ONLY (void) putchar(' ');#endif mprint(&magic[magindex], s); } } return 1; /* all through */ } else { /* main entry didn't match, flush its continuations */ while (magic[magindex + 1].contflag && magindex < nmagic) { ++magindex; } } ++magindex; /* on to the next */ } return 0; /* no match at all */}#ifdef MAKE_LIBRARY_ONLYstatic char typebuf2[BUFSIZ];#define printf(a,b) \ if (typebuf[0] == '\0') { \ sprintf(typebuf, (a), (b)); \ } else { \ sprintf(typebuf2, (a), (b)); \ strcat(typebuf, " "); \ strcat(typebuf, typebuf2); \ }#endifmprint(m, s) struct magic *m; char *s;{ register union VALUETYPE *p = (union VALUETYPE *) (s + m->offset); char *pp, *strchr(); switch (m->type) { case BYTE: printf(m->desc, p->b); break; case SHORT: printf(m->desc, p->h); break; case LONG: printf(m->desc, p->l); break; case STRING: if ((pp = strchr(p->s, '\n')) != NULL) *pp = '\0'; printf(m->desc, p->s); break; default: warning("invalid m->type (%d) in mprint()", m->type); }}#ifdef MAKE_LIBRARY_ONLY#undef printf#endifint mcheck(s, m) char *s; struct magic *m;{ register union VALUETYPE *p = (union VALUETYPE *) (s + m->offset); register long l = m->value.l; register long v; if (debug) { (void) printf("mcheck: %10.10s ", s); mdump(m); } switch (m->type) { case BYTE: v = p->b; break; case SHORT: v = p->h; break; case LONG: 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. */ { 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: warning("invalid type %d in mcheck()", m->type); return 0; } switch (m->reln) { case '=': return v == l; case '>': return v > l; case '<': return v < l; case '&': return v & l; default: warning("mcheck: can't happen: invalid relation %d", m->reln); return 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -