| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 | 
							- /*
 
-  * 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 <stdio.h>
 
- #include <stdlib.h>
 
- #include <string.h>
 
- #include <sys/types.h>
 
- #include <sys/param.h>	/* for MAXPATHLEN */
 
- #include <sys/stat.h>
 
- #include <fcntl.h>	/* for open() */
 
- #ifdef RESTORE_TIME
 
- # if (__COHERENT__ >= 0x420)
 
- #  include <sys/utime.h>
 
- # else
 
- #  ifdef USE_UTIMES
 
- #   include <sys/time.h>
 
- #  else
 
- #   include <utime.h>
 
- #  endif
 
- # endif
 
- #endif
 
- #include <unistd.h>	/* for read() */
 
- #include <netinet/in.h>		/* for byte swapping */
 
- #include "patchlevel.h"
 
- #include "file.h"
 
- #ifndef	lint
 
- FILE_RCSID("@(#)$Id: file.c,v 1.42 1998/09/12 13:17:52 christos Exp $")
 
- #endif	/* lint */
 
- #ifdef S_IFLNK
 
- # define USAGE  "Usage: %s [-vbczL] [-f namefile] [-m magicfiles] file...\n"
 
- #else
 
- # define USAGE  "Usage: %s [-vbcz] [-f namefile] [-m magicfiles] file...\n"
 
- #endif
 
- #ifndef MAGIC
 
- # define MAGIC "/etc/magic"
 
- #endif
 
- int 			/* Global command-line options 		*/
 
- 	debug = 0, 	/* debugging 				*/
 
- 	lflag = 0,	/* follow Symlinks (BSD only) 		*/
 
- 	bflag = 0,	/* brief output format	 		*/
 
- 	zflag = 0;	/* follow (uncompress) compressed files */
 
- int			/* Misc globals				*/
 
- 	nmagic = 0;	/* number of valid magic[]s 		*/
 
- struct  magic *magic;	/* array of magic entries		*/
 
- const char *magicfile;	/* where magic be found 		*/
 
- char *progname;		/* used throughout 			*/
 
- int lineno;		/* line number in the magic file	*/
 
- static void	unwrap		__P((char *fn));
 
- #if 0
 
- static int	byteconv4	__P((int, int, int));
 
- static short	byteconv2	__P((int, int, int));
 
- #endif
 
- int main __P((int, char *[]));
 
- /*
 
-  * main - parse arguments and handle options
 
-  */
 
- int
 
- main(argc, argv)
 
- int argc;
 
- char *argv[];
 
- {
 
- 	int c;
 
- 	int check = 0, didsomefiles = 0, errflg = 0, ret = 0, app = 0;
 
- 	if ((progname = strrchr(argv[0], '/')) != NULL)
 
- 		progname++;
 
- 	else
 
- 		progname = argv[0];
 
- 	if (!(magicfile = getenv("MAGIC")))
 
- 		magicfile = MAGIC;
 
- 	while ((c = getopt(argc, argv, "vbcdf:Lm:z")) != EOF)
 
- 		switch (c) {
 
- 		case 'v':
 
- 			(void) fprintf(stdout, "%s-%d.%d\n", progname,
 
- 				       FILE_VERSION_MAJOR, patchlevel);
 
- 			return 1;
 
- 		case 'b':
 
- 			++bflag;
 
- 			break;
 
- 		case 'c':
 
- 			++check;
 
- 			break;
 
- 		case 'd':
 
- 			++debug;
 
- 			break;
 
- 		case 'f':
 
- 			if (!app) {
 
- 				ret = apprentice(magicfile, check);
 
- 				if (check)
 
- 					exit(ret);
 
- 				app = 1;
 
- 			}
 
- 			unwrap(optarg);
 
- 			++didsomefiles;
 
- 			break;
 
- #ifdef S_IFLNK
 
- 		case 'L':
 
- 			++lflag;
 
- 			break;
 
- #endif
 
- 		case 'm':
 
- 			magicfile = optarg;
 
- 			break;
 
- 		case 'z':
 
- 			zflag++;
 
- 			break;
 
- 		case '?':
 
- 		default:
 
- 			errflg++;
 
- 			break;
 
- 		}
 
- 	if (errflg) {
 
- 		(void) fprintf(stderr, USAGE, progname);
 
- 		exit(2);
 
- 	}
 
- 	if (!app) {
 
- 		ret = apprentice(magicfile, check);
 
- 		if (check)
 
- 			exit(ret);
 
- 		app = 1;
 
- 	}
 
- 	if (optind == argc) {
 
- 		if (!didsomefiles) {
 
- 			(void)fprintf(stderr, USAGE, progname);
 
- 			exit(2);
 
- 		}
 
- 	}
 
- 	else {
 
- 		int i, wid, nw;
 
- 		for (wid = 0, i = optind; i < argc; i++) {
 
- 			nw = strlen(argv[i]);
 
- 			if (nw > wid)
 
- 				wid = nw;
 
- 		}
 
- 		for (; optind < argc; optind++)
 
- 			process(argv[optind], wid);
 
- 	}
 
- 	return 0;
 
- }
 
- /*
 
-  * unwrap -- read a file of filenames, do each one.
 
-  */
 
- static void
 
- unwrap(fn)
 
- char *fn;
 
- {
 
- 	char buf[MAXPATHLEN];
 
- 	FILE *f;
 
- 	int wid = 0, cwid;
 
- 	if (strcmp("-", fn) == 0) {
 
- 		f = stdin;
 
- 		wid = 1;
 
- 	} else {
 
- 		if ((f = fopen(fn, "r")) == NULL) {
 
- 			error("Cannot open `%s' (%s).\n", fn, strerror(errno));
 
- 			/*NOTREACHED*/
 
- 		}
 
- 		while (fgets(buf, MAXPATHLEN, f) != NULL) {
 
- 			cwid = strlen(buf) - 1;
 
- 			if (cwid > wid)
 
- 				wid = cwid;
 
- 		}
 
- 		rewind(f);
 
- 	}
 
- 	while (fgets(buf, MAXPATHLEN, f) != NULL) {
 
- 		buf[strlen(buf)-1] = '\0';
 
- 		process(buf, wid);
 
- 	}
 
- 	(void) fclose(f);
 
- }
 
- #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
 
-  */
 
- void
 
- process(inname, wid)
 
- 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) {
 
- 		    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("empty", stdout);
 
- 	else {
 
- 		buf[nbytes++] = '\0';	/* null-terminate it */
 
- 		match = tryit(buf, nbytes, zflag);
 
- 	}
 
- #ifdef BUILTIN_ELF
 
- 	if (match == 's' && nbytes > 5)
 
- 		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');
 
- }
 
- 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';
 
- 	/* see if it's international language text */
 
- 	if (internatmagic(buf, nb))
 
- 		return 'i';
 
- 	/* abandon hope, all ye who remain here */
 
- 	ckfputs("data", stdout);
 
- 		return '\0';
 
- }
 
 
  |