Updates file(1) to version 3.22 by way to NetBSD.
authormillert <millert@openbsd.org>
Sun, 9 Feb 1997 23:58:12 +0000 (23:58 +0000)
committermillert <millert@openbsd.org>
Sun, 9 Feb 1997 23:58:12 +0000 (23:58 +0000)
22 files changed:
usr.bin/Makefile
usr.bin/file/Makefile
usr.bin/file/apprentice.c
usr.bin/file/ascmagic.c
usr.bin/file/compress.c
usr.bin/file/file.1
usr.bin/file/file.c
usr.bin/file/file.h
usr.bin/file/fsmagic.c
usr.bin/file/internat.c [new file with mode: 0644]
usr.bin/file/is_tar.c
usr.bin/file/magdir/Localstuff
usr.bin/file/magic.5
usr.bin/file/names.h
usr.bin/file/patchlevel.h
usr.bin/file/print.c
usr.bin/file/readelf.c [new file with mode: 0644]
usr.bin/file/readelf.h [new file with mode: 0644]
usr.bin/file/softmagic.c
usr.bin/file/tar.h
usr.bin/fmt/fmt.1
usr.bin/rdist/os-openbsd.h

index ef002f7..b79d4e3 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.37 1997/01/21 04:34:32 millert Exp $
+#      $OpenBSD: Makefile,v 1.38 1997/02/09 23:58:12 millert Exp $
 #      $NetBSD: Makefile,v 1.62 1996/03/10 05:45:43 thorpej Exp $
 #      from: @(#)Makefile      5.8.1.1 (Berkeley) 5/8/91
 
@@ -11,9 +11,9 @@ SUBDIR= apply apropos arch asa at aucat awk banner basename bdes biff cal \
        fold from fsplit fstat ftp gencat getconf getopt head hexdump id \
        indent \
        info_mkdb ipcrm ipcs join jot kdump ktrace lam last lastcomm leave \
-       less lex lndir locate lock logger login logname look lorder m4 machine \
-       mail make man mesg mk_cmds mkdep mkfifo mkstr mktemp modstat msgs nc \
-       netstat newsyslog \
+       less lex lndir locate lock logger login.millert logname look lorder m4 \
+       machine mail make man mesg mk_cmds mkdep mkfifo mkstr mktemp modstat \
+       msgs nc netstat newsyslog \
        nfsstat nice nohup oldrdist pagesize passwd paste patch pr printenv \
        printf quota rdist rdistd renice rev rlogin rpcgen rpcinfo rs \
        rsh rup ruptime rusers rwall rwho \
index 436ed0e..705f597 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.5 1996/12/08 14:32:25 downsj Exp $
+#      $OpenBSD: Makefile,v 1.6 1997/02/09 23:58:15 millert Exp $
 
 MAGIC=         /etc/magic
 MAGICOWN=      root
@@ -7,8 +7,8 @@ MAGICMODE=      444
 
 PROG=          file
 SRCS=          file.c apprentice.c fsmagic.c softmagic.c ascmagic.c is_tar.c \
-               print.c compress.c
-CFLAGS+=       -DMAGIC='"$(MAGIC)"'
+               print.c compress.c readelf.c internat.c
+CFLAGS+=       -DMAGIC='"$(MAGIC)"' -DUSE_UTIMES
 MAN=           file.1 magic.5
 
 CLEANFILES+=   magic
index c6311b8..8a5ccbe 100644 (file)
@@ -1,4 +1,5 @@
-/*     $OpenBSD: apprentice.c,v 1.3 1996/06/26 05:32:54 deraadt Exp $  */
+/*     $OpenBSD: apprentice.c,v 1.4 1997/02/09 23:58:16 millert Exp $  */
+
 /*
  * apprentice - make one pass through /etc/magic, learning its secrets.
  *
@@ -34,7 +35,7 @@
 #include "file.h"
 
 #ifndef        lint
-static char *moduleid = "$OpenBSD: apprentice.c,v 1.3 1996/06/26 05:32:54 deraadt Exp $";
+static char *moduleid = "$OpenBSD: apprentice.c,v 1.4 1997/02/09 23:58:16 millert Exp $";
 #endif /* lint */
 
 #define        EATAB {while (isascii((unsigned char) *l) && \
@@ -133,10 +134,10 @@ int check;                        /* non-zero? checking-only run. */
 /*
  * extend the sign bit if the comparison is to be signed
  */
-unsigned long
+uint32
 signextend(m, v)
 struct magic *m;
-unsigned long v;
+uint32 v;
 {
        if (!(m->flag & UNSIGNED))
                switch(m->type) {
@@ -159,7 +160,7 @@ unsigned long v;
                case LONG:
                case BELONG:
                case LELONG:
-                       v = (long) v;
+                       v = (int32) v;
                        break;
                case STRING:
                        break;
@@ -210,6 +211,10 @@ int *ndx, check;
                ++l;            /* step over */
                m->flag |= INDIR;
        }
+       if (m->cont_level != 0 && *l == '&') {
+                ++l;            /* step over */
+                m->flag |= ADD;
+        }
 
        /* get offset, then skip over it */
        m->offset = (int) strtoul(l,&t,0);
@@ -491,21 +496,16 @@ int       plen, *slen;
                                *p++ = (char)val;
                                break;
 
-                       /* \x and up to 3 hex digits */
+                       /* \x and up to 2 hex digits */
                        case 'x':
                                val = 'x';      /* Default if no digits */
                                c = hextoint(*s++);     /* Get next char */
                                if (c >= 0) {
                                        val = c;
                                        c = hextoint(*s++);
-                                       if (c >= 0) {
+                                       if (c >= 0)
                                                val = (val << 4) + c;
-                                               c = hextoint(*s++);
-                                               if (c >= 0) {
-                                                       val = (val << 4) + c;
-                                               } else
-                                                       --s;
-                                       } else
+                                       else
                                                --s;
                                } else
                                        --s;
index 455f304..9caa50e 100644 (file)
@@ -1,4 +1,5 @@
-/*     $OpenBSD: ascmagic.c,v 1.2 1996/06/26 05:32:54 deraadt Exp $    */
+/*     $OpenBSD: ascmagic.c,v 1.3 1997/02/09 23:58:18 millert Exp $    */
+
 /*
  * ASCII magic -- file types that we know based on keywords
  * that can appear anywhere in the file.
@@ -36,7 +37,7 @@
 #include "names.h"
 
 #ifndef        lint
-static char *moduleid = "$OpenBSD: ascmagic.c,v 1.2 1996/06/26 05:32:54 deraadt Exp $";
+static char *moduleid = "$OpenBSD: ascmagic.c,v 1.3 1997/02/09 23:58:18 millert Exp $";
 #endif /* lint */
 
                        /* an optimisation over plain strcmp() */
@@ -88,6 +89,13 @@ int nbytes;  /* size actually read */
                return 1;
        }
 
+
+       /* Make sure we are dealing with ascii text before looking for tokens */
+       for (i = 0; i < nbytes; i++) {
+               if (!isascii(buf[i]))
+                       return 0;       /* not all ASCII */
+       }
+
        /* look for tokens from names.h - this is expensive! */
        /* make a copy of the buffer here because strtok() will destroy it */
        s = (unsigned char*) memcpy(nbuf, buf, nbytes);
@@ -106,12 +114,6 @@ int nbytes;        /* size actually read */
                }
        }
 
-
-       for (i = 0; i < nbytes; i++) {
-               if (!isascii(buf[i]))
-                       return 0;       /* not all ASCII */
-       }
-
        /* all else fails, but it is ASCII... */
        ckfputs("ASCII text", stdout);
        if (has_escapes) {
index c6fe63c..bde1ff4 100644 (file)
@@ -1,4 +1,5 @@
-/*     $OpenBSD: compress.c,v 1.2 1996/06/26 05:32:55 deraadt Exp $    */
+/*     $OpenBSD: compress.c,v 1.3 1997/02/09 23:58:19 millert Exp $    */
+
 /*
  * compress routines:
  *     zmagic() - returns 0 if not recognized, uncompresses and prints
index 706f08e..35e9b77 100644 (file)
@@ -1,5 +1,5 @@
-.\" $OpenBSD: file.1,v 1.3 1996/06/26 05:32:56 deraadt Exp $
-.TH FILE 1 "Copyright but distributable"
+.\" $OpenBSD: file.1,v 1.4 1997/02/09 23:58:20 millert Exp $
+.TH FILE 1 "Copyrighted but distributable"
 .SH NAME
 file
 \- determine file type
@@ -16,7 +16,10 @@ namefile ]
 magicfiles ]
 file ...
 .SH DESCRIPTION
-.I File
+This manual page documents version 3.22 of the
+.B file
+command.
+.B File
 tests each argument in an attempt to classify it.
 There are three sets of tests, performed in this order:
 filesystem tests, magic number tests, and language tests.
@@ -26,8 +29,11 @@ test that succeeds causes the file type to be printed.
 .PP
 The type printed will usually contain one of the words
 .B text
-(the file contains only ASCII characters and is 
-probably safe to read on an ASCII terminal),
+(the file contains only
+.SM ASCII
+characters and is probably safe to read on an
+.SM ASCII
+terminal),
 .B executable
 (the file contains the result of compiling a program
 in a form understandable to some \s-1UNIX\s0 kernel or another),
@@ -46,7 +52,7 @@ Don't do as Berkeley did \- change ``shell commands text''
 to ``shell script''.
 .PP
 The filesystem tests are based on examining the return from a
-.IR stat (2)
+.BR stat (2)
 system call.
 The program checks to see if the file is empty,
 or if it's some sort of special file.
@@ -55,16 +61,16 @@ Any known file types appropriate to the system you are running on
 implement them)
 are intuited if they are defined in
 the system header file
-.BR sys/stat.h  .
+.IR sys/stat.h  .
 .PP
 The magic number tests are used to check for files with data in
 particular fixed formats.
 The canonical example of this is a binary executable (compiled program)
-.B a.out
+.I a.out
 file, whose format is defined in 
-.B a.out.h
+.I a.out.h
 and possibly
-.B exec.h
+.I exec.h
 in the standard include directory.
 These files have a `magic number' stored in a particular place
 near the beginning of the file that tells the \s-1UNIX\s0 operating system
@@ -78,21 +84,23 @@ The information in these files is read from the magic file
 If an argument appears to be an
 .SM ASCII 
 file,
-.I file
+.B file
 attempts to guess its language.
-The language tests look for particular strings (cf \fInames.h\fP)
+The language tests look for particular strings (cf
+.IR names.h )
 that can appear anywhere in the first few blocks of a file.
 For example, the keyword
 .B .br
-indicates that the file is most likely a troff input file,
-just as the keyword 
+indicates that the file is most likely a
+.BR troff (1)
+input file, just as the keyword 
 .B struct
 indicates a C program.
 These tests are less reliable than the previous
 two groups, so they are performed last.
 The language test routines also test for some miscellany
 (such as 
-.I tar
+.BR tar (1)
 archives) and determine whether an unknown file should be
 labelled as `ascii text' or `data'. 
 .SH OPTIONS
@@ -125,7 +133,7 @@ to test the standard input, use ``-'' as a filename argument.
 .TP 8
 .B \-L
 option causes symlinks to be followed, as the like-named option in
-.IR ls (1).
+.BR ls (1).
 (on systems that support symbolic links).
 .SH FILES
 .I /etc/magic
@@ -135,10 +143,10 @@ The environment variable
 .B MAGIC
 can be used to set the default magic number files.
 .SH SEE ALSO
-.IR magic (5)
+.BR magic (5)
 \- description of magic file format.
 .br
-.IR Strings (1), " od" (1)
+.BR strings (1), " od" (1)
 \- tools for examining non-textfiles.
 .SH STANDARDS CONFORMANCE
 This program is believed to exceed the System V Interface Definition
@@ -171,7 +179,7 @@ in an existing magic file would have to be changed to
 .br
 .PP
 SunOS releases 3.2 and later from Sun Microsystems include a
-.IR file (1)
+.BR file (1)
 command derived from the System V one, but with some extensions.
 My version differs from Sun's only in minor ways.
 It includes the extension of the `&' operator, used as,
@@ -190,15 +198,15 @@ The order of entries in the magic file is significant.
 Depending on what system you are using, the order that
 they are put together may be incorrect.
 If your old
-.I file
+.B file
 command uses a magic file,
 keep the old magic file around for comparison purposes
 (rename it to 
 .IR /etc/magic.orig ).
 .SH HISTORY
 There has been a 
-.I file
-command in every UNIX since at least Research Version 6
+.B file
+command in every \s-1UNIX\s0 since at least Research Version 6
 (man page dated January, 1975).
 The System V version introduced one significant major change:
 the external list of magic number types.
@@ -227,7 +235,7 @@ put the ``old-style'' `&'
 operator back the way it was, because 1) Rob McMahon's change broke the
 previous style of usage, 2) the SunOS ``new-style'' `&' operator,
 which this version of
-.I file
+.B file
 supports, also handles `x&y op z', and 3) Rob's change wasn't documented
 in any case;
 .PP
@@ -236,11 +244,11 @@ put in multiple levels of `>';
 put in ``beshort'', ``leshort'', etc. keywords to look at numbers in the
 file in a specific byte order, rather than in the native byte order of
 the process running
-.IR file .
+.BR file .
 .RE
 .PP
 Changes by Ian Darwin and various authors including
-Christos Zoulas (christos@ee.cornell.edu), 1990-1992.
+Christos Zoulas (christos@deshaw.com), 1990-1997.
 .SH LEGAL NOTICE
 Copyright (c) Ian F. Darwin, Toronto, Canada,
 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993.
@@ -284,33 +292,42 @@ The files
 and
 .I is_tar.c
 were written by John Gilmore from his public-domain
-.I tar
+.B tar
 program, and are not covered by the above restrictions.
 .SH BUGS
 There must be a better way to automate the construction of the Magic
 file from all the glop in Magdir. What is it?
 Better yet, the magic file should be compiled into binary (say,
-.IR ndbm (3)
-or, better yet, fixed-length ASCII strings 
-for use in heterogenous network environments) for faster startup.
+.BR ndbm (3)
+or, better yet, fixed-length
+.SM ASCII
+strings for use in heterogenous network environments) for faster startup.
 Then the program would run as fast as the Version 7 program of the same name,
 with the flexibility of the System V version.
 .PP
-.I File
+.B File
 uses several algorithms that favor speed over accuracy,
-thus it can be misled about the contents of ASCII files.
+thus it can be misled about the contents of
+.SM ASCII
+files.
 .PP
-The support for ASCII files (primarily for programming languages)
+The support for
+.SM ASCII
+files (primarily for programming languages)
 is simplistic, inefficient and requires recompilation to update.
 .PP
 There should be an ``else'' clause to follow a series of continuation lines.
 .PP
 The magic file and keywords should have regular expression support.
-Their use of ASCII TAB as a field delimiter is ugly and makes
+Their use of
+.SM "ASCII TAB"
+as a field delimiter is ugly and makes
 it hard to edit the files, but is entrenched.
 .PP
 It might be advisable to allow upper-case letters in keywords
-for e.g., troff commands vs man page macros.
+for e.g.,
+.BR troff (1)
+commands vs man page macros.
 Regular expression support would make this easy.
 .PP
 The program doesn't grok \s-2FORTRAN\s0.
@@ -343,6 +360,6 @@ This manual page, and particularly this section, is too long.
 .SH AVAILABILITY
 You can obtain the original author's latest version by anonymous FTP
 on
-.B tesla.ee.cornell.edu
+.B ftp.deshaw.com
 in the directory
-.BR /pub/file-X.YY.tar.gz
+.I /pub/file/file-X.YY.tar.gz
index fc11439..95eeb94 100644 (file)
@@ -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 <stdio.h>
@@ -37,15 +38,17 @@ static char *moduleid = "$OpenBSD: file.c,v 1.4 1997/01/15 23:42:26 millert Exp
 #include <sys/stat.h>
 #include <fcntl.h>     /* for open() */
 #if (__COHERENT__ >= 0x420)
-#include <sys/utime.h>
+# include <sys/utime.h>
 #else
-#include <utime.h>
+# ifdef USE_UTIMES
+#  include <sys/time.h>
+# else
+#  include <utime.h>
+# endif
 #endif
 #include <unistd.h>    /* for read() */
 
-#ifdef __ELF__
-#include <elf.h>
-#endif
+#include <netinet/in.h>                /* for byte swapping */
 
 #include "patchlevel.h"
 #include "file.h"
@@ -76,7 +79,11 @@ char *progname;              /* used throughout                      */
 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 @@ char *fn;
        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,6 +214,71 @@ char *fn;
 }
 
 
+#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
  */
@@ -213,7 +290,6 @@ int wid;
        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 @@ int wid;
                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) {
-
-               union {
-                       long l;
-                       char c[sizeof (long)];
-               } u;
-               Elf32_Ehdr elfhdr;
-               int stripped = 1;
 
-               u.l = 1;
-               (void) memcpy(&elfhdr, buf, sizeof elfhdr);
+#ifdef BUILTIN_ELF
+       if (match == 's' && nbytes > 5)
+               tryelf(fd, buf, nbytes);
+#endif
 
+       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));
-
-                   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");
-               }
-       }
+# 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
-
-       if (inname != stdname)
                (void) close(fd);
+       }
        (void) putchar('\n');
 }
 
@@ -336,6 +389,10 @@ int nb, zflag;
        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';
index 0fa7a83..579eec2 100644 (file)
@@ -1,4 +1,5 @@
-/* * @(#)$OpenBSD: file.h,v 1.2 1996/06/26 05:32:57 deraadt Exp $*/
+/*     $OpenBSD: file.h,v 1.3 1997/02/09 23:58:23 millert Exp $        */
+
 /*
  * file.h - definitions for file(1) program
  *
  * 4. This notice may not be removed or altered.
  */
 
+#ifndef __file_h__
+#define __file_h__
+
+typedef int32_t int32;
+typedef u_int32_t uint32;
+
 #ifndef HOWMANY
 # define HOWMANY 8192          /* how much of the file to look at */
 #endif
@@ -37,12 +44,13 @@ struct magic {
        short flag;             
 #define INDIR  1               /* if '>(...)' appears,  */
 #define        UNSIGNED 2              /* comparison is unsigned */
+#define ADD    4               /* if '>&' appears,  */
        short cont_level;       /* level of ">" */
        struct {
                char type;      /* byte short long */
-               long offset;    /* offset from indirection */
+               int32 offset;   /* offset from indirection */
        } in;
-       long offset;            /* offset to magic number */
+       int32 offset;           /* offset to magic number */
        unsigned char reln;     /* relation (0=eq, '>'=gt, etc) */
        char type;              /* int, short, long or string. */
        char vallen;            /* length of string value, if any */
@@ -60,12 +68,12 @@ struct magic {
        union VALUETYPE {
                unsigned char b;
                unsigned short h;
-               unsigned long l;
+               uint32 l;
                char s[MAXstring];
                unsigned char hs[2];    /* 2 bytes of a fixed-endian "short" */
                unsigned char hl[4];    /* 2 bytes of a fixed-endian "long" */
        } value;                /* either number or string */
-       unsigned long mask;     /* mask before comparison with value */
+       uint32 mask;    /* mask before comparison with value */
        char nospflag;          /* supress space character */
        char desc[MAXDESC];     /* description */
 };
@@ -97,8 +105,9 @@ extern int   softmagic               __P((unsigned char *, int));
 extern int   tryit             __P((unsigned char *, int, int));
 extern int   zmagic            __P((unsigned char *, int));
 extern void  ckfprintf         __P((FILE *, const char *, ...));
-extern unsigned long signextend        __P((struct magic *, unsigned long));
-
+extern uint32 signextend       __P((struct magic *, unsigned int32));
+extern int internatmagic       __P((unsigned char *, int));
+extern void tryelf             __P((int, char *, int));
 
 
 extern int errno;              /* Some unixes don't define this..      */
@@ -118,7 +127,16 @@ extern int lflag;          /* follow symbolic links?               */
 extern int optind;             /* From getopt(3)                       */
 extern char *optarg;
 
-#if !defined(__STDC__) || defined(sun) || defined(__sun__) || defined(__convex__)
+#if defined(sun) || defined(__sun__) || defined (__sun)
+# if defined(__svr4) || defined (__SVR4) || defined(__svr4__)
+#  define SOLARIS
+# else
+#  define SUNOS
+# endif
+#endif
+
+
+#if !defined(__STDC__) || defined(SUNOS) || defined(__convex__)
 extern int sys_nerr;
 extern char *sys_errlist[];
 #define strerror(e) \
@@ -129,3 +147,5 @@ extern char *sys_errlist[];
 #ifndef MAXPATHLEN
 #define        MAXPATHLEN      512
 #endif
+
+#endif /* __file_h__ */
index 33cd2db..f5ba6ee 100644 (file)
@@ -1,4 +1,5 @@
-/*     $OpenBSD: fsmagic.c,v 1.2 1996/06/26 05:32:57 deraadt Exp $     */
+/*     $OpenBSD: fsmagic.c,v 1.3 1997/02/09 23:58:24 millert Exp $     */
+
 /*
  * fsmagic - magic based on filesystem info - directory, special files, etc.
  *
 #include <sys/stat.h>
 #include <unistd.h>
 #include <stdlib.h>
+#ifndef major
+# if defined(__SVR4) || defined(_SVR4_SOURCE)
+#  include <sys/mkdev.h>
+# endif
+#endif
 #ifndef        major                   /* if `major' not defined in types.h, */
 #include <sys/sysmacros.h>     /* try this one. */
 #endif
@@ -46,7 +52,7 @@
 #include "file.h"
 
 #ifndef        lint
-static char *moduleid = "$OpenBSD: fsmagic.c,v 1.2 1996/06/26 05:32:57 deraadt Exp $";
+static char *moduleid = "$OpenBSD: fsmagic.c,v 1.3 1997/02/09 23:58:24 millert Exp $";
 #endif /* lint */
 
 int
@@ -84,12 +90,12 @@ struct stat *sb;
                ckfputs("directory", stdout);
                return 1;
        case S_IFCHR:
-               (void) printf("character special (%d/%d)",
-                       major(sb->st_rdev), minor(sb->st_rdev));
+               (void) printf("character special (%ld/%ld)",
+                       (long) major(sb->st_rdev), (long) minor(sb->st_rdev));
                return 1;
        case S_IFBLK:
-               (void) printf("block special (%d/%d)",
-                       major(sb->st_rdev), minor(sb->st_rdev));
+               (void) printf("block special (%ld/%ld)",
+                       (long) major(sb->st_rdev), (long) minor(sb->st_rdev));
                return 1;
        /* TODO add code to handle V7 MUX and Blit MUX files */
 #ifdef S_IFIFO
diff --git a/usr.bin/file/internat.c b/usr.bin/file/internat.c
new file mode 100644 (file)
index 0000000..6ffe9e3
--- /dev/null
@@ -0,0 +1,75 @@
+/*     $OpenBSD: internat.c,v 1.1 1997/02/09 23:58:26 millert Exp $    */
+
+#include <string.h>
+#include <sys/types.h>
+
+#include "file.h"
+
+#define F 0
+#define T 1
+
+/*
+ * List of characters that look "reasonable" in international
+ * language texts.  That's almost all characters :), except a
+ * few in the control range of ASCII (all the known international
+ * charactersets share the bottom half with ASCII).
+ */
+static char maybe_internat[256] = {
+       F, F, F, F, F, F, F, F, T, T, T, T, T, T, F, F,  /* 0x0X */
+       F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F,  /* 0x1X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x2X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x3X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x4X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x5X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x6X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F,  /* 0x7X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x8X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x9X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0xaX */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0xbX */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0xcX */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0xdX */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0xeX */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T   /* 0xfX */
+};
+
+/* Maximal length of a line we consider "reasonable". */
+#define MAXLINELEN 300
+
+int
+internatmagic(buf, nbytes)
+       unsigned char *buf;
+       int nbytes;
+{
+       int i;
+       unsigned char *cp;
+
+       nbytes--;
+
+       /* First, look whether there are "unreasonable" characters. */
+       for (i = 0, cp = buf; i < nbytes; i++, cp++)
+               if (!maybe_internat[*cp])
+                       return 0;
+
+       /*
+        * Now, look whether the file consists of lines of
+        * "reasonable" length.
+        */
+
+       for (i = 0; i < nbytes;) {
+               cp = memchr(buf, '\n', nbytes - i);
+               if (cp == NULL) {
+                       /* Don't fail if we hit the end of buffer. */
+                       if (i + MAXLINELEN >= nbytes)
+                               break;
+                       else
+                               return 0;
+               }
+               if (cp - buf > MAXLINELEN)
+                       return 0;
+               i += (cp - buf + 1);
+               buf = cp + 1;
+       }
+       ckfputs("International language text", stdout);
+       return 1;
+}
index c6ebe06..ec10f41 100644 (file)
@@ -1,4 +1,5 @@
-/*     $OpenBSD: is_tar.c,v 1.2 1996/06/26 05:32:58 deraadt Exp $      */
+/*     $OpenBSD: is_tar.c,v 1.3 1997/02/09 23:58:27 millert Exp $      */
+
 /*
  * is_tar() -- figure out whether file is a tar archive.
  *
@@ -19,9 +20,9 @@
 #define        isodigit(c)     ( ((c) >= '0') && ((c) <= '7') )
 
 #if    defined(__STDC__) || defined(__cplusplus)
-static long from_oct(int, char*);      /* Decode octal number */
+static int from_oct(int, char*);       /* Decode octal number */
 #else
-static long from_oct();
+static int from_oct();
 #endif
 
 /*
@@ -37,7 +38,7 @@ int nbytes;
 {
        register union record *header = (union record *)buf;
        register int    i;
-       register long   sum, recsum;
+       register int    sum, recsum;
        register char   *p;
 
        if (nbytes < sizeof(union record))
@@ -75,12 +76,12 @@ int nbytes;
  *
  * Result is -1 if the field is invalid (all blank, or nonoctal).
  */
-static long
+static int
 from_oct(digs, where)
        register int    digs;
        register char   *where;
 {
-       register long   value;
+       register int    value;
 
        while (isspace(*where)) {               /* Skip spaces */
                where++;
index 9c4d992..c20418c 100644 (file)
@@ -1,7 +1,6 @@
-# $OpenBSD: Localstuff,v 1.2 1996/06/26 05:33:03 deraadt Exp $
-
 #------------------------------------------------------------------------------
 # Localstuff:  file(1) magic for locally observed files
 #
+# $OpenBSD: Localstuff,v 1.3 1997/02/09 23:58:40 millert Exp $
 # Add any locally observed files here.  Remember:
 # text if readable, executable if runnable binary, data if unreadable.
index bd93f5e..26cece4 100644 (file)
@@ -1,17 +1,20 @@
-.\" @(#)$OpenBSD: magic.5,v 1.2 1996/06/26 05:32:59 deraadt Exp $
+.\" $OpenBSD: magic.5,v 1.3 1997/02/09 23:58:28 millert Exp $
+.\" install as magic.4 on USG, magic.5 on V7 or Berkeley systems.
 .TH MAGIC 5 "Public Domain"
-.\" install as magic.5 on USG, magic.5 on V7 or Berkeley systems.
 .SH NAME
 magic \- file command's magic number file
 .SH DESCRIPTION
-The
-.IR file (1)
+This manual page documents the format of the magic file as
+used by the
+.BR file (1)
+command, version 3.22. The
+.B file
 command identifies the type of a file using,
 among other tests,
 a test for whether the file begins with a certain
 .IR "magic number" .
 The file
-.B /etc/magic
+.I /etc/magic
 specifies what magic numbers are to be tested for,
 what message to print if a particular magic number is found,
 and additional information to extract from the file.
@@ -114,7 +117,7 @@ then presumably print that string, by doing
 .IP message
 The message to be printed if the comparison succeeds.  If the string
 contains a
-.IR printf (3S)
+.BR printf (3S)
 format specification, the value from the file (with any specified masking
 performed) is printed using the message as the format string.
 .PP
@@ -157,6 +160,15 @@ type specifier. To that number the value of
 .I y
 is added and the result is used as an offset in the file. The default type
 if one is not specified is long.
+.PP
+Sometimes you do not know the exact offset as this depends on the length of
+preceding fields. You can specify an offset relative to the end of the
+last uplevel field (of course this may only be done for sublevel tests, i.e.
+test beginning with 
+.B >
+). Such a relative offset is specified using
+.B &
+as a prefix to the offset.
 .SH BUGS
 The formats 
 .IR long ,
@@ -177,7 +189,7 @@ a system on which the lengths are invariant.
 There is (currently) no support for specified-endian data to be used in
 indirect offsets.
 .SH SEE ALSO
-.IR file (1)
+.BR file (1)
 \- the command that reads this file.
 .\"
 .\" From: guy@sun.uucp (Guy Harris)
index 7d0f2da..23c99c8 100644 (file)
@@ -1,4 +1,5 @@
-/* * $OpenBSD: names.h,v 1.2 1996/06/26 05:32:59 deraadt Exp $*/
+/*     $OpenBSD: names.h,v 1.3 1997/02/09 23:58:29 millert Exp $       */
+
 /*
  * Names.h - names and types used by ascmagic in file(1).
  * These tokens are here because they can appear anywhere in
  * Written by Ian F. Darwin.
  *
  * See LEGAL.NOTICE
- *
  */
 
 /* these types are used to index the table 'types': keep em in sync! */
 #define L_C    0               /* first and foremost on UNIX */
-#define        L_FORT  1               /* the oldest one */
-#define L_MAKE 2               /* Makefiles */
-#define L_PLI  3               /* PL/1 */
-#define L_MACH 4               /* some kinda assembler */
-#define L_ENG  5               /* English */
-#define        L_PAS   6               /* Pascal */
-#define        L_MAIL  7               /* Electronic mail */
-#define        L_NEWS  8               /* Usenet Netnews */
+#define L_CC   1               /* Bjarne's postincrement */
+#define        L_FORT  2               /* the oldest one */
+#define L_MAKE 3               /* Makefiles */
+#define L_PLI  4               /* PL/1 */
+#define L_MACH 5               /* some kinda assembler */
+#define L_ENG  6               /* English */
+#define        L_PAS   7               /* Pascal */
+#define        L_MAIL  8               /* Electronic mail */
+#define        L_NEWS  9               /* Usenet Netnews */
 
 static char *types[] = {
        "C program text",
+       "C++ program text",
        "FORTRAN program text",
        "make commands text" ,
        "PL/1 program text",
@@ -43,6 +45,12 @@ static struct names {
 } names[] = {
        /* These must be sorted by eye for optimal hit rate */
        /* Add to this list only after substantial meditation */
+       {"//",          L_CC},
+       {"template",    L_CC},
+       {"virtual",     L_CC},
+       {"class",       L_CC},
+       {"public:",     L_CC},
+       {"private:",    L_CC},
        {"/*",          L_C},   /* must precede "The", "the", etc. */
        {"#include",    L_C},
        {"char",        L_C},
index 0109d13..ac808a7 100644 (file)
@@ -1,23 +1,33 @@
-/* * $OpenBSD: patchlevel.h,v 1.3 1996/06/26 05:33:00 deraadt Exp $*/
+/*     $OpenBSD: patchlevel.h,v 1.4 1997/02/09 23:58:31 millert Exp $  */
+
 #define        FILE_VERSION_MAJOR      3
-#define        patchlevel              19
+#define        patchlevel              22
 
 /*
  * Patchlevel file for Ian Darwin's MAGIC command.
  *
- * $Log: patchlevel.h,v $
- * Revision 1.3  1996/06/26 05:33:00  deraadt
- * rcsid
+ * Log: patchlevel.h,v
+ * Revision 1.22  1997/01/15 17:23:24  christos
+ * - add support for elf core files: find the program name under SVR4 [Ken Pizzini]
+ * - print strings only up to the first carriage return [various]
+ * - freebsd international ascii support [J Wunsch]
+ * - magic fixes and additions [Guy Harris]
+ * - 64 bit fixes [Larry Schwimmer]
+ * - support for both utime and utimes, but don't restore file access times
+ *   by default [various]
+ * - \xXX only takes 2 hex digits, not 3.
+ * - re-implement support for core files [Guy Harris]
  *
- * Revision 1.2  1995/12/14 03:30:04  deraadt
- * update from netbsd
+ * Revision 1.21  1996/10/05 18:15:29  christos
+ * Segregate elf stuff and conditionally enable it with -DBUILTIN_ELF
+ * More magic fixes
  *
- * Revision 1.5  1995/10/27 23:33:21  christos
- * Update to file-3.19.
- * - Magic fixes
- * - MAGIC environment variable processing
- * - Better LEGAL.NOTICE
- * - -m magic : separated list of magic files processing
+ * Revision 1.20  1996/06/22  22:15:52  christos
+ * - support relative offsets of the form >&
+ * - fix bug with truncating magic strings that contain \n
+ * - file -f - did not read from stdin as documented
+ * - support elf file parsing using our own elf support.
+ * - as always magdir fixes and additions.
  *
  * Revision 1.19  1995/10/27  23:14:46  christos
  * Ability to parse colon separated list of magic files
index 839bf04..089d1f2 100644 (file)
@@ -1,4 +1,5 @@
-/*     $OpenBSD: print.c,v 1.2 1996/06/26 05:33:00 deraadt Exp $       */
+/*     $OpenBSD: print.c,v 1.3 1997/02/09 23:58:32 millert Exp $       */
+
 /*
  * print.c - debugging printout routines
  *
@@ -40,7 +41,7 @@
 #include "file.h"
 
 #ifndef lint
-static char *moduleid = "$OpenBSD: print.c,v 1.2 1996/06/26 05:33:00 deraadt Exp $";
+static char *moduleid = "$OpenBSD: print.c,v 1.3 1997/02/09 23:58:32 millert Exp $";
 #endif  /* lint */
 
 #define SZOF(a)        (sizeof(a) / sizeof(a[0]))
@@ -58,7 +59,7 @@ struct magic *m;
                       m->offset);
 
        if (m->flag & INDIR)
-               (void) fprintf(stderr, "(%s,%ld),",
+               (void) fprintf(stderr, "(%s,%d),",
                               (m->in.type >= 0 && m->in.type < SZOF(typ)) ? 
                                        typ[(unsigned char) m->in.type] :
                                        "*bad*",
@@ -69,7 +70,7 @@ struct magic *m;
                                typ[(unsigned char) m->type] : 
                                "*bad*");
        if (m->mask != ~0L)
-               (void) fprintf(stderr, " & %.8lx", m->mask);
+               (void) fprintf(stderr, " & %.8x", m->mask);
 
        (void) fprintf(stderr, ",%c", m->reln);
 
@@ -82,7 +83,7 @@ struct magic *m;
            case LELONG:
            case BESHORT:
            case BELONG:
-                   (void) fprintf(stderr, "%ld", m->value.l);
+                   (void) fprintf(stderr, "%d", m->value.l);
                    break;
            case STRING:
                    showstr(stderr, m->value.s, -1);
diff --git a/usr.bin/file/readelf.c b/usr.bin/file/readelf.c
new file mode 100644 (file)
index 0000000..7f4f97b
--- /dev/null
@@ -0,0 +1,315 @@
+/*     $OpenBSD: readelf.c,v 1.1 1997/02/09 23:58:33 millert Exp $     */
+
+#ifdef BUILTIN_ELF
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "readelf.h"
+#include "file.h"
+
+static void
+doshn(fd, off, num, size, buf)
+       int fd;
+       off_t off;
+       int num;
+       size_t size;
+       char *buf;
+{
+       /*
+        * This works for both 32-bit and 64-bit ELF formats,
+        * because it looks only at the "sh_type" field, which is
+        * always 32 bits, and is preceded only by the "sh_name"
+        * field which is also always 32 bits, and because it uses
+        * the shdr size from the ELF header rather than using
+        * the size of an "Elf32_Shdr".
+        */
+       Elf32_Shdr *sh = (Elf32_Shdr *) buf;
+
+       if (lseek(fd, off, SEEK_SET) == -1)
+               error("lseek failed (%s).\n", strerror(errno));
+
+       for ( ; num; num--) {
+               if (read(fd, buf, size) == -1)
+                       error("read failed (%s).\n", strerror(errno));
+               if (sh->sh_type == SHT_SYMTAB) {
+                       (void) printf (", not stripped");
+                       return;
+               }
+       }
+       (void) printf (", stripped");
+}
+
+/*
+ * Look through the program headers of an executable image, searching
+ * for a PT_INTERP section; if one is found, it's dynamically linked,
+ * otherwise it's statically linked.
+ */
+static void
+dophn_exec(fd, off, num, size, buf)
+       int fd;
+       off_t off;
+       int num;
+       size_t size;
+       char *buf;
+{
+       /* I am not sure if this works for 64 bit elf formats */
+       Elf32_Phdr *ph = (Elf32_Phdr *) buf;
+
+       if (lseek(fd, off, SEEK_SET) == -1)
+               error("lseek failed (%s).\n", strerror(errno));
+
+       for ( ; num; num--) {
+               if (read(fd, buf, size) == -1)
+                       error("read failed (%s).\n", strerror(errno));
+               if (ph->p_type == PT_INTERP) {
+                       /*
+                        * Has an interpreter - must be a dynamically-linked
+                        * executable.
+                        */
+                       printf(", dynamically linked");
+                       return;
+               }
+       }
+       printf(", statically linked");
+}
+
+size_t prpsoffsets[] = {
+       100,            /* SunOS 5.x */
+       32,             /* Linux */
+};
+
+#define        NOFFSETS        (sizeof prpsoffsets / sizeof prpsoffsets[0])
+
+/*
+ * Look through the program headers of an executable image, searching
+ * for a PT_NOTE section of type NT_PRPSINFO, with a name "CORE"; if one
+ * is found, try looking in various places in its contents for a 16-character
+ * string containing only printable characters - if found, that string
+ * should be the name of the program that dropped core.
+ * Note: right after that 16-character string is, at least in SunOS 5.x
+ * (and possibly other SVR4-flavored systems) and Linux, a longer string
+ * (80 characters, in 5.x, probably other SVR4-flavored systems, and Linux)
+ * containing the start of the command line for that program.
+ */
+static void
+dophn_core(fd, off, num, size, buf)
+       int fd;
+       off_t off;
+       int num;
+       size_t size;
+       char *buf;
+{
+       /*
+        * This doesn't work for 64-bit ELF, as the "p_offset" field is
+        * 64 bits in 64-bit ELF.
+        */
+       /*
+        * This doesn't work for 64-bit ELF, as the "p_offset" field is
+        * 64 bits in 64-bit ELF.
+        */
+       Elf32_Phdr *ph = (Elf32_Phdr *) buf;
+       Elf32_Nhdr *nh;
+       size_t offset, noffset, reloffset;
+       unsigned char c;
+       int i, j;
+       char nbuf[BUFSIZ];
+       int bufsize;
+
+       for ( ; num; num--) {
+               if (lseek(fd, off, SEEK_SET) == -1)
+                       error("lseek failed (%s).\n", strerror(errno));
+               if (read(fd, buf, size) == -1)
+                       error("read failed (%s).\n", strerror(errno));
+               off += size;
+               if (ph->p_type != PT_NOTE)
+                       continue;
+               if (lseek(fd, ph->p_offset, SEEK_SET) == -1)
+                       error("lseek failed (%s).\n", strerror(errno));
+               bufsize = read(fd, nbuf, BUFSIZ);
+               if (bufsize == -1)
+                       error("read failed (%s).\n", strerror(errno));
+               offset = 0;
+               for (;;) {
+                       if (offset >= bufsize)
+                               break;
+                       nh = (Elf32_Nhdr *)&nbuf[offset];
+                       offset += sizeof *nh;
+
+                       /*
+                        * If this note isn't an NT_PRPSINFO note, it's
+                        * not what we're looking for.
+                        */
+                       if (nh->n_type != NT_PRPSINFO) {
+                               offset += nh->n_namesz;
+                               offset = ((offset + 3)/4)*4;
+                               offset += nh->n_descsz;
+                               offset = ((offset + 3)/4)*4;
+                               continue;
+                       }
+
+                       /*
+                        * Make sure this note has the name "CORE".
+                        */
+                       if (offset + nh->n_namesz >= bufsize) {
+                               /*
+                                * We're past the end of the buffer.
+                                */
+                               break;
+                       }
+                       if (nh->n_namesz != 5
+                           || strcmp(&nbuf[offset], "CORE") != 0)
+                               continue;
+                       offset += nh->n_namesz;
+                       offset = ((offset + 3)/4)*4;
+
+                       /*
+                        * Extract the program name.  We assume it to be
+                        * 16 characters (that's what it is in SunOS 5.x
+                        * and Linux).
+                        *
+                        * Unfortunately, it's at a different offset in
+                        * SunOS 5.x and Linux, so try multiple offsets.
+                        * If the characters aren't all printable, reject
+                        * it.
+                        */
+                       for (i = 0; i < NOFFSETS; i++) {
+                               reloffset = prpsoffsets[i];
+                               noffset = offset + reloffset;
+                               for (j = 0; j < 16;
+                                   j++, noffset++, reloffset++) {
+                                       /*
+                                        * Make sure we're not past the end
+                                        * of the buffer; if we are, just
+                                        * give up.
+                                        */
+                                       if (noffset >= bufsize)
+                                               return;
+
+                                       /*
+                                        * Make sure we're not past the
+                                        * end of the contents; if we
+                                        * are, this obviously isn't
+                                        * the right offset.
+                                        */
+                                       if (reloffset >= nh->n_descsz)
+                                               goto tryanother;
+
+                                       c = nbuf[noffset];
+                                       if (c != '\0' && !isprint(c))
+                                               goto tryanother;
+                               }
+
+                               /*
+                                * Well, that worked.
+                                */
+                               printf(", from '%.16s'",
+                                   &nbuf[offset + prpsoffsets[i]]);
+                               return;
+
+                       tryanother:
+                               ;
+                       }
+                       offset += nh->n_descsz;
+                       offset = ((offset + 3)/4)*4;
+               }
+       }
+}
+
+void
+tryelf(fd, buf, nbytes)
+       int fd;
+       char *buf;
+       int nbytes;
+{
+       union {
+               int32 l;
+               char c[sizeof (int32)];
+       } u;
+
+       /*
+        * 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.
+        */
+       if (buf[EI_MAG0] != ELFMAG0 || buf[EI_MAG1] != ELFMAG1
+           || buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)
+           return;
+
+
+       if (buf[4] == ELFCLASS32) {
+               Elf32_Ehdr elfhdr;
+               if (nbytes <= sizeof (Elf32_Ehdr))
+                       return;
+
+
+               u.l = 1;
+               (void) memcpy(&elfhdr, buf, sizeof elfhdr);
+               /*
+                * If the system byteorder does not equal the
+                * object byteorder then don't test.
+                * XXX - we could conceivably fix up the "dophn_XXX()" and
+                * "doshn()" routines to extract stuff in the right
+                * byte order....
+                */
+               if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5]) {
+                       if (elfhdr.e_type == ET_CORE) 
+                               dophn_core(fd, elfhdr.e_phoff, elfhdr.e_phnum, 
+                                     elfhdr.e_phentsize, buf);
+                       else {
+                               if (elfhdr.e_type == ET_EXEC) {
+                                       dophn_exec(fd, elfhdr.e_phoff,
+                                           elfhdr.e_phnum, 
+                                             elfhdr.e_phentsize, buf);
+                               }
+                               doshn(fd, elfhdr.e_shoff, elfhdr.e_shnum,
+                                     elfhdr.e_shentsize, buf);
+                       }
+               }
+               return;
+       }
+
+        if (buf[4] == ELFCLASS64) {
+               Elf64_Ehdr elfhdr;
+               if (nbytes <= sizeof (Elf64_Ehdr))
+                       return;
+
+
+               u.l = 1;
+               (void) memcpy(&elfhdr, buf, sizeof elfhdr);
+
+               /*
+                * If the system byteorder does not equal the
+                * object byteorder then don't test.
+                * XXX - we could conceivably fix up the "dophn_XXX()" and
+                * "doshn()" routines to extract stuff in the right
+                * byte order....
+                */
+               if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5]) {
+#ifdef notyet
+                       if (elfhdr.e_type == ET_CORE) 
+                               dophn_core(fd, elfhdr.e_phoff, elfhdr.e_phnum, 
+                                     elfhdr.e_phentsize, buf);
+                       else
+#endif
+                       {
+#ifdef notyet
+                               if (elfhdr.e_type == ET_EXEC) {
+                                       dophn_exec(fd, elfhdr.e_phoff,
+                                           elfhdr.e_phnum, 
+                                             elfhdr.e_phentsize, buf);
+                               }
+#endif
+                               doshn(fd, elfhdr.e_shoff, elfhdr.e_shnum,
+                                     elfhdr.e_shentsize, buf);
+                       }
+               }
+               return;
+       }
+}
+#endif
diff --git a/usr.bin/file/readelf.h b/usr.bin/file/readelf.h
new file mode 100644 (file)
index 0000000..bf66101
--- /dev/null
@@ -0,0 +1,168 @@
+/*     $OpenBSD: readelf.h,v 1.1 1997/02/09 23:58:34 millert Exp $     */
+
+/*
+ * readelf.h 
+ *
+ * Provide elf data structures for non-elf machines, allowing file
+ * non-elf hosts to determine if an elf binary is stripped.
+ * Note: cobbled from the linux header file, with modifications
+ */
+#ifndef __fake_elf_h__
+#define __fake_elf_h__
+
+typedef unsigned int   Elf32_Addr;
+typedef unsigned short Elf32_Half;
+typedef unsigned int   Elf32_Off;
+typedef unsigned int   Elf32_Word;
+typedef unsigned char  Elf32_Char;
+
+/* XXX: We need 64 bit numbers here */
+typedef unsigned int   Elf64_Addr[2];
+typedef unsigned short Elf64_Half;
+typedef unsigned int   Elf64_Off[2];
+typedef unsigned int   Elf64_Word;
+typedef unsigned char  Elf64_Char;
+
+#define EI_NIDENT      16
+
+typedef struct {
+    Elf32_Char e_ident[EI_NIDENT];
+    Elf32_Half e_type;
+    Elf32_Half e_machine;
+    Elf32_Word e_version;
+    Elf32_Addr e_entry;  /* Entry point */
+    Elf32_Off  e_phoff;
+    Elf32_Off  e_shoff;
+    Elf32_Word e_flags;
+    Elf32_Half e_ehsize;
+    Elf32_Half e_phentsize;
+    Elf32_Half e_phnum;
+    Elf32_Half e_shentsize;
+    Elf32_Half e_shnum;
+    Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct {
+    Elf64_Char e_ident[EI_NIDENT];
+    Elf64_Half e_type;
+    Elf64_Half e_machine;
+    Elf64_Word e_version;
+    Elf64_Addr e_entry;  /* Entry point */
+    Elf64_Off  e_phoff;
+    Elf64_Off  e_shoff;
+    Elf64_Word e_flags;
+    Elf64_Half e_ehsize;
+    Elf64_Half e_phentsize;
+    Elf64_Half e_phnum;
+    Elf64_Half e_shentsize;
+    Elf64_Half e_shnum;
+    Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+/* e_type */
+#define ET_EXEC                2
+#define ET_CORE                4
+
+/* sh_type */
+#define SHT_SYMTAB     2
+#define SHT_NOTE       7
+
+/* elf type */
+#define ELFDATANONE    0               /* e_ident[EI_DATA] */
+#define ELFDATA2LSB    1
+#define ELFDATA2MSB    2
+
+/* elf class */
+#define ELFCLASSNONE   0
+#define ELFCLASS32     1
+#define ELFCLASS64     2
+
+/* magic number */
+#define        EI_MAG0         0               /* e_ident[] indexes */
+#define        EI_MAG1         1
+#define        EI_MAG2         2
+#define        EI_MAG3         3
+#define        EI_CLASS        4
+#define        EI_DATA         5
+#define        EI_VERSION      6
+#define        EI_PAD          7
+
+#define        ELFMAG0         0x7f            /* EI_MAG */
+#define        ELFMAG1         'E'
+#define        ELFMAG2         'L'
+#define        ELFMAG3         'F'
+#define        ELFMAG          "\177ELF"
+
+typedef struct {
+    Elf32_Word p_type;
+    Elf32_Off  p_offset;
+    Elf32_Addr p_vaddr;
+    Elf32_Addr p_paddr;
+    Elf32_Word p_filesz;
+    Elf32_Word p_memsz;
+    Elf32_Word p_flags;
+    Elf32_Word p_align;
+} Elf32_Phdr;
+
+#define        PT_NULL         0               /* p_type */
+#define        PT_LOAD         1
+#define        PT_DYNAMIC      2
+#define        PT_INTERP       3
+#define        PT_NOTE         4
+#define        PT_SHLIB        5
+#define        PT_PHDR         6
+#define        PT_NUM          7
+
+typedef struct {
+    Elf32_Word sh_name;
+    Elf32_Word sh_type;
+    Elf32_Word sh_flags;
+    Elf32_Addr sh_addr;
+    Elf32_Off  sh_offset;
+    Elf32_Word sh_size;
+    Elf32_Word sh_link;
+    Elf32_Word sh_info;
+    Elf32_Word sh_addralign;
+    Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct {
+    Elf64_Word sh_name;
+    Elf64_Word sh_type;
+    Elf64_Off  sh_flags;
+    Elf64_Addr sh_addr;
+    Elf64_Off  sh_offset;
+    Elf64_Off  sh_size;
+    Elf64_Word sh_link;
+    Elf64_Word sh_info;
+    Elf64_Off  sh_addralign;
+    Elf64_Off  sh_entsize;
+} Elf64_Shdr;
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS    1
+#define NT_PRFPREG     2
+#define NT_PRPSINFO    3
+#define NT_TASKSTRUCT  4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf_note {
+  Elf32_Word   n_namesz;       /* Name size */
+  Elf32_Word   n_descsz;       /* Content size */
+  Elf32_Word   n_type;         /* Content type */
+} Elf32_Nhdr;
+
+typedef struct {
+    Elf64_Word n_namesz;
+    Elf64_Word n_descsz;
+    Elf64_Word n_type;
+} Elf64_Nhdr;
+
+#define        NT_PRSTATUS     1
+#define        NT_PRFPREG      2
+#define        NT_PRPSINFO     3
+#define        NT_PRXREG       4
+#define        NT_PLATFORM     5
+#define        NT_AUXV         6
+
+#endif
index bdcde97..a3e2f10 100644 (file)
@@ -1,4 +1,5 @@
-/*     $OpenBSD: softmagic.c,v 1.2 1996/06/26 05:33:01 deraadt Exp $   */
+/*     $OpenBSD: softmagic.c,v 1.3 1997/02/09 23:58:36 millert Exp $   */
+
 /*
  * softmagic - interpret variable magic from /etc/magic
  *
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include <time.h>
 #include <sys/types.h>
 
 #include "file.h"
 
 #ifndef        lint
-static char *moduleid = "$OpenBSD: softmagic.c,v 1.2 1996/06/26 05:33:01 deraadt Exp $";
+static char *moduleid = "$OpenBSD: softmagic.c,v 1.3 1997/02/09 23:58:36 millert Exp $";
 #endif /* lint */
 
 static int match       __P((unsigned char *, int));
 static int mget                __P((union VALUETYPE *,
                             unsigned char *, struct magic *, int));
 static int mcheck      __P((union VALUETYPE *, struct magic *));
-static void mprint     __P((union VALUETYPE *, struct magic *));
-static void mdebug     __P((long, char *, int));
+static int32 mprint    __P((union VALUETYPE *, struct magic *));
+static void mdebug     __P((int32, char *, int));
 static int mconvert    __P((union VALUETYPE *, struct magic *));
 
 /*
@@ -98,6 +100,13 @@ int nbytes;
        int cont_level = 0;
        int need_separator = 0;
        union VALUETYPE p;
+       static int32 *tmpoff = NULL;
+       static size_t tmplen = 0;
+       int32 oldoff = 0;
+
+       if (tmpoff == NULL)
+               if ((tmpoff = (int32 *) malloc(tmplen = 20)) == NULL)
+                       error("out of memory\n");
 
        for (magindex = 0; magindex < nmagic; magindex++) {
                /* if main entry matches, print it... */
@@ -113,7 +122,7 @@ int nbytes;
                            continue;
                }
 
-               mprint(&p, &magic[magindex]);
+               tmpoff[cont_level] = mprint(&p, &magic[magindex]);
                /*
                 * If we printed something, we'll need to print
                 * a blank before we print something else.
@@ -121,7 +130,10 @@ int nbytes;
                if (magic[magindex].desc[0])
                        need_separator = 1;
                /* and any continuations that match */
-               cont_level++;
+               if (++cont_level >= tmplen)
+                       if ((tmpoff = (int32 *) realloc(tmpoff,
+                                                      tmplen += 20)) == NULL)
+                               error("out of memory\n");
                while (magic[magindex+1].cont_level != 0 && 
                       ++magindex < nmagic) {
                        if (cont_level >= magic[magindex].cont_level) {
@@ -132,6 +144,10 @@ int nbytes;
                                         */
                                        cont_level = magic[magindex].cont_level;
                                }
+                               if (magic[magindex].flag & ADD) {
+                                       oldoff=magic[magindex].offset;
+                                       magic[magindex].offset += tmpoff[cont_level-1];
+                               }
                                if (mget(&p, s, &magic[magindex], nbytes) &&
                                    mcheck(&p, &magic[magindex])) {
                                        /*
@@ -149,7 +165,7 @@ int nbytes;
                                                (void) putchar(' ');
                                                need_separator = 0;
                                        }
-                                       mprint(&p, &magic[magindex]);
+                                       tmpoff[cont_level] = mprint(&p, &magic[magindex]);
                                        if (magic[magindex].desc[0])
                                                need_separator = 1;
 
@@ -158,7 +174,14 @@ int nbytes;
                                         * at a higher level,
                                         * process them.
                                         */
-                                       cont_level++;
+                                       if (++cont_level >= tmplen)
+                                               if ((tmpoff = 
+                                                   (int32 *) realloc(tmpoff,
+                                                   tmplen += 20)) == NULL)
+                                                       error("out of memory\n");
+                               }
+                               if (magic[magindex].flag & ADD) {
+                                        magic[magindex].offset = oldoff;
                                }
                        }
                }
@@ -167,13 +190,14 @@ int nbytes;
        return 0;                       /* no match at all */
 }
 
-static void
+static int32
 mprint(p, m)
 union VALUETYPE *p;
 struct magic *m;
 {
        char *pp, *rt;
-       unsigned long v;
+       uint32 v;
+       int32 t=0 ;
 
 
        switch (m->type) {
@@ -181,6 +205,7 @@ struct magic *m;
                v = p->b;
                v = signextend(m, v) & m->mask;
                (void) printf(m->desc, (unsigned char) v);
+               t = m->offset + sizeof(char);
                break;
 
        case SHORT:
@@ -189,6 +214,7 @@ struct magic *m;
                v = p->h;
                v = signextend(m, v) & m->mask;
                (void) printf(m->desc, (unsigned short) v);
+               t = m->offset + sizeof(short);
                break;
 
        case LONG:
@@ -196,17 +222,25 @@ struct magic *m;
        case LELONG:
                v = p->l;
                v = signextend(m, v) & m->mask;
-               (void) printf(m->desc, (unsigned long) v);
+               (void) printf(m->desc, (uint32) v);
+               t = m->offset + sizeof(int32);
                break;
 
        case STRING:
                if (m->reln == '=') {
                        (void) printf(m->desc, m->value.s);
+                       t = m->offset + strlen(m->value.s);
                }
                else {
+                       if (*m->value.s == '\0') {
+                               char *cp = strchr(p->s,'\n');
+                               if (cp)
+                                       *cp = '\0';
+                       }
                        (void) printf(m->desc, p->s);
+                       t = m->offset + strlen(p->s);
                }
-               return;
+               break;
 
        case DATE:
        case BEDATE:
@@ -215,11 +249,14 @@ struct magic *m;
                if ((rt = strchr(pp, '\n')) != NULL)
                        *rt = '\0';
                (void) printf(m->desc, pp);
-               return;
+               t = m->offset + sizeof(time_t);
+               break;
+
        default:
                error("invalid m->type (%d) in mprint().\n", m->type);
                /*NOTREACHED*/
        }
+       return(t);
 }
 
 /*
@@ -230,8 +267,6 @@ mconvert(p, m)
 union VALUETYPE *p;
 struct magic *m;
 {
-       char *rt;
-
        switch (m->type) {
        case BYTE:
        case SHORT:
@@ -239,17 +274,21 @@ struct magic *m;
        case DATE:
                return 1;
        case STRING:
-               /* Null terminate and eat the return */
-               p->s[sizeof(p->s) - 1] = '\0';
-               if ((rt = strchr(p->s, '\n')) != NULL)
-                       *rt = '\0';
-               return 1;
+               {
+                       char *ptr;
+
+                       /* Null terminate and eat the return */
+                       p->s[sizeof(p->s) - 1] = '\0';
+                       if ((ptr = strchr(p->s, '\n')) != NULL)
+                               *ptr = '\0';
+                       return 1;
+               }
        case BESHORT:
                p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
                return 1;
        case BELONG:
        case BEDATE:
-               p->l = (long)
+               p->l = (int32)
                    ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
                return 1;
        case LESHORT:
@@ -257,7 +296,7 @@ struct magic *m;
                return 1;
        case LELONG:
        case LEDATE:
-               p->l = (long)
+               p->l = (int32)
                    ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
                return 1;
        default:
@@ -269,11 +308,11 @@ struct magic *m;
 
 static void
 mdebug(offset, str, len)
-long offset;
+int32 offset;
 char *str;
 int len;
 {
-       (void) fprintf(stderr, "mget @%ld: ", offset);
+       (void) fprintf(stderr, "mget @%d: ", offset);
        showstr(stderr, (char *) str, len);
        (void) fputc('\n', stderr);
        (void) fputc('\n', stderr);
@@ -286,7 +325,7 @@ unsigned char       *s;
 struct magic *m;
 int nbytes;
 {
-       long offset = m->offset;
+       int32 offset = m->offset;
 
        if (offset + sizeof(union VALUETYPE) <= nbytes)
                memcpy(p, s + offset, sizeof(union VALUETYPE));
@@ -295,7 +334,7 @@ int nbytes;
                 * the usefulness of padding with zeroes eludes me, it
                 * might even cause problems
                 */
-               long have = nbytes - offset;
+               int32 have = nbytes - offset;
                memset(p, 0, sizeof(union VALUETYPE));
                if (have > 0)
                        memcpy(p, s + offset, have);
@@ -345,8 +384,8 @@ mcheck(p, m)
 union VALUETYPE* p;
 struct magic *m;
 {
-       register unsigned long l = m->value.l;
-       register unsigned long v;
+       register uint32 l = m->value.l;
+       register uint32 v;
        int matched;
 
        if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
@@ -389,7 +428,7 @@ struct magic *m;
                        register int len = m->vallen;
 
                        while (--len >= 0)
-                               if ((v = *b++ - *a++) != 0)
+                               if ((v = *b++ - *a++) != '\0')
                                        break;
                }
                break;
@@ -403,21 +442,21 @@ struct magic *m;
        switch (m->reln) {
        case 'x':
                if (debug)
-                       (void) fprintf(stderr, "%lu == *any* = 1\n", v);
+                       (void) fprintf(stderr, "%u == *any* = 1\n", v);
                matched = 1;
                break;
 
        case '!':
                matched = v != l;
                if (debug)
-                       (void) fprintf(stderr, "%lu != %lu = %d\n",
+                       (void) fprintf(stderr, "%u != %u = %d\n",
                                       v, l, matched);
                break;
 
        case '=':
                matched = v == l;
                if (debug)
-                       (void) fprintf(stderr, "%lu == %lu = %d\n",
+                       (void) fprintf(stderr, "%u == %u = %d\n",
                                       v, l, matched);
                break;
 
@@ -425,13 +464,13 @@ struct magic *m;
                if (m->flag & UNSIGNED) {
                        matched = v > l;
                        if (debug)
-                               (void) fprintf(stderr, "%lu > %lu = %d\n",
+                               (void) fprintf(stderr, "%u > %u = %d\n",
                                               v, l, matched);
                }
                else {
-                       matched = (long) v > (long) l;
+                       matched = (int32) v > (int32) l;
                        if (debug)
-                               (void) fprintf(stderr, "%ld > %ld = %d\n",
+                               (void) fprintf(stderr, "%d > %d = %d\n",
                                               v, l, matched);
                }
                break;
@@ -440,13 +479,13 @@ struct magic *m;
                if (m->flag & UNSIGNED) {
                        matched = v < l;
                        if (debug)
-                               (void) fprintf(stderr, "%lu < %lu = %d\n",
+                               (void) fprintf(stderr, "%u < %u = %d\n",
                                               v, l, matched);
                }
                else {
-                       matched = (long) v < (long) l;
+                       matched = (int32) v < (int32) l;
                        if (debug)
-                               (void) fprintf(stderr, "%ld < %ld = %d\n",
+                               (void) fprintf(stderr, "%d < %d = %d\n",
                                               v, l, matched);
                }
                break;
@@ -454,14 +493,14 @@ struct magic *m;
        case '&':
                matched = (v & l) == l;
                if (debug)
-                       (void) fprintf(stderr, "((%lx & %lx) == %lx) = %d\n",
+                       (void) fprintf(stderr, "((%x & %x) == %x) = %d\n",
                                       v, l, l, matched);
                break;
 
        case '^':
                matched = (v & l) != l;
                if (debug)
-                       (void) fprintf(stderr, "((%lx & %lx) != %lx) = %d\n",
+                       (void) fprintf(stderr, "((%x & %x) != %x) = %d\n",
                                       v, l, l, matched);
                break;
 
index 346831b..9246a13 100644 (file)
@@ -1,4 +1,5 @@
-/* * $OpenBSD: tar.h,v 1.2 1996/06/26 05:33:02 deraadt Exp $ # checkin only*/
+/*     $OpenBSD: tar.h,v 1.3 1997/02/09 23:58:37 millert Exp $ */
+
 /*
  * Header file for public domain tar (tape archive) program.
  *
index aacc8f4..3b223ff 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: fmt.1,v 1.2 1996/06/26 05:33:20 deraadt Exp $
+.\"    $OpenBSD: fmt.1,v 1.3 1997/02/09 23:58:42 millert Exp $
 .\"    $NetBSD: fmt.1,v 1.3 1995/09/01 01:29:40 jtc Exp $
 .\"
 .\" Copyright (c) 1980, 1990, 1993
@@ -42,6 +42,7 @@
 .Nd simple text formatter
 .Sh SYNOPSIS
 .Nm fmt
+.Fl c
 .Oo
 .Ar goal
 .Op Ar maximum
@@ -61,6 +62,11 @@ to 65 and the maximum to 75.  The spacing at the beginning of the
 input lines is preserved in the output, as are blank lines and
 interword spacing.
 .Pp
+.Fl c
+instructs
+.Nm fmt
+to center the text.
+.Pp
 .Nm Fmt
 is meant to format mail messages prior to sending, but may also be useful
 for other simple tasks.
index e402352..99862dc 100644 (file)
@@ -1,4 +1,4 @@
-/* * $OpenBSD: os-openbsd.h,v 1.3 1996/06/26 05:38:15 deraadt Exp $*/
+/* * $OpenBSD: os-openbsd.h,v 1.4 1997/02/09 23:58:44 millert Exp $*/
 /*
  * Copyright (c) 1993 Michael A. Cooper
  * Copyright (c) 1993 Regents of the University of California.
@@ -156,4 +156,4 @@ typedef void POINTER;
  * Define this only if the pathname is different than
  * that which appears in "include/paths.h".
  */
-#define _PATH_REMSH    "/usr/bin/rsh"                  /**/
+#define _PATH_REMSH    "/usr/local/bin/ssh"                    /**/