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:
tsutsui 2024-05-31 19:52:25 +00:00
parent ddaa4e7dfc
commit 75490c835a
7 changed files with 1655 additions and 0 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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 */

View File

@ -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.
*
*/

View File

@ -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;
}