/* * 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 license of the American Telephone * and Telegraph Company or of the Regents of the University of California. * * Permission is granted to anyone to use this software for any purpose on * any computer system, and to alter it and redistribute it freely, subject * to the following restrictions: * * 1. The author is not responsible for the consequences of use of this * software, no matter how awful, even if they arise from flaws in it. * * 2. The origin of this software must not be misrepresented, either by * explicit claim or by omission. Since few users ever read sources, * credits must appear in the documentation. * * 3. Altered versions must be plainly marked as such, and must not be * misrepresented as being the original software. Since few users * ever read sources, credits must appear in the documentation. * * 4. This notice may not be removed or altered. */ #include #include #include #include #include #include /* for MAXPATHLEN */ #include #include /* for open() */ #ifdef RESTORE_TIME # if (__COHERENT__ >= 0x420) # include # else # ifdef USE_UTIMES # include # else # include # endif # endif #endif #ifdef HAVE_UNISTD_H #include /* for read() */ #endif #ifdef HAVE_LOCALE_H #include #endif #include /* for byte swapping */ #include "file.h" #include "patchlevel.h" #ifndef lint FILE_RCSID("@(#)$Id: file.c,v 1.2 2001/10/22 17:05:36 provos Exp $") #endif /* lint */ #ifdef S_IFLNK # define USAGE "Usage: %s [-bciknsvzL] [-f namefile] [-m magicfiles] file...\n" #else # define USAGE "Usage: %s [-bciknsvz] [-f namefile] [-m magicfiles] file...\n" #endif #ifndef MAGIC # define MAGIC "/etc/magic" #endif #ifndef MAXPATHLEN #define MAXPATHLEN 512 #endif int /* Global command-line options */ noprint = 1, debug = 0, /* debugging */ lflag = 0, /* follow Symlinks (BSD only) */ bflag = 0, /* brief output format */ zflag = 0, /* follow (uncompress) compressed files */ sflag = 0, /* read block special files */ iflag = 0, nobuffer = 0, /* Do not buffer stdout */ kflag = 0; /* Keep going after the first match */ int /* Misc globals */ nmagic = 0; /* number of valid magic[]s */ struct magic *magic; /* array of magic entries */ const char *magicfile = 0; /* where the magic is */ const char *default_magicfile = MAGIC; char *progname; /* used throughout */ int lineno; /* line number in the magic file */ static void unwrap __P((char *fn)); static void usage __P((void)); #if 0 static int byteconv4 __P((int, int, int)); static short byteconv2 __P((int, int, int)); #endif int main __P((int, char *[])); int file_init(void) { int ret; ret = apprentice_memory(magic_mem, strlen(magic_mem)); return (ret); } #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 /* * process - process input file */ int file_process(u_char *data, int nbytes) { int match; unsigned char buf[HOWMANY+1]; /* one extra for terminating '\0' */ if (nbytes > HOWMANY) nbytes = HOWMANY; memcpy(buf, data, nbytes); buf[nbytes++] = '\0'; /* null-terminate it */ match = tryit(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 return (match); } int tryit(buf, nb, zflag) unsigned char *buf; int nb, zflag; { /* try compression stuff */ if (zflag && zmagic(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("data", stdout); return '\0'; } static void usage() { (void)fprintf(stderr, USAGE, progname); (void)fprintf(stderr, "Usage: %s -C [-m magic]\n", progname); exit(1); }