Import BSD licensed libfile for mkhybrid builds from cdrtools-3.01.
- unnecessary files for tools build are not imported - file.c is renamed to lfile.c to avoid conflict with libhfs_iso - RCSId strings are trimmed
This commit is contained in:
parent
ddaa4e7dfc
commit
75490c835a
|
@ -0,0 +1,37 @@
|
|||
# @(#)LEGAL.NOTICE 1.2 08/10/19 joerg
|
||||
Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995.
|
||||
Software written by Ian F. Darwin and others; maintained by Christos Zoulas.
|
||||
Id: LEGAL.NOTICE,v 1.9 1995/10/27 23:14:20 christos Exp
|
||||
|
||||
License changed Oct 19th 2008 by J. Schilling with permission from
|
||||
Ian F. Darwin, Christos Zoulas and James Pearson to:
|
||||
|
||||
File: COPYING,v 1.1 2008/02/05 19:08:11 christos Exp
|
||||
Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995.
|
||||
Software written by Ian F. Darwin and others;
|
||||
maintained 1994- Christos Zoulas.
|
||||
|
||||
This software is not subject to any export provision of the United States
|
||||
Department of Commerce, and may be exported to any country or planet.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice immediately at the beginning of the file, without modification,
|
||||
this list of conditions, and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
|
@ -0,0 +1,70 @@
|
|||
# @(#)README 1.1 98/06/16 joerg
|
||||
|
||||
Find file types by using a modified "magic" file
|
||||
|
||||
Based on file v3.22 by Ian F. Darwin (see libfile/LEGAL.NOTICE and
|
||||
libfile/README.dist - File v3.22 can be found at many archive sites)
|
||||
|
||||
For each entry in the magic file, the "message" for the initial offset MUST
|
||||
be 4 characters for the CREATOR and 4 characters for the TYPE - white space is
|
||||
optional between them. Any other characters on this line are ignored.
|
||||
Continuation lines (starting with a '>') are also ignored i.e. only the initial
|
||||
offset lines are used.
|
||||
|
||||
e.g magic entry for a GIF file:
|
||||
|
||||
# off type test message
|
||||
#
|
||||
# GIF image
|
||||
0 string GIF8 8BIM GIFf
|
||||
>4 string 7a \b, version 8%s,
|
||||
>4 string 9a \b, version 8%s,
|
||||
>6 leshort >0 %hd x
|
||||
>8 leshort >0 %hd,
|
||||
#>10 byte &0x80 color mapped,
|
||||
#>10 byte&0x07 =0x00 2 colors
|
||||
#>10 byte&0x07 =0x01 4 colors
|
||||
#>10 byte&0x07 =0x02 8 colors
|
||||
#>10 byte&0x07 =0x03 16 colors
|
||||
#>10 byte&0x07 =0x04 32 colors
|
||||
#>10 byte&0x07 =0x05 64 colors
|
||||
#>10 byte&0x07 =0x06 128 colors
|
||||
#>10 byte&0x07 =0x07 256 colors
|
||||
|
||||
Just the "8BIM" "GIFf" will be used whatever the type of GIF file it is.
|
||||
The continuation lines are used by the "file" command, but ignored by
|
||||
mkhybrid. They could be left out completely.
|
||||
|
||||
The complete format of the magic file is given in the magic man page (magic.5).
|
||||
|
||||
See the file "magic" for other examples
|
||||
|
||||
Use with the -magic magic_file option, where magic_file is a file
|
||||
described above.
|
||||
|
||||
The magic file can be used with the mapping file (option -map) - the order
|
||||
these options appear on the command line is important. mkhybrid will try to
|
||||
detect if the file is one of the Unix/Mac files (e.g. a CAP or Netatalk
|
||||
file) first. If that fails, it will then use the magic and/or mapping
|
||||
file e.g:
|
||||
|
||||
mkhybrid -o output.raw -map mapping -magic magic src_dir
|
||||
|
||||
The above will check filename extensions first, if that fails to set the
|
||||
CREATOR/TYPE, the magic file will be used. To check the magic file
|
||||
before the filename extensions, use:
|
||||
|
||||
mkhybrid -o output.raw -magic magic -map mapping src_dir
|
||||
|
||||
|
||||
Using just a magic file - filename extensions will not be checked e.g:
|
||||
|
||||
mkhybrid -o output.raw -magic magic src_dir
|
||||
|
||||
For the magic method to work, each file must be opened and read twice
|
||||
(once to find it's CREATOR/TYPE, and a second time to actually copy the
|
||||
file to the CD image). Therefore the -magic option may significantly
|
||||
increase processing time.
|
||||
|
||||
If a file's CREATOR/TYPE is not set via the magic and mapping matches,
|
||||
then the file is given the default CREATOR/TYPE.
|
|
@ -0,0 +1,627 @@
|
|||
/* @(#)apprentice.c 1.13 09/07/11 joerg */
|
||||
#include <schily/mconfig.h>
|
||||
#ifndef lint
|
||||
static UConst char sccsid[] =
|
||||
"@(#)apprentice.c 1.13 09/07/11 joerg";
|
||||
#endif
|
||||
/*
|
||||
** find file types by using a modified "magic" file
|
||||
**
|
||||
** based on file v3.22 by Ian F. Darwin (see below)
|
||||
**
|
||||
** Modified for mkhybrid James Pearson 19/5/98
|
||||
*/
|
||||
|
||||
/*
|
||||
* apprentice - make one pass through /etc/magic, learning its secrets.
|
||||
*
|
||||
* Copyright (c) Ian F. Darwin, 1987.
|
||||
* Written by Ian F. Darwin.
|
||||
*
|
||||
* This software is not subject to any export provision of the United States
|
||||
* Department of Commerce, and may be exported to any country or planet.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <schily/stdio.h>
|
||||
#include <schily/stdlib.h>
|
||||
#include <schily/string.h>
|
||||
#include <schily/ctype.h>
|
||||
#include "file.h"
|
||||
#include <schily/schily.h>
|
||||
|
||||
#ifndef lint
|
||||
static UConst char moduleid[] =
|
||||
"@(#)Id: apprentice.c,v 1.25 1997/01/15 17:23:24 christos Exp";
|
||||
#endif /* lint */
|
||||
|
||||
int __f_nmagic = 0; /* number of valid magic[]s */
|
||||
#if defined(IS_MACOS_X)
|
||||
/*
|
||||
* The MAC OS X linker does not grok "common" varaibles.
|
||||
* Make __f_magic a "data" variable.
|
||||
*/
|
||||
struct magic *__f_magic = 0; /* array of magic entries */
|
||||
#else
|
||||
struct magic *__f_magic; /* array of magic entries */
|
||||
#endif
|
||||
|
||||
#define EATAB {while (isascii((unsigned char) *l) && \
|
||||
isspace((unsigned char) *l)) ++l;}
|
||||
#define LOWCASE(l) (isupper((unsigned char) (l)) ? \
|
||||
tolower((unsigned char) (l)) : (l))
|
||||
|
||||
|
||||
static int getvalue __PR((struct magic *, char **));
|
||||
static int hextoint __PR((int));
|
||||
static char *apgetstr __PR((char *, char *, int, int *));
|
||||
static int parse __PR((char *, int *, int));
|
||||
static void eatsize __PR((char **));
|
||||
|
||||
static int maxmagic = 0;
|
||||
|
||||
static int apprentice_1 __PR((char *, int));
|
||||
|
||||
/*
|
||||
* init_magic - read magic file and set up mapping
|
||||
* based on the original apprentice()
|
||||
*/
|
||||
int
|
||||
init_magic(fn)
|
||||
char *fn; /* list of magic files */
|
||||
{
|
||||
maxmagic = MAXMAGIS;
|
||||
__f_magic = (struct magic *) calloc(sizeof(struct magic), maxmagic);
|
||||
if (__f_magic == NULL)
|
||||
return -1;
|
||||
|
||||
return(apprentice_1(fn, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
apprentice_1(fn, check)
|
||||
char *fn; /* name of magic file */
|
||||
int check; /* non-zero? checking-only run. */
|
||||
{
|
||||
static const char hdr[] =
|
||||
"cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
|
||||
FILE *f;
|
||||
char line[BUFSIZ+1];
|
||||
int errs = 0;
|
||||
int lineno;
|
||||
|
||||
f = fopen(fn, "r");
|
||||
if (f==NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* parse it */
|
||||
if (check) /* print silly verbose header for USG compat. */
|
||||
(void) printf("%s\n", hdr);
|
||||
|
||||
for (lineno = 1;fgets(line, BUFSIZ, f) != NULL; lineno++) {
|
||||
if (line[0]=='#') /* comment, do not parse */
|
||||
continue;
|
||||
if (strlen(line) <= (unsigned)1) /* null line, garbage, etc */
|
||||
continue;
|
||||
line[strlen(line)-1] = '\0'; /* delete newline */
|
||||
if (parse(line, &__f_nmagic, check) != 0)
|
||||
errs = 1;
|
||||
}
|
||||
|
||||
(void) fclose(f);
|
||||
return errs;
|
||||
}
|
||||
|
||||
/*
|
||||
* extend the sign bit if the comparison is to be signed
|
||||
* XXX is uint32 really a good idea XXX JS
|
||||
*/
|
||||
UInt32_t
|
||||
signextend(m, v)
|
||||
struct magic *m;
|
||||
UInt32_t v;
|
||||
{
|
||||
if (!(m->flag & UNSIGNED))
|
||||
switch(m->type) {
|
||||
/*
|
||||
* Do not remove the casts below. They are
|
||||
* vital. When later compared with the data,
|
||||
* the sign extension must have happened.
|
||||
*/
|
||||
case BYTE:
|
||||
v = (char) v;
|
||||
break;
|
||||
case SHORT:
|
||||
case BESHORT:
|
||||
case LESHORT:
|
||||
v = (short) v;
|
||||
break;
|
||||
case DATE:
|
||||
case BEDATE:
|
||||
case LEDATE:
|
||||
case LONG:
|
||||
case BELONG:
|
||||
case LELONG:
|
||||
v = (Int32_t) v;
|
||||
break;
|
||||
case STRING:
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* parse one line from magic file, put into magic[index++] if valid
|
||||
*/
|
||||
static int
|
||||
parse(l, ndx, check)
|
||||
char *l;
|
||||
int *ndx, check;
|
||||
{
|
||||
int i = 0, nd = *ndx;
|
||||
struct magic *m;
|
||||
char *t, *s;
|
||||
|
||||
#define ALLOC_INCR 20
|
||||
if (nd+1 >= maxmagic){
|
||||
maxmagic += ALLOC_INCR;
|
||||
if ((__f_magic = (struct magic *) realloc(__f_magic,
|
||||
sizeof(struct magic) *
|
||||
maxmagic)) == NULL) {
|
||||
#ifdef MAIN
|
||||
(void) fprintf(stderr, "%s: Out of memory.\n", progname);
|
||||
#else
|
||||
(void) fprintf(stderr, "libfile: Out of memory.\n");
|
||||
#endif
|
||||
if (check)
|
||||
return -1;
|
||||
else
|
||||
exit(1);
|
||||
}
|
||||
memset(&__f_magic[*ndx], 0, sizeof(struct magic) * ALLOC_INCR);
|
||||
}
|
||||
m = &__f_magic[*ndx];
|
||||
m->flag = 0;
|
||||
m->cont_level = 0;
|
||||
|
||||
while (*l == '>') {
|
||||
++l; /* step over */
|
||||
m->cont_level++;
|
||||
}
|
||||
|
||||
if (m->cont_level != 0 && *l == '(') {
|
||||
++l; /* step over */
|
||||
m->flag |= INDIR;
|
||||
}
|
||||
if (m->cont_level != 0 && *l == '&') {
|
||||
++l; /* step over */
|
||||
m->flag |= ADD;
|
||||
}
|
||||
|
||||
/* get offset, then skip over it */
|
||||
m->offset = (int) strtoul(l,&t,0);
|
||||
/*
|
||||
if (l == t)
|
||||
magwarn("offset %s invalid", l);
|
||||
*/
|
||||
l = t;
|
||||
|
||||
if (m->flag & INDIR) {
|
||||
m->in.type = LONG;
|
||||
m->in.offset = 0;
|
||||
/*
|
||||
* read [.lbs][+-]nnnnn)
|
||||
*/
|
||||
if (*l == '.') {
|
||||
l++;
|
||||
switch (LOWCASE(*l)) {
|
||||
case 'l':
|
||||
m->in.type = LONG;
|
||||
break;
|
||||
case 'h':
|
||||
case 's':
|
||||
m->in.type = SHORT;
|
||||
break;
|
||||
case 'c':
|
||||
case 'b':
|
||||
m->in.type = BYTE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
l++;
|
||||
}
|
||||
s = l;
|
||||
if (*l == '+' || *l == '-') l++;
|
||||
if (isdigit((unsigned char)*l)) {
|
||||
m->in.offset = strtoul(l, &t, 0);
|
||||
if (*s == '-') m->in.offset = - m->in.offset;
|
||||
}
|
||||
else
|
||||
t = l;
|
||||
/*
|
||||
if (*t++ != ')')
|
||||
magwarn("missing ')' in indirect offset");
|
||||
*/
|
||||
l = t;
|
||||
}
|
||||
|
||||
|
||||
while (isascii((unsigned char)*l) && isdigit((unsigned char)*l))
|
||||
++l;
|
||||
EATAB;
|
||||
|
||||
#define NBYTE 4
|
||||
#define NSHORT 5
|
||||
#define NLONG 4
|
||||
#define NSTRING 6
|
||||
#define NDATE 4
|
||||
#define NBESHORT 7
|
||||
#define NBELONG 6
|
||||
#define NBEDATE 6
|
||||
#define NLESHORT 7
|
||||
#define NLELONG 6
|
||||
#define NLEDATE 6
|
||||
|
||||
if (*l == 'u') {
|
||||
++l;
|
||||
m->flag |= UNSIGNED;
|
||||
}
|
||||
|
||||
/* get type, skip it */
|
||||
if (strncmp(l, "byte", NBYTE)==0) {
|
||||
m->type = BYTE;
|
||||
l += NBYTE;
|
||||
} else if (strncmp(l, "short", NSHORT)==0) {
|
||||
m->type = SHORT;
|
||||
l += NSHORT;
|
||||
} else if (strncmp(l, "long", NLONG)==0) {
|
||||
m->type = LONG;
|
||||
l += NLONG;
|
||||
} else if (strncmp(l, "string", NSTRING)==0) {
|
||||
m->type = STRING;
|
||||
l += NSTRING;
|
||||
} else if (strncmp(l, "date", NDATE)==0) {
|
||||
m->type = DATE;
|
||||
l += NDATE;
|
||||
} else if (strncmp(l, "beshort", NBESHORT)==0) {
|
||||
m->type = BESHORT;
|
||||
l += NBESHORT;
|
||||
} else if (strncmp(l, "belong", NBELONG)==0) {
|
||||
m->type = BELONG;
|
||||
l += NBELONG;
|
||||
} else if (strncmp(l, "bedate", NBEDATE)==0) {
|
||||
m->type = BEDATE;
|
||||
l += NBEDATE;
|
||||
} else if (strncmp(l, "leshort", NLESHORT)==0) {
|
||||
m->type = LESHORT;
|
||||
l += NLESHORT;
|
||||
} else if (strncmp(l, "lelong", NLELONG)==0) {
|
||||
m->type = LELONG;
|
||||
l += NLELONG;
|
||||
} else if (strncmp(l, "ledate", NLEDATE)==0) {
|
||||
m->type = LEDATE;
|
||||
l += NLEDATE;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
/* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */
|
||||
if (*l == '&') {
|
||||
++l;
|
||||
m->mask = signextend(m, (UInt32_t)strtoul(l, &l, 0)); /* XXX JS uint32 cat may be wrong */
|
||||
eatsize(&l);
|
||||
} else
|
||||
m->mask = ~0L;
|
||||
EATAB;
|
||||
|
||||
switch (*l) {
|
||||
case '>':
|
||||
case '<':
|
||||
/* Old-style anding: "0 byte &0x80 dynamically linked" */
|
||||
case '&':
|
||||
case '^':
|
||||
case '=':
|
||||
m->reln = *l;
|
||||
++l;
|
||||
break;
|
||||
case '!':
|
||||
if (m->type != STRING) {
|
||||
m->reln = *l;
|
||||
++l;
|
||||
break;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
default:
|
||||
if (*l == 'x' && isascii((unsigned char)l[1]) &&
|
||||
isspace((unsigned char)l[1])) {
|
||||
m->reln = *l;
|
||||
++l;
|
||||
goto GetDesc; /* Bill The Cat */
|
||||
}
|
||||
m->reln = '=';
|
||||
break;
|
||||
}
|
||||
EATAB;
|
||||
|
||||
if (getvalue(m, &l))
|
||||
return -1;
|
||||
/*
|
||||
* TODO finish this macro and start using it!
|
||||
* #define offsetcheck {if (offset > HOWMANY-1)
|
||||
* magwarn("offset too big"); }
|
||||
*/
|
||||
|
||||
/*
|
||||
* now get last part - the description
|
||||
*/
|
||||
GetDesc:
|
||||
EATAB;
|
||||
if (l[0] == '\b') {
|
||||
++l;
|
||||
m->nospflag = 1;
|
||||
} else if ((l[0] == '\\') && (l[1] == 'b')) {
|
||||
++l;
|
||||
++l;
|
||||
m->nospflag = 1;
|
||||
} else
|
||||
m->nospflag = 0;
|
||||
while ((m->desc[i++] = *l++) != '\0' && i<MAXDESC)
|
||||
/* NULLBODY */;
|
||||
|
||||
++(*ndx); /* make room for next */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a numeric value from a pointer, into the value union of a magic
|
||||
* pointer, according to the magic type. Update the string pointer to point
|
||||
* just after the number read. Return 0 for success, non-zero for failure.
|
||||
*/
|
||||
static int
|
||||
getvalue(m, p)
|
||||
struct magic *m;
|
||||
char **p;
|
||||
{
|
||||
int slen;
|
||||
|
||||
if (m->type == STRING) {
|
||||
*p = apgetstr(*p, m->value.s, sizeof(m->value.s), &slen);
|
||||
m->vallen = slen;
|
||||
} else
|
||||
if (m->reln != 'x') {
|
||||
m->value.l = signextend(m, (UInt32_t)strtoul(*p, p, 0)); /* XXX JS uint32 cat may be wrong */
|
||||
eatsize(p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string containing C character escapes. Stop at an unescaped
|
||||
* space or tab.
|
||||
* Copy the converted version to "p", returning its length in *slen.
|
||||
* Return updated scan pointer as function result.
|
||||
*/
|
||||
static char *
|
||||
apgetstr(s, p, plen, slen)
|
||||
register char *s;
|
||||
register char *p;
|
||||
int plen, *slen;
|
||||
{
|
||||
char *origs = s, *origp = p;
|
||||
char *pmax = p + plen - 1;
|
||||
register int c;
|
||||
register int val;
|
||||
|
||||
while ((c = *s++) != '\0') {
|
||||
if (isspace((unsigned char) c))
|
||||
break;
|
||||
if (p >= pmax) {
|
||||
fprintf(stderr, "String too long: %s\n", origs);
|
||||
break;
|
||||
}
|
||||
if(c == '\\') {
|
||||
switch(c = *s++) {
|
||||
|
||||
case '\0':
|
||||
goto out;
|
||||
|
||||
default:
|
||||
*p++ = (char) c;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
*p++ = '\n';
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
*p++ = '\r';
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
*p++ = '\b';
|
||||
break;
|
||||
|
||||
case 't':
|
||||
*p++ = '\t';
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
*p++ = '\f';
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
*p++ = '\v';
|
||||
break;
|
||||
|
||||
/* \ and up to 3 octal digits */
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
val = c - '0';
|
||||
c = *s++; /* try for 2 */
|
||||
if(c >= '0' && c <= '7') {
|
||||
val = (val<<3) | (c - '0');
|
||||
c = *s++; /* try for 3 */
|
||||
if(c >= '0' && c <= '7')
|
||||
val = (val<<3) | (c-'0');
|
||||
else
|
||||
--s;
|
||||
}
|
||||
else
|
||||
--s;
|
||||
*p++ = (char)val;
|
||||
break;
|
||||
|
||||
/* \x and up to 2 hex digits */
|
||||
case 'x':
|
||||
val = 'x'; /* Default if no digits */
|
||||
c = hextoint(*s++); /* Get next char */
|
||||
if (c >= 0) {
|
||||
val = c;
|
||||
c = hextoint(*s++);
|
||||
if (c >= 0)
|
||||
val = (val << 4) + c;
|
||||
else
|
||||
--s;
|
||||
} else
|
||||
--s;
|
||||
*p++ = (char)val;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
*p++ = (char)c;
|
||||
}
|
||||
out:
|
||||
*p = '\0';
|
||||
*slen = p - origp;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* Single hex char to int; -1 if not a hex char. */
|
||||
static int
|
||||
hextoint(c)
|
||||
int c;
|
||||
{
|
||||
if (!isascii((unsigned char) c)) return -1;
|
||||
if (isdigit((unsigned char) c)) return c - '0';
|
||||
if ((c>='a')&&(c<='f')) return c + 10 - 'a';
|
||||
if ((c>='A')&&(c<='F')) return c + 10 - 'A';
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print a string containing C character escapes.
|
||||
*/
|
||||
void
|
||||
showstr(fp, s, len)
|
||||
FILE *fp;
|
||||
const char *s;
|
||||
int len;
|
||||
{
|
||||
register char c;
|
||||
|
||||
for (;;) {
|
||||
c = *s++;
|
||||
if (len == -1) {
|
||||
if (c == '\0')
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (len-- == 0)
|
||||
break;
|
||||
}
|
||||
if(c >= 040 && c <= 0176) /* TODO isprint && !iscntrl */
|
||||
(void) fputc(c, fp);
|
||||
else {
|
||||
(void) fputc('\\', fp);
|
||||
switch (c) {
|
||||
|
||||
case '\n':
|
||||
(void) fputc('n', fp);
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
(void) fputc('r', fp);
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
(void) fputc('b', fp);
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
(void) fputc('t', fp);
|
||||
break;
|
||||
|
||||
case '\f':
|
||||
(void) fputc('f', fp);
|
||||
break;
|
||||
|
||||
case '\v':
|
||||
(void) fputc('v', fp);
|
||||
break;
|
||||
|
||||
default:
|
||||
(void) fprintf(fp, "%.3o", c & 0377);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* eatsize(): Eat the size spec from a number [eg. 10UL]
|
||||
*/
|
||||
static void
|
||||
eatsize(p)
|
||||
char **p;
|
||||
{
|
||||
char *l = *p;
|
||||
|
||||
if (LOWCASE(*l) == 'u')
|
||||
l++;
|
||||
|
||||
switch (LOWCASE(*l)) {
|
||||
case 'l': /* long */
|
||||
case 's': /* short */
|
||||
case 'h': /* short */
|
||||
case 'b': /* char/byte */
|
||||
case 'c': /* char/byte */
|
||||
l++;
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*p = l;
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/* @(#)file.h 1.12 09/07/13 joerg */
|
||||
/*
|
||||
* file.h - definitions for file(1) program
|
||||
* @(#)Id: file.h,v 1.25 1997/01/15 19:28:35 christos Exp
|
||||
*
|
||||
* Copyright (c) Ian F. Darwin, 1987.
|
||||
* Written by Ian F. Darwin.
|
||||
*
|
||||
* This software is not subject to any export provision of the United States
|
||||
* Department of Commerce, and may be exported to any country or planet.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __file_h__
|
||||
#define __file_h__
|
||||
|
||||
#ifndef _SCHILY_MCONFIG_H
|
||||
#include <schily/mconfig.h>
|
||||
#endif
|
||||
#include <schily/utypes.h>
|
||||
|
||||
#ifndef HOWMANY
|
||||
# define HOWMANY 8192 /* how much of the file to look at */
|
||||
#endif
|
||||
#define MAXMAGIS 1000 /* max entries in /etc/magic */
|
||||
#define MAXDESC 50 /* max leng of text description */
|
||||
#define MAXstring 32 /* max leng of "string" types */
|
||||
|
||||
struct magic {
|
||||
short flag;
|
||||
#define INDIR 1 /* if '>(...)' appears, */
|
||||
#define UNSIGNED 2 /* comparison is unsigned */
|
||||
#define ADD 4 /* if '>&' appears, */
|
||||
short cont_level; /* level of ">" */
|
||||
struct {
|
||||
char type; /* byte short long */
|
||||
Int32_t offset; /* offset from indirection */
|
||||
} in;
|
||||
Int32_t offset; /* offset to magic number */
|
||||
unsigned char reln; /* relation (0=eq, '>'=gt, etc) */
|
||||
char type; /* int, short, long or string. */
|
||||
char vallen; /* length of string value, if any */
|
||||
#define BYTE 1
|
||||
#define SHORT 2
|
||||
#define LONG 4
|
||||
#define STRING 5
|
||||
#define DATE 6
|
||||
#define BESHORT 7
|
||||
#define BELONG 8
|
||||
#define BEDATE 9
|
||||
#define LESHORT 10
|
||||
#define LELONG 11
|
||||
#define LEDATE 12
|
||||
union VALUETYPE {
|
||||
unsigned char b;
|
||||
unsigned short h;
|
||||
UInt32_t l;
|
||||
char s[MAXstring];
|
||||
unsigned char hs[2]; /* 2 bytes of a fixed-endian "short" */
|
||||
unsigned char hl[4]; /* 2 bytes of a fixed-endian "long" */
|
||||
} value; /* either number or string */
|
||||
UInt32_t mask; /* mask before comparison with value */
|
||||
char nospflag; /* supress space character */
|
||||
char desc[MAXDESC]; /* description */
|
||||
};
|
||||
|
||||
#include <schily/stdio.h>
|
||||
|
||||
extern int init_magic __PR((char *));
|
||||
extern int ascmagic __PR((unsigned char *, int));
|
||||
/*extern void error __PR((const char *, ...));*/
|
||||
extern void ckfputs __PR((const char *, FILE *));
|
||||
struct stat;
|
||||
extern int fsmagic __PR((const char *, struct stat *));
|
||||
extern int is_compress __PR((const unsigned char *, int *));
|
||||
extern int is_tar __PR((unsigned char *, int));
|
||||
extern void magwarn __PR((const char *, ...));
|
||||
extern void mdump __PR((struct magic *));
|
||||
extern char *get_magic_magic __PR((const char *));
|
||||
extern void showstr __PR((FILE *, const char *, int));
|
||||
extern char *softmagic __PR((unsigned char *, int));
|
||||
extern int tryit __PR((unsigned char *, int, int));
|
||||
extern int zmagic __PR((unsigned char *, int));
|
||||
extern void ckfprintf __PR((FILE *, const char *, ...));
|
||||
#ifndef __BEOS__
|
||||
extern UInt32_t signextend __PR((struct magic *, UInt32_t));
|
||||
#endif /* __BEOS__ */
|
||||
extern int internatmagic __PR((unsigned char *, int));
|
||||
extern void tryelf __PR((int, char *, int));
|
||||
|
||||
|
||||
extern char *progname; /* the program name */
|
||||
extern char *magicfile; /* name of the magic file */
|
||||
|
||||
extern struct magic *__f_magic; /* array of magic entries */
|
||||
extern int __f_nmagic; /* number of valid magic[]s */
|
||||
|
||||
|
||||
extern int debug; /* enable debugging? */
|
||||
extern int zflag; /* process compressed files? */
|
||||
extern int lflag; /* follow symbolic links? */
|
||||
|
||||
#if defined(sun) || defined(__sun__) || defined (__sun)
|
||||
# if defined(__svr4) || defined (__SVR4) || defined(__svr4__)
|
||||
# define SOLARIS
|
||||
# else
|
||||
# define SUNOS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
#define strerror(e) \
|
||||
(((e) >= 0 && (e) < sys_nerr) ? sys_errlist[(e)] : "Unknown error")
|
||||
#endif
|
||||
#ifndef HAVE_STRTOUL
|
||||
#define strtoul(a, b, c) strtol(a, b, c)
|
||||
#endif
|
||||
|
||||
#endif /* __file_h__ */
|
|
@ -0,0 +1,286 @@
|
|||
/* @(#)file.c 1.10 09/08/04 joerg */
|
||||
#include <schily/mconfig.h>
|
||||
#ifndef lint
|
||||
static UConst char sccsid[] =
|
||||
"@(#)file.c 1.10 09/08/04 joerg";
|
||||
#endif
|
||||
/*
|
||||
** find file types by using a modified "magic" file
|
||||
**
|
||||
** based on file v3.22 by Ian F. Darwin (see below)
|
||||
**
|
||||
** For each entry in the magic file, the message MUST start with
|
||||
** two 4 character strings which are the CREATOR and TYPE for the
|
||||
** Mac file. Any continuation lines are ignored. e.g magic entry
|
||||
** for a GIF file:
|
||||
**
|
||||
** 0 string GIF8 8BIM GIFf
|
||||
** >4 string 7a \b, version 8%s,
|
||||
** >4 string 9a \b, version 8%s,
|
||||
** >6 leshort >0 %hd x
|
||||
** >8 leshort >0 %hd,
|
||||
** #>10 byte &0x80 color mapped,
|
||||
** #>10 byte&0x07 =0x00 2 colors
|
||||
** #>10 byte&0x07 =0x01 4 colors
|
||||
** #>10 byte&0x07 =0x02 8 colors
|
||||
** #>10 byte&0x07 =0x03 16 colors
|
||||
** #>10 byte&0x07 =0x04 32 colors
|
||||
** #>10 byte&0x07 =0x05 64 colors
|
||||
** #>10 byte&0x07 =0x06 128 colors
|
||||
** #>10 byte&0x07 =0x07 256 colors
|
||||
**
|
||||
** Just the "8BIM" "GIFf" will be used whatever the type GIF file
|
||||
** it is.
|
||||
**
|
||||
** Modified for mkhybrid James Pearson 19/5/98
|
||||
*/
|
||||
|
||||
/*
|
||||
* file - find type of a file or files - main program.
|
||||
*
|
||||
* Copyright (c) Ian F. Darwin, 1987.
|
||||
* Written by Ian F. Darwin.
|
||||
*
|
||||
* This software is not subject to any export provision of the United States
|
||||
* Department of Commerce, and may be exported to any country or planet.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef lint
|
||||
static UConst char moduleid[] =
|
||||
"@(#)Id: file.c,v 1.38 1997/01/15 19:28:35 christos Exp";
|
||||
#endif /* lint */
|
||||
|
||||
#include <schily/stdio.h>
|
||||
#include <schily/stdlib.h>
|
||||
#include <schily/unistd.h> /* for read() */
|
||||
#include <schily/stat.h>
|
||||
#include <schily/fcntl.h> /* for open() */
|
||||
|
||||
#ifdef RESTORE_TIME
|
||||
#include <schily/utime.h>
|
||||
#ifdef HAVE_UTIMES
|
||||
#define USE_UTIMES
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <schily/in.h> /* for byte swapping */
|
||||
#endif
|
||||
|
||||
#include "patchlevel.h"
|
||||
#include "file.h"
|
||||
|
||||
#ifdef MAIN
|
||||
/* Global command-line options */
|
||||
#ifdef DEBUG
|
||||
int debug = 1; /* debugging */
|
||||
#else
|
||||
int debug = 0; /* debugging */
|
||||
#endif /* DEBUG */
|
||||
int lflag = 0; /* follow Symlinks (BSD only) */
|
||||
int zflag = 0; /* follow (uncompress) compressed files */
|
||||
|
||||
/* Misc globals */
|
||||
char *magicfile; /* where magic be found */
|
||||
|
||||
char *progname; /* used throughout */
|
||||
#endif
|
||||
|
||||
char * get_magic_match __PR((const char *inname));
|
||||
void clean_magic __PR((void));
|
||||
|
||||
#if 0
|
||||
static int byteconv4 __P((int, int, int));
|
||||
static short byteconv2 __P((int, int, int));
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* byteconv4
|
||||
* Input:
|
||||
* from 4 byte quantity to convert
|
||||
* same whether to perform byte swapping
|
||||
* big_endian whether we are a big endian host
|
||||
*/
|
||||
static int
|
||||
byteconv4(from, same, big_endian)
|
||||
int from;
|
||||
int same;
|
||||
int big_endian;
|
||||
{
|
||||
if (same)
|
||||
return from;
|
||||
else if (big_endian) /* lsb -> msb conversion on msb */
|
||||
{
|
||||
union {
|
||||
int i;
|
||||
char c[4];
|
||||
} retval, tmpval;
|
||||
|
||||
tmpval.i = from;
|
||||
retval.c[0] = tmpval.c[3];
|
||||
retval.c[1] = tmpval.c[2];
|
||||
retval.c[2] = tmpval.c[1];
|
||||
retval.c[3] = tmpval.c[0];
|
||||
|
||||
return retval.i;
|
||||
}
|
||||
else
|
||||
return ntohl(from); /* msb -> lsb conversion on lsb */
|
||||
}
|
||||
|
||||
/*
|
||||
* byteconv2
|
||||
* Same as byteconv4, but for shorts
|
||||
*/
|
||||
static short
|
||||
byteconv2(from, same, big_endian)
|
||||
int from;
|
||||
int same;
|
||||
int big_endian;
|
||||
{
|
||||
if (same)
|
||||
return from;
|
||||
else if (big_endian) /* lsb -> msb conversion on msb */
|
||||
{
|
||||
union {
|
||||
short s;
|
||||
char c[2];
|
||||
} retval, tmpval;
|
||||
|
||||
tmpval.s = (short) from;
|
||||
retval.c[0] = tmpval.c[1];
|
||||
retval.c[1] = tmpval.c[0];
|
||||
|
||||
return retval.s;
|
||||
}
|
||||
else
|
||||
return ntohs(from); /* msb -> lsb conversion on lsb */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* get_magic_match - get the CREATOR/TYPE string
|
||||
* based on the original process()
|
||||
*/
|
||||
char *
|
||||
get_magic_match(inname)
|
||||
const char *inname;
|
||||
{
|
||||
int fd = 0;
|
||||
unsigned char buf[HOWMANY+1]; /* one extra for terminating '\0' */
|
||||
struct stat sb;
|
||||
int nbytes = 0; /* number of bytes read from a datafile */
|
||||
char *match;
|
||||
|
||||
/* check the file is regular and non-zero length */
|
||||
if (stat(inname, &sb) != 0)
|
||||
return 0;
|
||||
|
||||
if (sb.st_size == 0 || ! S_ISREG(sb.st_mode))
|
||||
return 0;
|
||||
|
||||
if ((fd = open(inname, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* try looking at the first HOWMANY bytes
|
||||
*/
|
||||
if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1)
|
||||
return 0;
|
||||
|
||||
if (nbytes == 0)
|
||||
return 0;
|
||||
else {
|
||||
buf[nbytes++] = '\0'; /* null-terminate it */
|
||||
match = softmagic(buf, nbytes);
|
||||
}
|
||||
|
||||
#ifdef RESTORE_TIME
|
||||
/* really no point as we going to access the file later anyway */
|
||||
{
|
||||
/*
|
||||
* Try to restore access, modification times if read it.
|
||||
*/
|
||||
# ifdef USE_UTIMES
|
||||
struct timeval utsbuf[2];
|
||||
utsbuf[0].tv_sec = sb.st_atime;
|
||||
utsbuf[1].tv_sec = sb.st_mtime;
|
||||
|
||||
(void) utimes(inname, utsbuf); /* don't care if loses */
|
||||
# else
|
||||
struct utimbuf utbuf;
|
||||
|
||||
utbuf.actime = sb.st_atime;
|
||||
utbuf.modtime = sb.st_mtime;
|
||||
(void) utime(inname, &utbuf); /* don't care if loses */
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
(void) close(fd);
|
||||
|
||||
return(match);
|
||||
}
|
||||
|
||||
/*
|
||||
* clean_magic - deallocate memory used
|
||||
*/
|
||||
void
|
||||
clean_magic()
|
||||
{
|
||||
if (__f_magic)
|
||||
free(__f_magic);
|
||||
}
|
||||
|
||||
|
||||
#ifdef MAIN
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *ret;
|
||||
char creator[5];
|
||||
char type[5];
|
||||
|
||||
if (argc < 3)
|
||||
exit(1);
|
||||
|
||||
init_magic(argv[1]);
|
||||
|
||||
ret = get_magic_match(argv[2]);
|
||||
|
||||
if (!ret)
|
||||
ret = "unixTEXT";
|
||||
|
||||
sscanf(ret, "%4s%4s", creator, type);
|
||||
|
||||
creator[4] = type[4] = '\0';
|
||||
|
||||
printf("%s %s\n", creator, type);
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
#endif /* MAIN */
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/* @(#)patchlevel.h 1.1 97/01/15 joerg */
|
||||
#define FILE_VERSION_MAJOR 3
|
||||
#define patchlevel 22
|
||||
|
||||
/*
|
||||
* Patchlevel file for Ian Darwin's MAGIC command.
|
||||
* Id: patchlevel.h,v 1.22 1997/01/15 17:23:24 christos Exp
|
||||
*
|
||||
* Log: patchlevel.h,v
|
||||
* Revision 1.22 1997/01/15 17:23:24 christos
|
||||
* - add support for elf core files: find the program name under SVR4 [Ken Pizzini]
|
||||
* - print strings only up to the first carriage return [various]
|
||||
* - freebsd international ascii support [J Wunsch]
|
||||
* - magic fixes and additions [Guy Harris]
|
||||
* - 64 bit fixes [Larry Schwimmer]
|
||||
* - support for both utime and utimes, but don't restore file access times
|
||||
* by default [various]
|
||||
* - \xXX only takes 2 hex digits, not 3.
|
||||
* - re-implement support for core files [Guy Harris]
|
||||
*
|
||||
* Revision 1.21 1996/10/05 18:15:29 christos
|
||||
* Segregate elf stuff and conditionally enable it with -DBUILTIN_ELF
|
||||
* More magic fixes
|
||||
*
|
||||
* Revision 1.20 1996/06/22 22:15:52 christos
|
||||
* - support relative offsets of the form >&
|
||||
* - fix bug with truncating magic strings that contain \n
|
||||
* - file -f - did not read from stdin as documented
|
||||
* - support elf file parsing using our own elf support.
|
||||
* - as always magdir fixes and additions.
|
||||
*
|
||||
* Revision 1.19 1995/10/27 23:14:46 christos
|
||||
* Ability to parse colon separated list of magic files
|
||||
* New LEGAL.NOTICE
|
||||
* Various magic file changes
|
||||
*
|
||||
* Revision 1.18 1995/05/20 22:09:21 christos
|
||||
* Passed incorrect argument to eatsize().
|
||||
* Use %ld and %lx where appropriate.
|
||||
* Remove unused variables
|
||||
* ELF support for both big and little endian
|
||||
* Fixes for small files again.
|
||||
*
|
||||
* Revision 1.17 1995/04/28 17:29:13 christos
|
||||
* - Incorrect nroff detection fix from der Mouse
|
||||
* - Lost and incorrect magic entries.
|
||||
* - Added ELF stripped binary detection [in C; ugh]
|
||||
* - Look for $MAGIC to find the magic file.
|
||||
* - Eat trailing size specifications from numbers i.e. ignore 10L
|
||||
* - More fixes for very short files
|
||||
*
|
||||
* Revision 1.16 1995/03/25 22:06:45 christos
|
||||
* - use strtoul() where it exists.
|
||||
* - fix sign-extend bug
|
||||
* - try to detect tar archives before nroff files, otherwise
|
||||
* tar files where the first file starts with a . will not work
|
||||
*
|
||||
* Revision 1.15 1995/01/21 21:03:35 christos
|
||||
* Added CSECTION for the file man page
|
||||
* Added version flag -v
|
||||
* Fixed bug with -f input flag (from iorio@violet.berkeley.edu)
|
||||
* Lots of magic fixes and reorganization...
|
||||
*
|
||||
* Revision 1.14 1994/05/03 17:58:23 christos
|
||||
* changes from mycroft@gnu.ai.mit.edu (Charles Hannum) for unsigned
|
||||
*
|
||||
* Revision 1.13 1994/01/21 01:27:01 christos
|
||||
* Fixed null termination bug from Don Seeley at BSDI in ascmagic.c
|
||||
*
|
||||
* Revision 1.12 1993/10/27 20:59:05 christos
|
||||
* Changed -z flag to understand gzip format too.
|
||||
* Moved builtin compression detection to a table, and move
|
||||
* the compress magic entry out of the source.
|
||||
* Made printing of numbers unsigned, and added the mask to it.
|
||||
* Changed the buffer size to 8k, because gzip will refuse to
|
||||
* unzip just a few bytes.
|
||||
*
|
||||
* Revision 1.11 1993/09/24 18:49:06 christos
|
||||
* Fixed small bug in softmagic.c introduced by
|
||||
* copying the data to be examined out of the input
|
||||
* buffer. Changed the Makefile to use sed to create
|
||||
* the correct man pages.
|
||||
*
|
||||
* Revision 1.10 1993/09/23 21:56:23 christos
|
||||
* Passed purify. Fixed indirections. Fixed byte order printing.
|
||||
* Fixed segmentation faults caused by referencing past the end
|
||||
* of the magic buffer. Fixed bus errors caused by referencing
|
||||
* unaligned shorts or longs.
|
||||
*
|
||||
* Revision 1.9 1993/03/24 14:23:40 ian
|
||||
* Batch of minor changes from several contributors.
|
||||
*
|
||||
* Revision 1.8 93/02/19 15:01:26 ian
|
||||
* Numerous changes from Guy Harris too numerous to mention but including
|
||||
* byte-order independance, fixing "old-style masking", etc. etc. A bugfix
|
||||
* for broken symlinks from martin@@d255s004.zfe.siemens.de.
|
||||
*
|
||||
* Revision 1.7 93/01/05 14:57:27 ian
|
||||
* Couple of nits picked by Christos (again, thanks).
|
||||
*
|
||||
* Revision 1.6 93/01/05 13:51:09 ian
|
||||
* Lotsa work on the Magic directory.
|
||||
*
|
||||
* Revision 1.5 92/09/14 14:54:51 ian
|
||||
* Fix a tiny null-pointer bug in previous fix for tar archive + uncompress.
|
||||
*
|
||||
*/
|
||||
|
|
@ -0,0 +1,384 @@
|
|||
/* @(#)softmagic.c 1.12 09/07/11 joerg */
|
||||
#include <schily/mconfig.h>
|
||||
#ifndef lint
|
||||
static UConst char sccsid[] =
|
||||
"@(#)softmagic.c 1.12 09/07/11 joerg";
|
||||
#endif
|
||||
/*
|
||||
** find file types by using a modified "magic" file
|
||||
**
|
||||
** based on file v3.22 by Ian F. Darwin (see below)
|
||||
**
|
||||
** Modified for mkhybrid James Pearson 19/5/98
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 export provision of the United States
|
||||
* Department of Commerce, and may be exported to any country or planet.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <schily/stdio.h>
|
||||
#include <schily/string.h>
|
||||
#include <schily/stdlib.h>
|
||||
#include <schily/schily.h>
|
||||
|
||||
#include "file.h"
|
||||
|
||||
#ifndef lint
|
||||
static UConst char moduleid[] =
|
||||
"@(#)Id: softmagic.c,v 1.34 1997/01/15 19:28:35 christos Exp";
|
||||
#endif /* lint */
|
||||
|
||||
#ifdef DEBUG
|
||||
int debug = 1; /* debugging */
|
||||
#else
|
||||
#define debug 0 /* debugging */
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* static int match __PR((unsigned char *, int)); */
|
||||
static char *match __PR((unsigned char *, int));
|
||||
static int mget __PR((union VALUETYPE *,
|
||||
unsigned char *, struct magic *, int));
|
||||
/* QNX has a mcheck() prototyp in a public include file */
|
||||
static int magcheck __PR((union VALUETYPE *, struct magic *));
|
||||
#ifdef __used__
|
||||
static void mdebug __PR((Int32_t, char *, int));
|
||||
#endif
|
||||
static int mconvert __PR((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 */
|
||||
char *
|
||||
softmagic(buf, nbytes)
|
||||
unsigned char *buf;
|
||||
int nbytes;
|
||||
{
|
||||
return (match(buf, nbytes));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 char *
|
||||
match(s, nbytes)
|
||||
unsigned char *s;
|
||||
int nbytes;
|
||||
{
|
||||
int magindex = 0;
|
||||
union VALUETYPE p;
|
||||
|
||||
for (magindex = 0; magindex < __f_nmagic; magindex++) {
|
||||
/* if main entry matches, print it... */
|
||||
if (!mget(&p, s, &__f_magic[magindex], nbytes) ||
|
||||
!magcheck(&p, &__f_magic[magindex])) {
|
||||
/*
|
||||
* main entry didn't match,
|
||||
* flush its continuations
|
||||
*/
|
||||
while (magindex < __f_nmagic &&
|
||||
__f_magic[magindex + 1].cont_level != 0)
|
||||
magindex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
return (__f_magic[magindex].desc);
|
||||
}
|
||||
return 0; /* no match at all */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert the byte order of the data we are looking at
|
||||
*/
|
||||
static int
|
||||
mconvert(p, m)
|
||||
union VALUETYPE *p;
|
||||
struct magic *m;
|
||||
{
|
||||
switch (m->type) {
|
||||
case BYTE:
|
||||
case SHORT:
|
||||
case LONG:
|
||||
case DATE:
|
||||
return 1;
|
||||
case STRING:
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
/* Null terminate and eat the return */
|
||||
p->s[sizeof(p->s) - 1] = '\0';
|
||||
if ((ptr = strchr(p->s, '\n')) != NULL)
|
||||
*ptr = '\0';
|
||||
return 1;
|
||||
}
|
||||
case BESHORT:
|
||||
p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
|
||||
return 1;
|
||||
case BELONG:
|
||||
case BEDATE:
|
||||
p->l = (Int32_t)
|
||||
((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 = (Int32_t)
|
||||
((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __used__
|
||||
static void
|
||||
mdebug(offset, str, len)
|
||||
Int32_t offset;
|
||||
char *str;
|
||||
int len;
|
||||
{
|
||||
(void) fprintf(stderr, "mget @%d: ", offset);
|
||||
showstr(stderr, (char *) str, len);
|
||||
(void) fputc('\n', stderr);
|
||||
(void) fputc('\n', stderr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
mget(p, s, m, nbytes)
|
||||
union VALUETYPE* p;
|
||||
unsigned char *s;
|
||||
struct magic *m;
|
||||
int nbytes;
|
||||
{
|
||||
Int32_t offset = m->offset;
|
||||
|
||||
if (offset + sizeof(union VALUETYPE) <= nbytes)
|
||||
memcpy(p, s + offset, sizeof(union VALUETYPE));
|
||||
else {
|
||||
/*
|
||||
* the usefulness of padding with zeroes eludes me, it
|
||||
* might even cause problems
|
||||
*/
|
||||
Int32_t have = nbytes - offset;
|
||||
memset(p, 0, sizeof(union VALUETYPE));
|
||||
if (have > 0)
|
||||
memcpy(p, s + offset, have);
|
||||
}
|
||||
|
||||
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 (!mconvert(p, m))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
magcheck(p, m)
|
||||
union VALUETYPE* p;
|
||||
struct magic *m;
|
||||
{
|
||||
register UInt32_t l = m->value.l;
|
||||
register UInt32_t v;
|
||||
int matched;
|
||||
|
||||
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:
|
||||
return 0;/*NOTREACHED*/
|
||||
}
|
||||
|
||||
v = signextend(m, v) & m->mask;
|
||||
|
||||
switch (m->reln) {
|
||||
case 'x':
|
||||
if (debug)
|
||||
(void) fprintf(stderr, "%u == *any* = 1\n", v);
|
||||
matched = 1;
|
||||
break;
|
||||
|
||||
case '!':
|
||||
matched = v != l;
|
||||
if (debug)
|
||||
(void) fprintf(stderr, "%u != %u = %d\n",
|
||||
v, l, matched);
|
||||
break;
|
||||
|
||||
case '=':
|
||||
matched = v == l;
|
||||
if (debug)
|
||||
(void) fprintf(stderr, "%u == %u = %d\n",
|
||||
v, l, matched);
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if (m->flag & UNSIGNED) {
|
||||
matched = v > l;
|
||||
if (debug)
|
||||
(void) fprintf(stderr, "%u > %u = %d\n",
|
||||
v, l, matched);
|
||||
}
|
||||
else {
|
||||
matched = (Int32_t) v > (Int32_t) l;
|
||||
if (debug)
|
||||
(void) fprintf(stderr, "%d > %d = %d\n",
|
||||
(Int32_t)v, (Int32_t)l, matched);
|
||||
}
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if (m->flag & UNSIGNED) {
|
||||
matched = v < l;
|
||||
if (debug)
|
||||
(void) fprintf(stderr, "%u < %u = %d\n",
|
||||
v, l, matched);
|
||||
}
|
||||
else {
|
||||
matched = (Int32_t) v < (Int32_t) l;
|
||||
if (debug)
|
||||
(void) fprintf(stderr, "%d < %d = %d\n",
|
||||
(Int32_t)v, (Int32_t)l, matched);
|
||||
}
|
||||
break;
|
||||
|
||||
case '&':
|
||||
matched = (v & l) == l;
|
||||
if (debug)
|
||||
(void) fprintf(stderr, "((%x & %x) == %x) = %d\n",
|
||||
v, l, l, matched);
|
||||
break;
|
||||
|
||||
case '^':
|
||||
matched = (v & l) != l;
|
||||
if (debug)
|
||||
(void) fprintf(stderr, "((%x & %x) != %x) = %d\n",
|
||||
v, l, l, matched);
|
||||
break;
|
||||
|
||||
default:
|
||||
matched = 0;
|
||||
break;/*NOTREACHED*/
|
||||
}
|
||||
|
||||
return matched;
|
||||
}
|
Loading…
Reference in New Issue