Split CLI from libraries, create libfmagic.
CVS patchset: 5748 CVS date: 2002/10/02 19:00:31
This commit is contained in:
parent
1c582f226d
commit
2dfa85a312
|
@ -1,32 +1,34 @@
|
|||
AUTOMAKE_OPTIONS = 1.4 foreign
|
||||
|
||||
noinst_HEADERS = debug.h system.h
|
||||
|
||||
bin_PROGRAMS = file
|
||||
|
||||
data_DATA = magic magic.mime magic.mgc magic.mime.mgc
|
||||
|
||||
MAGIC = @datadir@/magic
|
||||
CPPFLAGS = -DMAGIC='"$(MAGIC)"'
|
||||
|
||||
if FSECT5
|
||||
man_MAGIC = magic.5
|
||||
else
|
||||
man_MAGIC = magic.4
|
||||
endif
|
||||
fsect = @fsect@
|
||||
man_MANS = file.1 $(man_MAGIC)
|
||||
|
||||
file_SOURCES = file.c apprentice.c fsmagic.c softmagic.c ascmagic.c \
|
||||
compress.c is_tar.c readelf.c print.c \
|
||||
file.h names.h patchlevel.h readelf.h tar.h
|
||||
#file_LDFLAGS = -all-static
|
||||
|
||||
EXTRA_DIST = LEGAL.NOTICE MAINT Makefile.std magic2mime \
|
||||
Localstuff Header $(magic_FRAGMENTS) file.man magic.man
|
||||
|
||||
BUILT_SOURCES = $(man_MANS) magic magic.mgc magic.mime.mgc
|
||||
|
||||
pkgincdir = @includedir@/fmagic
|
||||
pkginc_HEADERS = file.h
|
||||
|
||||
noinst_HEADERS = debug.h names.h patchlevel.h readelf.h system.h tar.h
|
||||
|
||||
lib_LTLIBRARIES = libfmagic.la
|
||||
libfmagic_la_SOURCES = \
|
||||
apprentice.c ascmagic.c fsmagic.c compress.c is_tar.c \
|
||||
print.c readelf.c softmagic.c
|
||||
|
||||
bin_PROGRAMS = file
|
||||
file_SOURCES = file.c
|
||||
file_LDADD = libfmagic.la
|
||||
|
||||
data_DATA = magic magic.mime magic.mgc magic.mime.mgc
|
||||
|
||||
man_MAGIC = magic.@fsect@
|
||||
man_MANS = file.1 $(man_MAGIC)
|
||||
|
||||
MAGIC = @datadir@/magic
|
||||
CPPFLAGS = -DMAGIC='"$(MAGIC)"'
|
||||
|
||||
fsect = @fsect@
|
||||
|
||||
magic: Header Localstuff $(magic_FRAGMENTS)
|
||||
cat $(srcdir)/Header $(srcdir)/Localstuff > $@
|
||||
for frag in $(magic_FRAGMENTS); do \
|
||||
|
@ -217,5 +219,5 @@ Magdir/zyxel
|
|||
|
||||
.PHONY: lclint
|
||||
lclint:
|
||||
lclint $(DEFS) $(INCLUDES) $(file_SOURCES)
|
||||
lclint $(DEFS) $(INCLUDES) $(file_SOURCES) $(libfmagic_la_SOURCES) $(pkginc_HEADERS) $(noinst_HEADERS)
|
||||
|
||||
|
|
|
@ -763,8 +763,7 @@ byteswap(struct magic *m, uint32_t nmagic)
|
|||
*/
|
||||
static char *
|
||||
mkdbname(const char *fn)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies fileSystem @*/
|
||||
/*@*/
|
||||
{
|
||||
static const char ext[] = ".mgc";
|
||||
/*@only@*/
|
||||
|
|
163
file/file.c
163
file/file.c
|
@ -32,7 +32,6 @@
|
|||
|
||||
FILE_RCSID("@(#)Id: file.c,v 1.66 2002/07/03 19:00:41 christos Exp ")
|
||||
|
||||
|
||||
#ifdef S_IFLNK
|
||||
# define USAGE "Usage: %s [-bciknsvzL] [-f namefile] [-m magicfiles] file...\n"
|
||||
#else
|
||||
|
@ -56,19 +55,20 @@ int os2_apptype (const char *fn, char *buf, int nb);
|
|||
/*@unchecked@*/
|
||||
int debug = 0; /* debugging */
|
||||
/*@unchecked@*/
|
||||
int lflag = 0; /* follow Symlinks (BSD only) */
|
||||
/*@unchecked@*/
|
||||
static int bflag = 0; /* brief output format */
|
||||
/*@unchecked@*/
|
||||
int zflag = 0; /* follow (uncompress) compressed files */
|
||||
/*@unchecked@*/
|
||||
int sflag = 0; /* read block special files */
|
||||
int bflag = 0; /* brief output format */
|
||||
/*@unchecked@*/
|
||||
int iflag = 0;
|
||||
/*@unchecked@*/
|
||||
static int nobuffer = 0; /* Do not buffer stdout */
|
||||
/*@unchecked@*/
|
||||
int kflag = 0; /* Keep going after the first match */
|
||||
/*@unchecked@*/
|
||||
int lflag = 0; /* follow Symlinks (BSD only) */
|
||||
/*@unchecked@*/
|
||||
int sflag = 0; /* read block special files */
|
||||
/*@unchecked@*/
|
||||
int zflag = 0; /* follow (uncompress) compressed files */
|
||||
|
||||
/*@unchecked@*/
|
||||
static int nobuffer = 0; /* Do not buffer stdout */
|
||||
|
||||
/*@unchecked@*/ /*@null@*/
|
||||
const char *magicfile = 0; /* where the magic is */
|
||||
|
@ -80,142 +80,6 @@ char *progname; /* used throughout */
|
|||
/*@unchecked@*/
|
||||
int lineno; /* line number in the magic file */
|
||||
|
||||
int
|
||||
tryit(const char *fn, unsigned char *buf, int nb, int zfl)
|
||||
{
|
||||
|
||||
/*
|
||||
* The main work is done here!
|
||||
* We have the file name and/or the data buffer to be identified.
|
||||
*/
|
||||
|
||||
#ifdef __EMX__
|
||||
/*
|
||||
* Ok, here's the right place to add a call to some os-specific
|
||||
* routine, e.g.
|
||||
*/
|
||||
if (os2_apptype(fn, buf, nb) == 1)
|
||||
return 'o';
|
||||
#endif
|
||||
/* try compression stuff */
|
||||
if (zfl && zmagic(fn, buf, nb))
|
||||
return 'z';
|
||||
|
||||
/* try tests in /etc/magic (or surrogate magic file) */
|
||||
if (softmagic(buf, nb))
|
||||
return 's';
|
||||
|
||||
/* try known keywords, check whether it is ASCII */
|
||||
if (ascmagic(buf, nb))
|
||||
return 'a';
|
||||
|
||||
/* abandon hope, all ye who remain here */
|
||||
ckfputs(iflag ? "application/octet-stream" : "data", stdout);
|
||||
return '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* process - process input file
|
||||
*/
|
||||
void
|
||||
process(const char *inname, int wid)
|
||||
{
|
||||
int fd = 0;
|
||||
static const char stdname[] = "standard input";
|
||||
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 = '\0';
|
||||
|
||||
if (strcmp("-", inname) == 0) {
|
||||
if (fstat(0, &sb)<0) {
|
||||
error("cannot fstat `%s' (%s).\n", stdname,
|
||||
strerror(errno));
|
||||
/*@notreached@*/
|
||||
}
|
||||
inname = stdname;
|
||||
}
|
||||
|
||||
if (wid > 0 && !bflag)
|
||||
(void) printf("%s:%*s ", inname,
|
||||
(int) (wid - strlen(inname)), "");
|
||||
|
||||
if (inname != stdname) {
|
||||
/*
|
||||
* first try judging the file based on its filesystem status
|
||||
*/
|
||||
if (fsmagic(inname, &sb) != 0) {
|
||||
(void) putchar('\n');
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fd = open(inname, O_RDONLY)) < 0) {
|
||||
/* We can't open it, but we were able to stat it. */
|
||||
if (sb.st_mode & 0002) ckfputs("writeable, ", stdout);
|
||||
if (sb.st_mode & 0111) ckfputs("executable, ", stdout);
|
||||
ckfprintf(stdout, "can't read `%s' (%s).\n",
|
||||
inname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* try looking at the first HOWMANY bytes
|
||||
*/
|
||||
if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) {
|
||||
error("read failed (%s).\n", strerror(errno));
|
||||
/*@notreached@*/
|
||||
}
|
||||
|
||||
if (nbytes == 0)
|
||||
ckfputs(iflag ? "application/x-empty" : "empty", stdout);
|
||||
else {
|
||||
buf[nbytes++] = '\0'; /* null-terminate it */
|
||||
match = tryit(inname, buf, nbytes, zflag);
|
||||
}
|
||||
|
||||
#ifdef BUILTIN_ELF
|
||||
if (match == 's' && nbytes > 5) {
|
||||
/*
|
||||
* We matched something in the file, so this *might*
|
||||
* be an ELF file, and the file is at least 5 bytes long,
|
||||
* so if it's an ELF file it has at least one byte
|
||||
* past the ELF magic number - try extracting information
|
||||
* from the ELF headers that can't easily be extracted
|
||||
* with rules in the magic file.
|
||||
*/
|
||||
tryelf(fd, buf, nbytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (inname != stdname) {
|
||||
#ifdef RESTORE_TIME
|
||||
/*
|
||||
* Try to restore access, modification times if read it.
|
||||
* This is really *bad* because it will modify the status
|
||||
* time of the file... And of course this will affect
|
||||
* backup programs
|
||||
*/
|
||||
# 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);
|
||||
}
|
||||
(void) putchar('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* unwrap -- read a file of filenames, do each one.
|
||||
*/
|
||||
|
@ -320,7 +184,7 @@ main(int argc, char **argv)
|
|||
struct stat sb;
|
||||
#define OPTSTRING "bcdf:ikm:nsvzCL"
|
||||
#ifdef HAVE_GETOPT_H
|
||||
int longindex;
|
||||
int longindex = 0;
|
||||
/*@-nullassign -readonlytrans@*/
|
||||
static struct option long_options[] =
|
||||
{
|
||||
|
@ -372,7 +236,8 @@ main(int argc, char **argv)
|
|||
magicfile = usermagic;
|
||||
else {
|
||||
if ((home = getenv("HOME")) != NULL) {
|
||||
usermagic = xmalloc(strlen(home) + 8);
|
||||
size_t nb = strlen(home) + 8;
|
||||
usermagic = xmalloc(nb);
|
||||
(void)strcpy(usermagic, home);
|
||||
(void)strcat(usermagic, "/.magic");
|
||||
if (stat(usermagic, &sb)<0)
|
||||
|
@ -385,10 +250,8 @@ main(int argc, char **argv)
|
|||
#ifndef HAVE_GETOPT_H
|
||||
while ((c = getopt(argc, argv, OPTSTRING)) != -1)
|
||||
#else
|
||||
/*@-compdef @*/
|
||||
while ((c = getopt_long(argc, argv, OPTSTRING, long_options,
|
||||
&longindex)) != -1)
|
||||
/*@=compdef @*/
|
||||
#endif
|
||||
{
|
||||
switch (c) {
|
||||
|
|
23
file/file.h
23
file/file.h
|
@ -128,15 +128,17 @@ extern struct mlist mlist; /* list of arrays of magic entries */
|
|||
/*@unchecked@*/
|
||||
extern int debug; /* enable debugging? */
|
||||
/*@unchecked@*/
|
||||
extern int zflag; /* process compressed files? */
|
||||
extern int bflag; /* brief output format */
|
||||
/*@unchecked@*/
|
||||
extern int iflag; /* Output types as mime-types */
|
||||
/*@unchecked@*/
|
||||
extern int kflag; /* Keep going after the first match */
|
||||
/*@unchecked@*/
|
||||
extern int lflag; /* follow symbolic links? */
|
||||
/*@unchecked@*/
|
||||
extern int sflag; /* read/analyze block special files? */
|
||||
/*@unchecked@*/
|
||||
extern int iflag; /* Output types as mime-types */
|
||||
/*@unchecked@*/
|
||||
extern int kflag; /* Keep going after the first match */
|
||||
extern int zflag; /* process compressed files? */
|
||||
/*@=exportlocal@*/
|
||||
|
||||
/*@mayexit@*/
|
||||
|
@ -180,6 +182,19 @@ extern int softmagic(unsigned char *buf, int nbytes)
|
|||
extern int tryit(const char *fn, unsigned char *buf, int nb, int zfl)
|
||||
/*@globals fileSystem, internalState @*/
|
||||
/*@modifies buf, fileSystem, internalState @*/;
|
||||
/**
|
||||
*/
|
||||
/*@unused@*/ /*@exits@*/ /*@only@*/
|
||||
static inline void * vmefail(/*@unused@*/ size_t nb)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies fileSystem @*/
|
||||
{
|
||||
error("out of memory");
|
||||
/*@notreached@*/
|
||||
/*@-nullret@*/
|
||||
return NULL;
|
||||
/*@=nullret@*/
|
||||
}
|
||||
extern int zmagic(const char *fname, unsigned char *buf, int nbytes)
|
||||
/*@globals fileSystem, internalState @*/
|
||||
/*@modifies buf, fileSystem, internalState @*/;
|
||||
|
|
136
file/fsmagic.c
136
file/fsmagic.c
|
@ -224,3 +224,139 @@ fsmagic(const char *fn, struct stat *sb)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tryit(const char *fn, unsigned char *buf, int nb, int zfl)
|
||||
{
|
||||
|
||||
/*
|
||||
* The main work is done here!
|
||||
* We have the file name and/or the data buffer to be identified.
|
||||
*/
|
||||
|
||||
#ifdef __EMX__
|
||||
/*
|
||||
* Ok, here's the right place to add a call to some os-specific
|
||||
* routine, e.g.
|
||||
*/
|
||||
if (os2_apptype(fn, buf, nb) == 1)
|
||||
return 'o';
|
||||
#endif
|
||||
/* try compression stuff */
|
||||
if (zfl && zmagic(fn, buf, nb))
|
||||
return 'z';
|
||||
|
||||
/* try tests in /etc/magic (or surrogate magic file) */
|
||||
if (softmagic(buf, nb))
|
||||
return 's';
|
||||
|
||||
/* try known keywords, check whether it is ASCII */
|
||||
if (ascmagic(buf, nb))
|
||||
return 'a';
|
||||
|
||||
/* abandon hope, all ye who remain here */
|
||||
ckfputs(iflag ? "application/octet-stream" : "data", stdout);
|
||||
return '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* process - process input file
|
||||
*/
|
||||
void
|
||||
process(const char *inname, int wid)
|
||||
{
|
||||
int fd = 0;
|
||||
static const char stdname[] = "standard input";
|
||||
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 = '\0';
|
||||
|
||||
if (strcmp("-", inname) == 0) {
|
||||
if (fstat(0, &sb)<0) {
|
||||
error("cannot fstat `%s' (%s).\n", stdname,
|
||||
strerror(errno));
|
||||
/*@notreached@*/
|
||||
}
|
||||
inname = stdname;
|
||||
}
|
||||
|
||||
if (wid > 0 && !bflag)
|
||||
(void) printf("%s:%*s ", inname,
|
||||
(int) (wid - strlen(inname)), "");
|
||||
|
||||
if (inname != stdname) {
|
||||
/*
|
||||
* first try judging the file based on its filesystem status
|
||||
*/
|
||||
if (fsmagic(inname, &sb) != 0) {
|
||||
(void) putchar('\n');
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fd = open(inname, O_RDONLY)) < 0) {
|
||||
/* We can't open it, but we were able to stat it. */
|
||||
if (sb.st_mode & 0002) ckfputs("writeable, ", stdout);
|
||||
if (sb.st_mode & 0111) ckfputs("executable, ", stdout);
|
||||
ckfprintf(stdout, "can't read `%s' (%s).\n",
|
||||
inname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* try looking at the first HOWMANY bytes
|
||||
*/
|
||||
if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) {
|
||||
error("read failed (%s).\n", strerror(errno));
|
||||
/*@notreached@*/
|
||||
}
|
||||
|
||||
if (nbytes == 0)
|
||||
ckfputs(iflag ? "application/x-empty" : "empty", stdout);
|
||||
else {
|
||||
buf[nbytes++] = '\0'; /* null-terminate it */
|
||||
match = tryit(inname, buf, nbytes, zflag);
|
||||
}
|
||||
|
||||
#ifdef BUILTIN_ELF
|
||||
if (match == 's' && nbytes > 5) {
|
||||
/*
|
||||
* We matched something in the file, so this *might*
|
||||
* be an ELF file, and the file is at least 5 bytes long,
|
||||
* so if it's an ELF file it has at least one byte
|
||||
* past the ELF magic number - try extracting information
|
||||
* from the ELF headers that can't easily be extracted
|
||||
* with rules in the magic file.
|
||||
*/
|
||||
tryelf(fd, buf, nbytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (inname != stdname) {
|
||||
#ifdef RESTORE_TIME
|
||||
/*
|
||||
* Try to restore access, modification times if read it.
|
||||
* This is really *bad* because it will modify the status
|
||||
* time of the file... And of course this will affect
|
||||
* backup programs
|
||||
*/
|
||||
# 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);
|
||||
}
|
||||
(void) putchar('\n');
|
||||
}
|
||||
|
|
|
@ -1031,7 +1031,7 @@ sm_match(struct magic *m, uint32_t nmagic, unsigned char *s, int nbytes)
|
|||
/* and any continuations that match */
|
||||
while (m[magindex+1].cont_level != 0 && ++magindex < nmagic) {
|
||||
if (cont_level < m[magindex].cont_level)
|
||||
continue;
|
||||
/*@innercontinue@*/ continue;
|
||||
if (cont_level > m[magindex].cont_level) {
|
||||
/*
|
||||
* We're at the end of the level
|
||||
|
|
|
@ -190,7 +190,7 @@ extern char *sys_errlist[];
|
|||
#define strtoul(a, b, c) strtol(a, b, c)
|
||||
#endif
|
||||
|
||||
/*@-declundef -incondefs @*/
|
||||
/*@-declundef -exportfcn -incondefs @*/
|
||||
/**
|
||||
*/
|
||||
/*@mayexit@*/ /*@only@*/ /*@out@*/
|
||||
|
@ -216,10 +216,12 @@ void * xrealloc (/*@null@*/ /*@only@*/ void * ptr, size_t size)
|
|||
|
||||
/**
|
||||
*/
|
||||
/*@-fcnuse@*/
|
||||
/*@mayexit@*/ /*@only@*/
|
||||
char * xstrdup (const char *str)
|
||||
/*@*/;
|
||||
/*@=declundef =incondefs @*/
|
||||
/*@=fcnuse@*/
|
||||
/*@=declundef =exportfcn=incondefs @*/
|
||||
|
||||
#if HAVE_MCHECK_H
|
||||
#include <mcheck.h>
|
||||
|
@ -247,11 +249,13 @@ extern void muntrace (void) __THROW
|
|||
#endif /* defined(__LCLINT__) */
|
||||
#endif /* HAVE_MCHECK_H */
|
||||
|
||||
#if !defined(__LCLINT__)
|
||||
/* Memory allocation via macro defs to get meaningful locations from mtrace() */
|
||||
#define xmalloc(_size) (malloc(_size) ? : (error("out of memory"), NULL))
|
||||
#define xcalloc(_nmemb, _size) (calloc((_nmemb), (_size)) ? : (error("out of memory"), NULL))
|
||||
#define xrealloc(_ptr, _size) (realloc((_ptr), (_size)) ? : (error("out of memory"), NULL))
|
||||
#define xmalloc(_size) (malloc(_size) ? : vmefail(0))
|
||||
#define xcalloc(_nmemb, _size) (calloc((_nmemb), (_size)) ? : vmefail(0))
|
||||
#define xrealloc(_ptr, _size) (realloc((_ptr), (_size)) ? : vmefail(0))
|
||||
#define xstrdup(_str) (strcpy(xmalloc(strlen(_str)+1), (_str)))
|
||||
#endif
|
||||
|
||||
#if HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
|
|
Loading…
Reference in New Issue