** README for file(1) Command **
-@(#) $Id: README,v 1.20 1993/09/23 21:47:01 christos Exp $
+@(#) $Id: README,v 1.21 1997/01/15 17:23:24 christos Exp $
This is Release 3.x of Ian Darwin's (copyright but distributable)
-file(1) command. Release 3.x is scheduled for inclusion in the
-4.4 BSD (Berkeley Software Distribution) of UNIX-like
-software, and is the standard "file" command for Linux, 386bsd,
-and other systems. (See "patchlevel.h" for the exact release number).
+file(1) command. This version is the standard "file" command for Linux,
+*BSD, and other systems. (See "patchlevel.h" for the exact release number).
UNIX is a trademark of UNIX System Laboratories.
file.c - main program
file.h - header file
fsmagic.c - first set of tests the program runs, based on filesystem info
-is_tar.c - knows about tarchives (courtesy John Gilmore).
+is_tar.c, tar.h - knows about tarchives (courtesy John Gilmore).
magdir - directory of /etc/magic pieces
magdir/Makefile - ADJUST THIS FOR YOUR CONFIGURATION
names.h - header file for ascmagic.c
softmagic.c - 2nd set of tests, based on /etc/magic
-strtok.c, getopt.c - in case you them (courtesy of Henry Spencer).
-strtol.c, strchr.c - in case you need them - public domain.
-tst - simple test suite, built from tst/Makefile
+readelf.[ch] - Standalone elf parsing code.
+compress.c - on-the-fly decompression.
+internat.c - recognize international `text' files.
+print.c - print results, errors, warnings.
+If your gzip sometimes fails to decompress things complaining about a short
+file, apply this patch [which is going to be in the next version of gzip]:
+*** - Tue Oct 29 02:06:35 1996
+--- util.c Sun Jul 21 21:51:38 1996
+*** 106,111 ****
+--- 108,114 ----
+
+ if (insize == 0) {
+ if (eof_ok) return EOF;
++ flush_window();
+ read_error();
+ }
+ bytes_in += (ulg)insize;
E-mail: christos@deshaw.com, moraes@deshaw.com
.TH FILE __CSECTION__ "Copyright but distributable"
-.\" $Id: file.man,v 1.27 1996/06/22 22:05:07 christos Exp $
+.\" $Id: file.man,v 1.28 1997/01/15 17:23:24 christos Exp $
.SH NAME
file
\- determine file type
.RE
.PP
Changes by Ian Darwin and various authors including
-Christos Zoulas (christos@ee.cornell.edu), 1990-1992.
+Christos Zoulas (christos@deshaw.com), 1990-1992.
.SH LEGAL NOTICE
Copyright (c) Ian F. Darwin, Toronto, Canada,
1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993.
.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
-.I /pub/file-X.YY.tar.gz
+.I /pub/file/file-X.YY.tar.gz
# Makefile for file(1) cmd.
# Copyright (c) Ian F. Darwin 86/09/01 - see LEGAL.NOTICE.
-# @(#)$Id: Makefile,v 1.54 1996/12/16 03:33:34 christos Exp $
+# @(#)$Id: Makefile,v 1.55 1997/01/15 17:23:24 christos Exp $
#
# This software is not subject to any license of the American Telephone
# and Telegraph Company or of the Regents of the University of California.
# ever read sources, credits must appear in the documentation.
#
# 4. This notice may not be removed or altered.
-VERSION = 3.21
+VERSION = 3.22
SHELL = /bin/sh
#MAGIC = /etc/magic
MAGIC = /usr/local/etc/magic
LOCALINC = # localinc/*.h localinc/sys/*.h
SRCS = file.c apprentice.c fsmagic.c softmagic.c ascmagic.c \
- compress.c is_tar.c readelf.c international.c \
+ compress.c is_tar.c readelf.c internat.c \
print.c $(LOCALSRCS) $(LOCALINC)
OBJS = file.o apprentice.o fsmagic.o softmagic.o ascmagic.o \
- compress.o is_tar.o readelf.o international.o \
+ compress.o is_tar.o readelf.o internat.o \
print.o $(LOCALOBJS)
ALLSRC = LEGAL.NOTICE README MAINT PORTING $(SRCS) *.h \
#ifndef lint
static char *moduleid =
- "@(#)$Id: apprentice.c,v 1.24 1996/06/22 22:04:22 christos Exp $";
+ "@(#)$Id: apprentice.c,v 1.25 1997/01/15 17:23:24 christos Exp $";
#endif /* lint */
#define EATAB {while (isascii((unsigned char) *l) && \
/*
* 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) {
case LONG:
case BELONG:
case LELONG:
- v = (long) v;
+ v = (int32) v;
break;
case STRING:
break;
*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;
#ifndef lint
static char *moduleid =
- "@(#)$Id: ascmagic.c,v 1.20 1995/05/20 22:09:21 christos Exp $";
+ "@(#)$Id: ascmagic.c,v 1.21 1997/01/15 17:23:24 christos Exp $";
#endif /* lint */
/* an optimisation over plain strcmp() */
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);
}
}
-
- 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) {
*/
#ifndef lint
static char *moduleid =
- "@(#)$Id: file.c,v 1.36 1996/10/05 18:13:57 christos Exp $";
+ "@(#)$Id: file.c,v 1.37 1997/01/15 17:23:24 christos Exp $";
#endif /* lint */
#include <stdio.h>
#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() */
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';
#endif
if (inname != stdname) {
+#ifdef RESTORE_TIME
/*
* Try to restore access, modification times if read it.
*/
+# 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');
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';
/*
* file.h - definitions for file(1) program
- * @(#)$Id: file.h,v 1.23 1996/06/22 22:04:22 christos Exp $
+ * @(#)$Id: file.h,v 1.24 1997/01/15 17:23:24 christos Exp $
*
* Copyright (c) Ian F. Darwin, 1987.
* Written by Ian F. Darwin.
* 4. This notice may not be removed or altered.
*/
+#ifndef __file_h__
+#define __file_h__
+
+typedef int int32;
+typedef unsigned int uint32;
+
#ifndef HOWMANY
# define HOWMANY 8192 /* how much of the file to look at */
#endif
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 */
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 */
};
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 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) \
#ifndef MAXPATHLEN
#define MAXPATHLEN 512
#endif
+
+#endif /* __file_h__ */
* Pubic Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
*
* @(#)list.c 1.18 9/23/86 Public Domain - gnu
- * $Id: is_tar.c,v 1.8 1993/09/16 21:09:35 christos Exp $
+ * $Id: is_tar.c,v 1.9 1997/01/15 17:23:24 christos Exp $
*
* Comments changed and some code/comments reformatted
* for file command by Ian Darwin.
#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
/*
{
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))
*
* 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++;
*
* See LEGAL.NOTICE
*
- * $Id: names.h,v 1.12 1995/04/28 17:29:13 christos Exp $
+ * $Id: names.h,v 1.13 1997/01/15 17:23:24 christos Exp $
*/
/* 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",
} 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},
#define FILE_VERSION_MAJOR 3
-#define patchlevel 21
+#define patchlevel 22
/*
* Patchlevel file for Ian Darwin's MAGIC command.
- * $Id: patchlevel.h,v 1.21 1996/10/05 18:15:29 christos Exp $
+ * $Id: patchlevel.h,v 1.22 1997/01/15 17:23:24 christos Exp $
*
* $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.21 1996/10/05 18:15:29 christos
* Segregate elf stuff and conditionally enable it with -DBUILTIN_ELF
* More magic fixes
#ifdef BUILTIN_ELF
+#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
-#ifdef __SVR4
-#include <sys/procfs.h>
-#endif
#include "readelf.h"
#include "file.h"
size_t size;
char *buf;
{
- /* This works for both 32 and 64 bit elf formats */
+ /*
+ * 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)
for ( ; num; num--) {
if (read(fd, buf, size) == -1)
error("read failed (%s).\n", strerror(errno));
- if (sh->sh_type == SHT_SYMTAB)
+ if (sh->sh_type == SHT_SYMTAB) {
+ (void) printf (", not stripped");
return;
+ }
}
(void) printf (", stripped");
}
/*
- * From: Ken Pizzini <ken@spry.com>
+ * 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(fd, off, num, size, buf)
+dophn_exec(fd, off, num, size, buf)
int fd;
off_t off;
int num;
char *buf;
{
/* I am not sure if this works for 64 bit elf formats */
- Elf32_Phdr ph;
- Elf32_Nhdr nh;
- off_t off_sv;
- off_t fname_off;
+ 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 (read(fd, &ph, sizeof ph) != sizeof ph)
+ 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));
- if (ph.p_type != PT_NOTE)
+ off += size;
+ if (ph->p_type != PT_NOTE)
continue;
- off_sv = lseek(fd, ph.p_offset, SEEK_SET);
- if (off_sv == -1)
+ if (lseek(fd, ph->p_offset, SEEK_SET) == -1)
error("lseek failed (%s).\n", strerror(errno));
- if (read(fd, &nh, sizeof nh) != sizeof nh)
+ bufsize = read(fd, nbuf, BUFSIZ);
+ if (bufsize == -1)
error("read failed (%s).\n", strerror(errno));
- if (nh.n_type != NT_PRPSINFO) {
- if (lseek(fd, off_sv, SEEK_SET) == -1)
- error("lseek failed (%s).\n", strerror(errno));
- continue;
- }
+ offset = 0;
+ for (;;) {
+ if (offset >= bufsize)
+ break;
+ nh = (Elf32_Nhdr *)&nbuf[offset];
+ offset += sizeof *nh;
-#ifdef __SVR4
+ /*
+ * 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;
+ }
-#define ALIGN(n) (((n)+3) & ~3) /* round up to nearest multiple of 4 */
-#define offsetof(a, b) (int) &((a *) 0)->b
+ /*
+ * 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;
- fname_off = offsetof(struct prpsinfo, pr_fname) +
- ALIGN(nh.n_namesz);
- if (lseek(fd, fname_off, SEEK_CUR) == -1)
- error("lseek failed (%s).\n", strerror(errno));
- if (read(fd, buf, size) == -1)
- error("read failed (%s).\n", strerror(errno));
- (void) printf ("; from `%s'", buf);
-#endif
- return;
+ /*
+ * 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;
int nbytes;
{
union {
- long l;
- char c[sizeof (long)];
+ int32 l;
+ char c[sizeof (int32)];
} u;
/*
u.l = 1;
(void) memcpy(&elfhdr, buf, sizeof elfhdr);
-
- if (elfhdr.e_type == ET_CORE)
- dophn(fd, elfhdr.e_phoff, elfhdr.e_phnum,
- elfhdr.e_phentsize, buf);
- else
- {
- /*
- * If the system byteorder does not equal the
- * object byteorder then don't test.
- */
- if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5])
+ /*
+ * 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;
}
u.l = 1;
(void) memcpy(&elfhdr, buf, sizeof elfhdr);
- if (elfhdr.e_type == ET_CORE)
- dophn(fd, elfhdr.e_phoff, elfhdr.e_phnum,
- elfhdr.e_phentsize, buf);
- else
- {
- /*
- * If the system byteorder does not equal the
- * object byteorder then don't test.
- */
- if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5])
+ /*
+ * 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;
}
}
/*
* readelf.h
- * @(#)$Id: readelf.h,v 1.3 1996/10/25 18:11:51 christos Exp $
+ * @(#)$Id: readelf.h,v 1.4 1997/01/15 17:23:24 christos Exp $
*
* Provide elf data structures for non-elf machines, allowing file
* non-elf hosts to determine if an elf binary is stripped.
} Elf64_Ehdr;
/* e_type */
+#define ET_EXEC 2
#define ET_CORE 4
/* sh_type */
Elf64_Off sh_entsize;
} Elf64_Shdr;
-
-typedef struct {
- Elf32_Word n_namesz;
- Elf32_Word n_descsz;
- Elf32_Word n_type;
+/* 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 {
#ifndef lint
static char *moduleid =
- "@(#)$Id: softmagic.c,v 1.32 1996/10/25 19:50:35 christos Exp $";
+ "@(#)$Id: softmagic.c,v 1.33 1997/01/15 17:23:24 christos 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 long 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 *));
/*
int cont_level = 0;
int need_separator = 0;
union VALUETYPE p;
- static long *tmpoff = NULL;
+ static int32 *tmpoff = NULL;
static size_t tmplen = 0;
- long oldoff = 0;
+ int32 oldoff = 0;
if (tmpoff == NULL)
- if ((tmpoff = (long *) malloc(tmplen = 20)) == NULL)
+ if ((tmpoff = (int32 *) malloc(tmplen = 20)) == NULL)
error("out of memory\n");
for (magindex = 0; magindex < nmagic; magindex++) {
need_separator = 1;
/* and any continuations that match */
if (++cont_level >= tmplen)
- if ((tmpoff = (long *) realloc(tmpoff,
+ if ((tmpoff = (int32 *) realloc(tmpoff,
tmplen += 20)) == NULL)
error("out of memory\n");
while (magic[magindex+1].cont_level != 0 &&
*/
if (++cont_level >= tmplen)
if ((tmpoff =
- (long *) realloc(tmpoff,
+ (int32 *) realloc(tmpoff,
tmplen += 20)) == NULL)
error("out of memory\n");
}
return 0; /* no match at all */
}
-static long
+static int32
mprint(p, m)
union VALUETYPE *p;
struct magic *m;
{
char *pp, *rt;
- unsigned long v;
- long t=0 ;
+ uint32 v;
+ int32 t=0 ;
switch (m->type) {
case LELONG:
v = p->l;
v = signextend(m, v) & m->mask;
- (void) printf(m->desc, (unsigned long) v);
- t = m->offset + sizeof(long);
+ (void) printf(m->desc, (uint32) v);
+ t = m->offset + sizeof(int32);
break;
case STRING:
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 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:
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:
static void
mdebug(offset, str, len)
-long offset;
+int32 offset;
char *str;
int len;
{
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));
* 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);
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') ) {
v, l, matched);
}
else {
- matched = (long) v > (long) l;
+ matched = (int32) v > (int32) l;
if (debug)
(void) fprintf(stderr, "%ld > %ld = %d\n",
v, l, matched);
v, l, matched);
}
else {
- matched = (long) v < (long) l;
+ matched = (int32) v < (int32) l;
if (debug)
(void) fprintf(stderr, "%ld < %ld = %d\n",
v, l, matched);