Split CLI from libraries, create libfmagic.

CVS patchset: 5748
CVS date: 2002/10/02 19:00:31
This commit is contained in:
jbj 2002-10-02 19:00:31 +00:00
parent 1c582f226d
commit 2dfa85a312
7 changed files with 204 additions and 185 deletions

View File

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

View File

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

View File

@ -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) {

View File

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

View File

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

View File

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

View File

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