=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/file/file.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- src/usr.bin/file/file.c 1997/01/15 23:42:26 1.4 +++ src/usr.bin/file/file.c 1997/02/09 23:58:22 1.5 @@ -1,4 +1,5 @@ -/* $OpenBSD: file.c,v 1.4 1997/01/15 23:42:26 millert Exp $ */ +/* $OpenBSD: file.c,v 1.5 1997/02/09 23:58:22 millert Exp $ */ + /* * file - find type of a file or files - main program. * @@ -26,7 +27,7 @@ * 4. This notice may not be removed or altered. */ #ifndef lint -static char *moduleid = "$OpenBSD: file.c,v 1.4 1997/01/15 23:42:26 millert Exp $"; +static char *moduleid = "$OpenBSD: file.c,v 1.5 1997/02/09 23:58:22 millert Exp $"; #endif /* lint */ #include @@ -37,15 +38,17 @@ #include #include /* for open() */ #if (__COHERENT__ >= 0x420) -#include +# include #else -#include +# ifdef USE_UTIMES +# include +# else +# include +# endif #endif #include /* for read() */ -#ifdef __ELF__ -#include -#endif +#include /* for byte swapping */ #include "patchlevel.h" #include "file.h" @@ -76,7 +79,11 @@ int lineno; /* line number in the magic file */ -static void unwrap __P((char *fn)); +static void unwrap __P((char *fn)); +#if 0 +static int byteconv4 __P((int, int, int)); +static short byteconv2 __P((int, int, int)); +#endif /* * main - parse arguments and handle options @@ -180,20 +187,25 @@ FILE *f; int wid = 0, cwid; - if ((f = fopen(fn, "r")) == NULL) { - error("Cannot open `%s' (%s).\n", fn, strerror(errno)); - /*NOTREACHED*/ - } + 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; + while (fgets(buf, sizeof(buf), f) != NULL) { + cwid = strlen(buf) - 1; + if (cwid > wid) + wid = cwid; + } + + rewind(f); } - rewind(f); - - while (fgets(buf, MAXPATHLEN, f) != NULL) { + while (fgets(buf, sizeof(buf), f) != NULL) { buf[strlen(buf)-1] = '\0'; process(buf, wid); } @@ -202,7 +214,72 @@ } +#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 @@ -213,7 +290,6 @@ int fd = 0; static const char stdname[] = "standard input"; unsigned char buf[HOWMANY+1]; /* one extra for terminating '\0' */ - struct utimbuf utbuf; struct stat sb; int nbytes = 0; /* number of bytes read from a datafile */ char match = '\0'; @@ -265,56 +341,33 @@ buf[nbytes++] = '\0'; /* null-terminate it */ match = tryit(buf, nbytes, zflag); } -#ifdef __ELF__ - /* - * ELF executables have multiple section headers in arbitrary - * file locations and thus file(1) cannot determine it from easily. - * Instead we traverse thru all section headers until a symbol table - * one is found or else the binary is stripped. - * XXX: This will not work for binaries of a different byteorder. - * Should come up with a better fix. - */ - if (match == 's' && nbytes > sizeof (Elf32_Ehdr) && - buf[EI_MAG0] == ELFMAG0 && - buf[EI_MAG1] == ELFMAG1 && - buf[EI_MAG2] == ELFMAG2 && - buf[EI_MAG3] == ELFMAG3) { +#ifdef BUILTIN_ELF + if (match == 's' && nbytes > 5) + tryelf(fd, buf, nbytes); +#endif - union { - long l; - char c[sizeof (long)]; - } u; - Elf32_Ehdr elfhdr; - int stripped = 1; - - u.l = 1; - (void) memcpy(&elfhdr, buf, sizeof elfhdr); - + if (inname != stdname) { +#ifdef RESTORE_TIME /* - * If the system byteorder does not equal the object byteorder - * then don't test. + * Try to restore access, modification times if read it. */ - if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5]) { - if (lseek(fd, elfhdr.e_shoff, SEEK_SET)<0) - error("lseek failed (%s).\n", strerror(errno)); +# ifdef USE_UTIMES + struct timeval utsbuf[2]; + utsbuf[0].tv_sec = sb.st_atime; + utsbuf[1].tv_sec = sb.st_mtime; - for ( ; elfhdr.e_shnum ; elfhdr.e_shnum--) { - if (read(fd, buf, elfhdr.e_shentsize)<0) - error("read failed (%s).\n", strerror(errno)); - if (((Elf32_Shdr *)&buf)->sh_type == SHT_SYMTAB) { - stripped = 0; - break; - } - } - if (stripped) - (void) printf (", stripped"); - } - } -#endif + (void) utimes(inname, utsbuf); /* don't care if loses */ +# else + struct utimbuf utbuf; - if (inname != stdname) + 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'); } @@ -335,6 +388,10 @@ /* 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);