diff options
| author | pooka <pooka@NetBSD.org> | 2000-09-22 16:34:59 +0000 |
|---|---|---|
| committer | pooka <pooka@NetBSD.org> | 2000-09-22 16:34:59 +0000 |
| commit | e5efd07a0bcfa67e020a523ca2712d5d429dc21e (patch) | |
| tree | 95594a357126783c85bf2b817f3f723d6d8fb668 /usr.bin | |
| parent | c45f82114cfbb9473b63a60442801cf660d65c8e (diff) | |
resolve conflicts
Diffstat (limited to 'usr.bin')
| -rw-r--r-- | usr.bin/file/Header | 1 | ||||
| -rw-r--r-- | usr.bin/file/Makefile | 4 | ||||
| -rw-r--r-- | usr.bin/file/README | 6 | ||||
| -rw-r--r-- | usr.bin/file/apprentice.c | 64 | ||||
| -rw-r--r-- | usr.bin/file/ascmagic.c | 645 | ||||
| -rw-r--r-- | usr.bin/file/compress.c | 79 | ||||
| -rw-r--r-- | usr.bin/file/file.1 | 96 | ||||
| -rw-r--r-- | usr.bin/file/file.c | 144 | ||||
| -rw-r--r-- | usr.bin/file/file.h | 4 | ||||
| -rw-r--r-- | usr.bin/file/fsmagic.c | 11 | ||||
| -rw-r--r-- | usr.bin/file/is_tar.c | 28 | ||||
| -rw-r--r-- | usr.bin/file/magdir/alpha | 9 | ||||
| -rw-r--r-- | usr.bin/file/magdir/animation | 8 | ||||
| -rw-r--r-- | usr.bin/file/magdir/apple | 104 | ||||
| -rw-r--r-- | usr.bin/file/magdir/commands | 7 | ||||
| -rw-r--r-- | usr.bin/file/magdir/database | 133 | ||||
| -rw-r--r-- | usr.bin/file/magdir/filesystems | 15 | ||||
| -rw-r--r-- | usr.bin/file/magdir/images | 5 | ||||
| -rw-r--r-- | usr.bin/file/magdir/mail.news | 3 | ||||
| -rw-r--r-- | usr.bin/file/magdir/netbsd | 11 | ||||
| -rw-r--r-- | usr.bin/file/magdir/sniffer | 45 | ||||
| -rw-r--r-- | usr.bin/file/magdir/troff | 2 | ||||
| -rw-r--r-- | usr.bin/file/names.h | 33 | ||||
| -rw-r--r-- | usr.bin/file/patchlevel.h | 15 | ||||
| -rw-r--r-- | usr.bin/file/print.c | 74 | ||||
| -rw-r--r-- | usr.bin/file/readelf.c | 180 | ||||
| -rw-r--r-- | usr.bin/file/softmagic.c | 48 |
27 files changed, 1315 insertions, 459 deletions
diff --git a/usr.bin/file/Header b/usr.bin/file/Header index 2c76925dc8a..3ca9b0eb2cc 100644 --- a/usr.bin/file/Header +++ b/usr.bin/file/Header @@ -1,3 +1,4 @@ +# Magic # Magic data for file(1) command. # Machine-generated from src/cmd/file/magdir/*; edit there only! # Format is described in magic(files), where: diff --git a/usr.bin/file/Makefile b/usr.bin/file/Makefile index 27f9f3efed1..192b661e358 100644 --- a/usr.bin/file/Makefile +++ b/usr.bin/file/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.24 2000/05/14 22:53:37 christos Exp $ +# $NetBSD: Makefile,v 1.25 2000/09/22 16:34:59 pooka Exp $ .include <bsd.own.mk> @@ -12,7 +12,7 @@ FILES= ${MFILES} PROG= file SRCS= file.c apprentice.c fsmagic.c softmagic.c ascmagic.c is_tar.c \ - print.c compress.c readelf.c internat.c + print.c compress.c readelf.c CPPFLAGS+= -DMAGIC='"$(MAGIC)"' -DHAVE_CONFIG_H -I${.CURDIR} CPPFLAGS+= -DBUILTIN_ELF -DELFCORE MAN= file.1 magic.5 diff --git a/usr.bin/file/README b/usr.bin/file/README index 834cd688e80..a0ed23c1b5e 100644 --- a/usr.bin/file/README +++ b/usr.bin/file/README @@ -1,6 +1,6 @@ -$NetBSD: README,v 1.6 1998/09/20 15:27:15 christos Exp $ +$NetBSD: README,v 1.7 2000/09/22 16:34:59 pooka Exp $ ** README for file(1) Command ** -@(#) Id: README,v 1.22 1997/11/05 16:03:18 christos Exp +@(#) Id: README,v 1.23 2000/08/05 18:25:29 christos Exp This is Release 3.x of Ian Darwin's (copyright but distributable) file(1) command. This version is the standard "file" command for Linux, @@ -81,7 +81,7 @@ file, apply this patch [which is going to be in the next version of gzip]: } bytes_in += (ulg)insize; -E-mail: christos@astron.com, moraes@deshaw.com +E-mail: christos@astron.com Phone: Do not even think of telephoning me about this program. Send cash first! diff --git a/usr.bin/file/apprentice.c b/usr.bin/file/apprentice.c index a2748e79aa5..2d06fa93ba6 100644 --- a/usr.bin/file/apprentice.c +++ b/usr.bin/file/apprentice.c @@ -1,4 +1,4 @@ -/* $NetBSD: apprentice.c,v 1.19 2000/05/14 22:53:37 christos Exp $ */ +/* $NetBSD: apprentice.c,v 1.20 2000/09/22 16:34:59 pooka Exp $ */ /* * apprentice - make one pass through /etc/magic, learning its secrets. @@ -39,7 +39,7 @@ #if 0 FILE_RCSID("@(#)Id: apprentice.c,v 1.32 2000/04/23 04:32:19 christos Exp ") #else -__RCSID("$NetBSD: apprentice.c,v 1.19 2000/05/14 22:53:37 christos Exp $"); +__RCSID("$NetBSD: apprentice.c,v 1.20 2000/09/22 16:34:59 pooka Exp $"); #endif #endif /* lint */ @@ -68,8 +68,8 @@ static int apprentice_1 __P((const char *, int)); int apprentice(fn, check) -const char *fn; /* list of magic files */ -int check; /* non-zero? checking-only run. */ + const char *fn; /* list of magic files */ + int check; /* non-zero? checking-only run. */ { char *p, *mfn; int file_err, errs = -1; @@ -107,8 +107,8 @@ int check; /* non-zero? checking-only run. */ static int apprentice_1(fn, check) -const char *fn; /* name of magic file */ -int check; /* non-zero? checking-only run. */ + const char *fn; /* name of magic file */ + int check; /* non-zero? checking-only run. */ { static const char hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"; @@ -120,8 +120,8 @@ int check; /* non-zero? checking-only run. */ if (f==NULL) { if (errno != ENOENT) (void) fprintf(stderr, - "%s: can't read magic file %s (%s)\n", - progname, fn, strerror(errno)); + "%s: can't read magic file %s (%s)\n", + progname, fn, strerror(errno)); return -1; } @@ -148,8 +148,8 @@ int check; /* non-zero? checking-only run. */ */ uint32 signextend(m, v) -struct magic *m; -uint32 v; + struct magic *m; + uint32 v; { if (!(m->flag & UNSIGNED)) switch(m->type) { @@ -189,8 +189,8 @@ uint32 v; */ static int parse(l, ndx, check) -char *l; -int *ndx, check; + char *l; + int *ndx, check; { int i = 0, nd = *ndx; struct magic *m; @@ -451,8 +451,8 @@ GetDesc: */ static int getvalue(m, p) -struct magic *m; -char **p; + struct magic *m; + char **p; { int slen; @@ -475,14 +475,14 @@ char **p; */ static char * getstr(s, p, plen, slen) -register char *s; -register char *p; -int plen, *slen; + char *s; + char *p; + int plen, *slen; { char *origs = s, *origp = p; char *pmax = p + plen - 1; - register int c; - register int val; + int c; + int val; while ((c = *s++) != '\0') { if (isspace((unsigned char) c)) @@ -578,13 +578,17 @@ out: /* Single hex char to int; -1 if not a hex char. */ static int hextoint(c) -int c; + int c; { - if (!isascii((unsigned char) c)) return -1; - if (isdigit((unsigned char) c)) return c - '0'; - if ((c>='a')&&(c<='f')) return c + 10 - 'a'; - if ((c>='A')&&(c<='F')) return c + 10 - 'A'; - return -1; + if (!isascii((unsigned char) c)) + return -1; + if (isdigit((unsigned char) c)) + return c - '0'; + if ((c >= 'a')&&(c <= 'f')) + return c + 10 - 'a'; + if (( c>= 'A')&&(c <= 'F')) + return c + 10 - 'A'; + return -1; } @@ -593,11 +597,11 @@ int c; */ void showstr(fp, s, len) -FILE *fp; -const char *s; -int len; + FILE *fp; + const char *s; + int len; { - register char c; + char c; for (;;) { c = *s++; @@ -652,7 +656,7 @@ int len; */ static void eatsize(p) -char **p; + char **p; { char *l = *p; diff --git a/usr.bin/file/ascmagic.c b/usr.bin/file/ascmagic.c index c1dd81feaa5..dfa404bff62 100644 --- a/usr.bin/file/ascmagic.c +++ b/usr.bin/file/ascmagic.c @@ -1,4 +1,4 @@ -/* $NetBSD: ascmagic.c,v 1.14 2000/05/14 22:53:37 christos Exp $ */ +/* $NetBSD: ascmagic.c,v 1.15 2000/09/22 16:34:59 pooka Exp $ */ /* * ASCII magic -- file types that we know based on keywords @@ -7,6 +7,14 @@ * Copyright (c) Ian F. Darwin, 1987. * Written by Ian F. Darwin. * + * Extensively modified by Eric Fischer <enf@pobox.com> in July, 2000, + * to handle character codes other than ASCII on a unified basis. + * + * Joerg Wunsch <joerg@freebsd.org> wrote the original support for 8-bit + * international characters, now subsumed into this file. + */ + +/* * This software is not subject to any license of the American Telephone * and Telegraph Company or of the Regents of the University of California. * @@ -44,23 +52,54 @@ #if 0 FILE_RCSID("@(#)Id: ascmagic.c,v 1.27 2000/04/23 04:28:19 christos Exp ") #else -__RCSID("$NetBSD: ascmagic.c,v 1.14 2000/05/14 22:53:37 christos Exp $"); +__RCSID("$NetBSD: ascmagic.c,v 1.15 2000/09/22 16:34:59 pooka Exp $"); #endif #endif /* lint */ /* an optimisation over plain strcmp() */ #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) +typedef unsigned long unichar; + +#define MAXLINELEN 300 /* longest sane line length */ +#define ISSPC(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n' \ + || (x) == 0x85 || (x) == '\f') + +static int looks_ascii __P((const unsigned char *, int, unichar *, int *)); +static int looks_utf8 __P((const unsigned char *, int, unichar *, int *)); +static int looks_unicode __P((const unsigned char *, int, unichar *, int *)); +static int looks_latin1 __P((const unsigned char *, int, unichar *, int *)); +static int looks_extended __P((const unsigned char *, int, unichar *, int *)); +static void from_ebcdic __P((const unsigned char *, int, unsigned char *)); +static int ascmatch __P((const unsigned char *, const unichar *, int)); + int ascmagic(buf, nbytes) -unsigned char *buf; -int nbytes; /* size actually read */ + unsigned char *buf; + int nbytes; /* size actually read */ { - int i, has_escapes = 0; - unsigned char *s; - char nbuf[HOWMANY+1]; /* one extra for terminating '\0' */ - char *token; - register struct names *p; + int i; + char nbuf[HOWMANY+1]; /* one extra for terminating '\0' */ + unichar ubuf[HOWMANY+1]; /* one extra for terminating '\0' */ + int ulen; + struct names *p; + + char *code = NULL; + char *code_mime = NULL; + char *type = NULL; + char *subtype = NULL; + char *subtype_mime = NULL; + + int has_escapes = 0; + int has_backspace = 0; + + int n_crlf = 0; + int n_lf = 0; + int n_cr = 0; + int n_nel = 0; + + int last_line_end = -1; + int has_long_lines = 0; /* * Do the tar test first, because if the first file in the tar @@ -76,58 +115,582 @@ int nbytes; /* size actually read */ return 1; } + /* Undo the NUL-termination kindly provided by process() */ + + while (nbytes > 0 && buf[nbytes - 1] == '\0') + nbytes--; + + /* + * Then try to determine whether it's any character code we can + * identify. Each of these tests, if it succeeds, will leave + * the text converted into one-unichar-per-character Unicode in + * ubuf, and the number of characters converted in ulen. + */ + if (looks_ascii(buf, nbytes, ubuf, &ulen)) { + code = "ASCII"; + code_mime = "us-ascii"; + type = "text"; + } else if (looks_utf8(buf, nbytes, ubuf, &ulen)) { + code = "UTF-8 Unicode"; + code_mime = "utf-8"; + type = "text"; + } else if ((i = looks_unicode(buf, nbytes, ubuf, &ulen))) { + if (i == 1) + code = "Little-endian UTF-16 Unicode"; + else + code = "Big-endian UTF-16 Unicode"; + + type = "character data"; + code_mime = "utf-16"; /* is this defined? */ + } else if (looks_latin1(buf, nbytes, ubuf, &ulen)) { + code = "ISO-8859"; + type = "text"; + code_mime = "iso-8859-1"; + } else if (looks_extended(buf, nbytes, ubuf, &ulen)) { + code = "Non-ISO extended-ASCII"; + type = "text"; + code_mime = "unknown"; + } else { + from_ebcdic(buf, nbytes, nbuf); + + if (looks_ascii(nbuf, nbytes, ubuf, &ulen)) { + code = "EBCDIC"; + type = "character data"; + code_mime = "ebcdic"; + } else if (looks_latin1(nbuf, nbytes, ubuf, &ulen)) { + code = "International EBCDIC"; + type = "character data"; + code_mime = "ebcdic"; + } else { + return 0; /* doesn't look like text at all */ + } + } + /* * for troff, look for . + letter + letter or .\"; * this must be done to disambiguate tar archives' ./file * and other trash from real troff input. + * + * I believe Plan 9 troff allows non-ASCII characters in the names + * of macros, so this test might possibly fail on such a file. */ - if (*buf == '.') { - unsigned char *tp = buf + 1; + if (*ubuf == '.') { + unichar *tp = ubuf + 1; - while (isascii(*tp) && isspace(*tp)) + while (ISSPC(*tp)) ++tp; /* skip leading whitespace */ - if ((isascii(*tp) && (isalnum(*tp) || *tp=='\\') && - isascii(tp[1]) && (isalnum(tp[1]) || tp[1] == '"'))) { - ckfputs(iflag ? "text/troff" - : "troff or preprocessor input text", stdout); - return 1; + if ((tp[0] == '\\' && tp[1] == '\"') || + (isascii(tp[0]) && isalnum(tp[0]) && + isascii(tp[1]) && isalnum(tp[1]) && + ISSPC(tp[2]))) { + subtype_mime = "text/troff"; + subtype = "troff or preprocessor input"; + goto subtype_identified; } } - if ((*buf == 'c' || *buf == 'C') && - isascii(buf[1]) && isspace(buf[1])) { - ckfputs(iflag ? "text/fortran" : "fortran program text", stdout); + + if ((*buf == 'c' || *buf == 'C') && ISSPC(buf[1])) { + subtype_mime = "text/fortran"; + subtype = "fortran program"; + goto subtype_identified; + } + + /* look for tokens from names.h - this is expensive! */ + + i = 0; + while (i < ulen) { + int end; + + /* + * skip past any leading space + */ + while (i < ulen && ISSPC(ubuf[i])) + i++; + if (i >= ulen) + break; + + /* + * find the next whitespace + */ + for (end = i + 1; end < nbytes; end++) + if (ISSPC(ubuf[end])) + break; + + /* + * compare the word thus isolated against the token list + */ + for (p = names; p < names + NNAMES; p++) { + if (ascmatch(p->name, ubuf + i, end - i)) { + subtype = types[p->type].human; + subtype_mime = types[p->type].mime; + goto subtype_identified; + } + } + + i = end; + } + +subtype_identified: + + /* + * Now try to discover other details about the file. + */ + for (i = 0; i < ulen; i++) { + if (i > last_line_end + MAXLINELEN) + has_long_lines = 1; + + if (ubuf[i] == '\033') + has_escapes = 1; + if (ubuf[i] == '\b') + has_backspace = 1; + + if (ubuf[i] == '\r' && (i + 1 < ulen && ubuf[i + 1] == '\n')) { + n_crlf++; + last_line_end = i; + } + if (ubuf[i] == '\r' && (i + 1 >= ulen || ubuf[i + 1] != '\n')) { + n_cr++; + last_line_end = i; + } + if (ubuf[i] == '\n' && (i - 1 < 0 || ubuf[i - 1] != '\r')) { + n_lf++; + last_line_end = i; + } + if (ubuf[i] == 0x85) { /* X3.64/ECMA-43 "next line" character */ + n_nel++; + last_line_end = i; + } + } + + if (iflag) { + if (subtype_mime) + ckfputs(subtype_mime, stdout); + else + ckfputs("text/plain", stdout); + + if (code_mime) { + ckfputs("; charset=", stdout); + ckfputs(code_mime, stdout); + } + } else { + ckfputs(code, stdout); + + if (subtype) { + ckfputs(" ", stdout); + ckfputs(subtype, stdout); + } + + ckfputs(" ", stdout); + ckfputs(type, stdout); + + if (has_long_lines) + ckfputs(", with very long lines", stdout); + + /* + * Only report line terminators if we find one other than LF, + * or if we find none at all. + */ + if ((n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) || + (n_crlf != 0 || n_cr != 0 || n_nel != 0)) { + ckfputs(", with", stdout); + + if (n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) + ckfputs(" no", stdout); + else { + if (n_crlf) { + ckfputs(" CRLF", stdout); + if (n_cr || n_lf || n_nel) + ckfputs(",", stdout); + } + if (n_cr) { + ckfputs(" CR", stdout); + if (n_lf || n_nel) + ckfputs(",", stdout); + } + if (n_lf) { + ckfputs(" LF", stdout); + if (n_nel) + ckfputs(",", stdout); + } + if (n_nel) + ckfputs(" NEL", stdout); + } + + ckfputs(" line terminators", stdout); + } + + if (has_escapes) + ckfputs(", with escape sequences", stdout); + if (has_backspace) + ckfputs(", with overstriking", stdout); + } + + return 1; +} + +static int +ascmatch(s, us, ulen) + const unsigned char *s; + const unichar *us; + int ulen; +{ + size_t i; + + for (i = 0; i < ulen; i++) { + if (s[i] != us[i]) + return 0; + } + + if (s[i]) + return 0; + else return 1; +} + +/* + * This table reflects a particular philosophy about what constitutes + * "text," and there is room for disagreement about it. + * + * Version 3.31 of the file command considered a file to be ASCII if + * each of its characters was approved by either the isascii() or + * isalpha() function. On most systems, this would mean that any + * file consisting only of characters in the range 0x00 ... 0x7F + * would be called ASCII text, but many systems might reasonably + * consider some characters outside this range to be alphabetic, + * so the file command would call such characters ASCII. It might + * have been more accurate to call this "considered textual on the + * local system" than "ASCII." + * + * It considered a file to be "International language text" if each + * of its characters was either an ASCII printing character (according + * to the real ASCII standard, not the above test), a character in + * the range 0x80 ... 0xFF, or one of the following control characters: + * backspace, tab, line feed, vertical tab, form feed, carriage return, + * escape. No attempt was made to determine the language in which files + * of this type were written. + * + * + * The table below considers a file to be ASCII if all of its characters + * are either ASCII printing characters (again, according to the X3.4 + * standard, not isascii()) or any of the following controls: bell, + * backspace, tab, line feed, form feed, carriage return, esc, nextline. + * + * I include bell because some programs (particularly shell scripts) + * use it literally, even though it is rare in normal text. I exclude + * vertical tab because it never seems to be used in real text. I also + * include, with hesitation, the X3.64/ECMA-43 control nextline (0x85), + * because that's what the dd EBCDIC->ASCII table maps the EBCDIC newline + * character to. It might be more appropriate to include it in the 8859 + * set instead of the ASCII set, but it's got to be included in *something* + * we recognize or EBCDIC files aren't going to be considered textual. + * Some old Unix source files use SO/SI (^N/^O) to shift between Greek + * and Latin characters, so these should possibly be allowed. But they + * make a real mess on VT100-style displays if they're not paired properly, + * so we are probably better off not calling them text. + * + * A file is considered to be ISO-8859 text if its characters are all + * either ASCII, according to the above definition, or printing characters + * from the ISO-8859 8-bit extension, characters 0xA0 ... 0xFF. + * + * Finally, a file is considered to be international text from some other + * character code if its characters are all either ISO-8859 (according to + * the above definition) or characters in the range 0x80 ... 0x9F, which + * ISO-8859 considers to be control characters but the IBM PC and Macintosh + * consider to be printing characters. + */ + +#define F 0 /* character never appears in text */ +#define T 1 /* character appears in plain ASCII text */ +#define I 2 /* character appears in ISO-8859 text */ +#define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */ + +static char text_chars[256] = { + /* BEL BS HT LF FF CR */ + F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F, /* 0x0X */ + /* ESC */ + 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 */ + /* NEL */ + X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X, /* 0x8X */ + X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, /* 0x9X */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xaX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xbX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xcX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xdX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xeX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I /* 0xfX */ +}; + +static int +looks_ascii(buf, nbytes, ubuf, ulen) + const unsigned char *buf; + int nbytes; + unichar *ubuf; + int *ulen; +{ + int i; + + *ulen = 0; + + for (i = 0; i < nbytes; i++) { + int t = text_chars[buf[i]]; + + if (t != T) + return 0; + + ubuf[(*ulen)++] = buf[i]; } + return 1; +} + +static int +looks_latin1(buf, nbytes, ubuf, ulen) + const unsigned char *buf; + int nbytes; + unichar *ubuf; + int *ulen; +{ + int i; + + *ulen = 0; - /* Make sure we are dealing with ascii text before looking for tokens */ for (i = 0; i < nbytes; i++) { - if (!isascii(buf[i]) && !isalpha(buf[i])) - return 0; /* not all ASCII */ + int t = text_chars[buf[i]]; + + if (t != T && t != I) + return 0; + + ubuf[(*ulen)++] = buf[i]; } - /* 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); - s[nbytes] = '\0'; - has_escapes = (memchr(s, '\033', nbytes) != NULL); - while ((token = strtok((char *) s, " \t\n\r\f")) != NULL) { - s = NULL; /* make strtok() keep on tokin' */ - for (p = names; p < names + NNAMES; p++) { - if (STREQ(p->name, token)) { - ckfputs(iflag ? types[p->type].mime : types[p->type].human, stdout); - if (has_escapes) - ckfputs(" (with escape sequences)", - stdout); - return 1; + return 1; +} + +static int +looks_extended(buf, nbytes, ubuf, ulen) + const unsigned char *buf; + int nbytes; + unichar *ubuf; + int *ulen; +{ + int i; + + *ulen = 0; + + for (i = 0; i < nbytes; i++) { + int t = text_chars[buf[i]]; + + if (t != T && t != I && t != X) + return 0; + + ubuf[(*ulen)++] = buf[i]; + } + + return 1; +} + +int +looks_utf8(buf, nbytes, ubuf, ulen) + const unsigned char *buf; + int nbytes; + unichar *ubuf; + int *ulen; +{ + int i, n; + unichar c; + int gotone = 0; + + *ulen = 0; + + for (i = 0; i < nbytes; i++) { + if ((buf[i] & 0x80) == 0) { /* 0xxxxxxx is plain ASCII */ + /* + * Even if the whole file is valid UTF-8 sequences, + * still reject it if it uses weird control characters. + */ + + if (text_chars[buf[i]] != T) + return 0; + + ubuf[(*ulen)++] = buf[i]; + } else if ((buf[i] & 0x40) == 0) { /* 10xxxxxx never 1st byte */ + return 0; + } else { /* 11xxxxxx begins UTF-8 */ + int following; + + if ((buf[i] & 0x20) == 0) { /* 110xxxxx */ + c = buf[i] & 0x1f; + following = 1; + } else if ((buf[i] & 0x10) == 0) { /* 1110xxxx */ + c = buf[i] & 0x0f; + following = 2; + } else if ((buf[i] & 0x08) == 0) { /* 11110xxx */ + c = buf[i] & 0x07; + following = 3; + } else if ((buf[i] & 0x04) == 0) { /* 111110xx */ + c = buf[i] & 0x03; + following = 4; + } else if ((buf[i] & 0x02) == 0) { /* 1111110x */ + c = buf[i] & 0x01; + following = 5; + } else + return 0; + + for (n = 0; n < following; n++) { + i++; + if (i >= nbytes) + goto done; + + if ((buf[i] & 0x80) == 0 || (buf[i] & 0x40)) + return 0; + + c = (c << 6) + (buf[i] & 0x3f); } + + ubuf[(*ulen)++] = c; + gotone = 1; } } +done: + return gotone; /* don't claim it's UTF-8 if it's all 7-bit */ +} + +static int +looks_unicode(buf, nbytes, ubuf, ulen) + const unsigned char *buf; + int nbytes; + unichar *ubuf; + int *ulen; +{ + int bigend; + int i; + + if (nbytes < 2) + return 0; + + if (buf[0] == 0xff && buf[1] == 0xfe) + bigend = 0; + else if (buf[0] == 0xfe && buf[1] == 0xff) + bigend = 1; + else + return 0; - /* all else fails, but it is ASCII... */ - ckfputs(iflag ? "text/plain, ASCII" : "ASCII text", stdout); - if (has_escapes) { - ckfputs(" (with escape sequences)", stdout); + *ulen = 0; + + for (i = 2; i + 1 < nbytes; i += 2) { + /* XXX fix to properly handle chars > 65536 */ + + if (bigend) + ubuf[(*ulen)++] = buf[i + 1] + 256 * buf[i]; + else + ubuf[(*ulen)++] = buf[i] + 256 * buf[i + 1]; + + if (ubuf[*ulen - 1] == 0xfffe) + return 0; + if (ubuf[*ulen - 1] < 128 && text_chars[ubuf[*ulen - 1]] != T) + return 0; } + return 1; } + +#undef F +#undef T +#undef I +#undef X + +/* + * This table maps each EBCDIC character to an (8-bit extended) ASCII + * character, as specified in the rationale for the dd(1) command in + * draft 11.2 (September, 1991) of the POSIX P1003.2 standard. + * + * Unfortunately it does not seem to correspond exactly to any of the + * five variants of EBCDIC documented in IBM's _Enterprise Systems + * Architecture/390: Principles of Operation_, SA22-7201-06, Seventh + * Edition, July, 1999, pp. I-1 - I-4. + * + * Fortunately, though, all versions of EBCDIC, including this one, agree + * on most of the printing characters that also appear in (7-bit) ASCII. + * Of these, only '|', '!', '~', '^', '[', and ']' are in question at all. + * + * Fortunately too, there is general agreement that codes 0x00 through + * 0x3F represent control characters, 0x41 a nonbreaking space, and the + * remainder printing characters. + * + * This is sufficient to allow us to identify EBCDIC text and to distinguish + * between old-style and internationalized examples of text. + */ + +unsigned char ebcdic_to_ascii[] = { + 0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31, +128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7, +144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26, +' ', 160, 161, 162, 163, 164, 165, 166, 167, 168, 213, '.', '<', '(', '+', '|', +'&', 169, 170, 171, 172, 173, 174, 175, 176, 177, '!', '$', '*', ')', ';', '~', +'-', '/', 178, 179, 180, 181, 182, 183, 184, 185, 203, ',', '%', '_', '>', '?', +186, 187, 188, 189, 190, 191, 192, 193, 194, '`', ':', '#', '@', '\'','=', '"', +195, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 196, 197, 198, 199, 200, 201, +202, 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', '^', 204, 205, 206, 207, 208, +209, 229, 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 210, 211, 212, '[', 214, 215, +216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, ']', 230, 231, +'{', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 232, 233, 234, 235, 236, 237, +'}', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 238, 239, 240, 241, 242, 243, +'\\',159, 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 244, 245, 246, 247, 248, 249, +'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 250, 251, 252, 253, 254, 255 +}; + +/* + * The following EBCDIC-to-ASCII table may relate more closely to reality, + * or at least to modern reality. It comes from + * + * http://ftp.s390.ibm.com/products/oe/bpxqp9.html + * + * and maps the characters of EBCDIC code page 1047 (the code used for + * Unix-derived software on IBM's 390 systems) to the corresponding + * characters from ISO 8859-1. + * + * If this table is used instead of the above one, some of the special + * cases for the NEL character can be taken out of the code. + */ + +unsigned char ebcdic_1047_to_8859[] = { +0x00,0x01,0x02,0x03,0x9C,0x09,0x86,0x7F,0x97,0x8D,0x8E,0x0B,0x0C,0x0D,0x0E,0x0F, +0x10,0x11,0x12,0x13,0x9D,0x0A,0x08,0x87,0x18,0x19,0x92,0x8F,0x1C,0x1D,0x1E,0x1F, +0x80,0x81,0x82,0x83,0x84,0x85,0x17,0x1B,0x88,0x89,0x8A,0x8B,0x8C,0x05,0x06,0x07, +0x90,0x91,0x16,0x93,0x94,0x95,0x96,0x04,0x98,0x99,0x9A,0x9B,0x14,0x15,0x9E,0x1A, +0x20,0xA0,0xE2,0xE4,0xE0,0xE1,0xE3,0xE5,0xE7,0xF1,0xA2,0x2E,0x3C,0x28,0x2B,0x7C, +0x26,0xE9,0xEA,0xEB,0xE8,0xED,0xEE,0xEF,0xEC,0xDF,0x21,0x24,0x2A,0x29,0x3B,0x5E, +0x2D,0x2F,0xC2,0xC4,0xC0,0xC1,0xC3,0xC5,0xC7,0xD1,0xA6,0x2C,0x25,0x5F,0x3E,0x3F, +0xF8,0xC9,0xCA,0xCB,0xC8,0xCD,0xCE,0xCF,0xCC,0x60,0x3A,0x23,0x40,0x27,0x3D,0x22, +0xD8,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0xAB,0xBB,0xF0,0xFD,0xFE,0xB1, +0xB0,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0xAA,0xBA,0xE6,0xB8,0xC6,0xA4, +0xB5,0x7E,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0xA1,0xBF,0xD0,0x5B,0xDE,0xAE, +0xAC,0xA3,0xA5,0xB7,0xA9,0xA7,0xB6,0xBC,0xBD,0xBE,0xDD,0xA8,0xAF,0x5D,0xB4,0xD7, +0x7B,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0xAD,0xF4,0xF6,0xF2,0xF3,0xF5, +0x7D,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0xB9,0xFB,0xFC,0xF9,0xFA,0xFF, +0x5C,0xF7,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0xB2,0xD4,0xD6,0xD2,0xD3,0xD5, +0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0xB3,0xDB,0xDC,0xD9,0xDA,0x9F +}; + +/* + * Copy buf[0 ... nbytes-1] into out[], translating EBCDIC to ASCII. + */ +static void +from_ebcdic(buf, nbytes, out) + const unsigned char *buf; + int nbytes; + unsigned char *out; +{ + int i; + + for (i = 0; i < nbytes; i++) { + out[i] = ebcdic_to_ascii[buf[i]]; + } +} diff --git a/usr.bin/file/compress.c b/usr.bin/file/compress.c index 314a197bb0b..088eb1d5a70 100644 --- a/usr.bin/file/compress.c +++ b/usr.bin/file/compress.c @@ -1,4 +1,4 @@ -/* $NetBSD: compress.c,v 1.8 2000/05/14 22:53:37 christos Exp $ */ +/* $NetBSD: compress.c,v 1.9 2000/09/22 16:34:59 pooka Exp $ */ /* * compress routines: @@ -20,26 +20,27 @@ #include <sys/cdefs.h> #ifndef lint #if 0 -FILE_RCSID("@(#)Id: compress.c,v 1.15 1999/11/28 20:02:29 christos Exp ") +FILE_RCSID("@(#)Id: compress.c,v 1.17 2000/08/05 17:36:47 christos Exp ") #else -__RCSID("$NetBSD: compress.c,v 1.8 2000/05/14 22:53:37 christos Exp $"); +__RCSID("$NetBSD: compress.c,v 1.9 2000/09/22 16:34:59 pooka Exp $"); #endif #endif static struct { - const char *magic; - int maglen; - const char *const argv[3]; - int silent; + const char *magic; + int maglen; + const char *const argv[3]; + int silent; } compr[] = { - { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, /* compressed */ - { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */ - { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */ - { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */ - /* the standard pack utilities do not accept standard input */ - { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */ - { "BZh", 3, { "bzip2", "-d", NULL }, 1 }, /* bzip2-ed */ + { "\037\235", 2, { "uncompress", "-c", NULL }, 0 }, /* compressed */ + { "\037\235", 2, { "gzip", "-cdq", NULL }, 1 }, /* compressed */ + { "\037\213", 2, { "gzip", "-cdq", NULL }, 1 }, /* gzipped */ + { "\037\236", 2, { "gzip", "-cdq", NULL }, 1 }, /* frozen */ + { "\037\240", 2, { "gzip", "-cdq", NULL }, 1 }, /* SCO LZH */ + /* the standard pack utilities do not accept standard input */ + { "\037\036", 2, { "gzip", "-cdq", NULL }, 0 }, /* packed */ + { "BZh", 3, { "bzip2", "-d", NULL }, 1 }, /* bzip2-ed */ }; static int ncompr = sizeof(compr) / sizeof(compr[0]); @@ -49,8 +50,8 @@ static int uncompress __P((int, const unsigned char *, unsigned char **, int)); int zmagic(buf, nbytes) -unsigned char *buf; -int nbytes; + unsigned char *buf; + int nbytes; { unsigned char *newbuf; int newsize; @@ -59,30 +60,30 @@ int nbytes; for (i = 0; i < ncompr; i++) { if (nbytes < compr[i].maglen) continue; - if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0) - break; + if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 && + (newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) { + tryit(newbuf, newsize, 1); + free(newbuf); + printf(" ("); + tryit(buf, nbytes, 0); + printf(")"); + return 1; + } } if (i == ncompr) return 0; - if ((newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) { - tryit(newbuf, newsize, 1); - free(newbuf); - printf(" ("); - tryit(buf, nbytes, 0); - printf(")"); - } return 1; } static int uncompress(method, old, newch, n) -int method; -const unsigned char *old; -unsigned char **newch; -int n; + int method; + const unsigned char *old; + unsigned char **newch; + int n; { int fdin[2], fdout[2]; @@ -102,12 +103,11 @@ int n; (void) close(fdout[0]); (void) close(fdout[1]); if (compr[method].silent) - (void) close(2); + (void) close(2); execvp(compr[method].argv[0], (char *const *)compr[method].argv); - error("could not execute `%s' (%s).\n", - compr[method].argv[0], strerror(errno)); + exit(1); /*NOTREACHED*/ case -1: error("could not fork (%s).\n", strerror(errno)); @@ -116,19 +116,14 @@ int n; default: /* parent */ (void) close(fdin[0]); (void) close(fdout[1]); - if (write(fdin[1], old, n) != n) { - error("write failed (%s).\n", strerror(errno)); - /*NOTREACHED*/ - } + if (write(fdin[1], old, n) != n) + return 0; (void) close(fdin[1]); - if ((*newch = (unsigned char *) malloc(n)) == NULL) { - error("out of memory.\n"); - /*NOTREACHED*/ - } + if ((*newch = (unsigned char *) malloc(n)) == NULL) + return 0; if ((n = read(fdout[0], *newch, n)) <= 0) { free(*newch); - error("read failed (%s).\n", strerror(errno)); - /*NOTREACHED*/ + return 0; } (void) close(fdout[0]); (void) wait(NULL); diff --git a/usr.bin/file/file.1 b/usr.bin/file/file.1 index 13b381b2f88..a876aaf514d 100644 --- a/usr.bin/file/file.1 +++ b/usr.bin/file/file.1 @@ -1,7 +1,7 @@ -.\" $NetBSD: file.1,v 1.16 2000/05/14 22:53:37 christos Exp $ +.\" $NetBSD: file.1,v 1.17 2000/09/22 16:34:59 pooka Exp $ .\" .TH FILE __CSECTION__ "Copyright but distributable" -.\" Id: file.man,v 1.35 2000/05/14 17:58:36 christos Exp +.\" Id: file.man,v 1.36 2000/08/05 17:36:48 christos Exp .SH NAME file \- determine file type @@ -33,7 +33,7 @@ test that succeeds causes the file type to be printed. The type printed will usually contain one of the words .B text (the file contains only -.SM ASCII +printing characters and a few common control characters and is probably safe to read on an .SM ASCII terminal), @@ -51,7 +51,7 @@ or the program itself, .B "preserve these keywords" . People depend on knowing that all the readable files in a directory have the word ``text'' printed. -Don't do as Berkeley did \- change ``shell commands text'' +Don't do as Berkeley did and change ``shell commands text'' to ``shell script''. .PP The filesystem tests are based on examining the return from a @@ -64,7 +64,7 @@ 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 -.IR sys/stat.h . +.IR <sys/stat.h> . .PP The magic number tests are used to check for files with data in particular fixed formats. @@ -81,14 +81,36 @@ that the file is a binary executable, and which of several types thereof. The concept of `magic number' has been applied by extension to data files. Any file with some invariant identifier at a small fixed offset into the file can usually be described in this way. -The information in these files is read from the magic file -.I /usr/share/misc/magic +The information identifying these files is read from the magic file +.I /usr/share/misc/magic. +.PP +If a file does not match any of the entries in the magic file, +it is examined to see if it seems to be a text file. +ASCII, ISO-8859-x, non-ISO 8-bit extended-ASCII character sets +(such as those used on Macintosh and IBM PC systems), +UTF-8-encoded Unicode, UTF-16-encoded Unicode, and EBCDIC +character sets can be distinguished by the different +ranges and sequences of bytes that constitute printable text +in each set. +If a file passes any of these tests, its character set is reported. +ASCII, ISO-8859-x, UTF-8, and extended-ASCII files are identified +as ``text'' because they will be mostly readable on nearly any terminal; +UTF-16 and EBCDIC are only ``character data'' because, while +they contain text, it is text that will require translation +before it can be read. +In addition, +.B file +will attempt to determine other characteristics of text-type files. +If the lines of a file are terminated by CR, CRLF, or NEL, instead +of the Unix-standard LF, this will be reported. +Files that contain embedded escape sequences or overstriking +will also be identified. .PP -If an argument appears to be an -.SM ASCII -file, +Once .B file -attempts to guess its language. +has determined the character set used in a text-type file, +it will +attempt to determine in what language the file is written. The language tests look for particular strings (cf .IR names.h ) that can appear anywhere in the first few blocks of a file. @@ -104,8 +126,10 @@ two groups, so they are performed last. The language test routines also test for some miscellany (such as .BR tar (1) -archives) and determine whether an unknown file should be -labelled as `ascii text' or `data'. +archives). +.PP +Any file that cannot be identified as having been written +in any of the character sets listed above is simply said to be ``data''. .SH OPTIONS .TP 8 .B \-b @@ -125,15 +149,18 @@ before the argument list. Either .I namefile or at least one filename argument must be present; -to test the standard input, use ``-'' as a filename argument. +to test the standard input, use ``\-'' as a filename argument. .TP 8 .B \-i Causes the file command to output mime type strings rather than the more -traditional human readable ones. Thus it may say "text/plain, ASCII" rather -than "ASCII text". In order for this option to work, file changes the way +traditional human readable ones. Thus it may say +``text/plain; charset=us-ascii'' +rather +than ``ASCII text''. In order for this option to work, file changes the way it handles files recognised by the command it's self (such as many of the -text file types, directories etc), and makes use of an alternative "magic" file. -(See "FILES" section, below). +text file types, directories etc), and makes use of an alternative +``magic'' file. +(See ``FILES'' section, below). .TP 8 .B \-k Don't stop at the first match, keep going. @@ -282,7 +309,7 @@ file: application/x-executable, dynamically linked (uses shared libs), no There has been a .B file command in every \s-1UNIX\s0 since at least Research Version 6 -(man page dated January, 1975). +(man page dated January 16, 1975). The System V version introduced one significant major change: the external list of magic number types. This slowed the program down slightly but made it a lot more flexible. @@ -326,8 +353,12 @@ Changes by Ian Darwin and various authors including Christos Zoulas (christos@astron.com), 1990-1999. .PP Altered by Chris Lowth, chris@lowth.com, 2000: -Handle the "-i" option to output mime type strings and using an alternative +Handle the ``-i'' option to output mime type strings and using an alternative magic file and internal logic. +.PP +Altered by Eric Fischer (enf@pobox.com), July, 2000, +to identify character codes and attempt to identify the languages +of non-ASCII files. .SH LEGAL NOTICE Copyright (c) Ian F. Darwin, Toronto, Canada, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993. @@ -357,14 +388,16 @@ misrepresented as being the original software. Since few users ever read sources, credits must appear in the documentation. .PP 4. This notice may not be removed or altered. -.PP -A few support files (\fIgetopt\fP, \fIstrtok\fP) -distributed with this package -are by Henry Spencer and are subject to the same terms as above. -.PP -A few simple support files (\fIstrtol\fP, \fIstrchr\fP) -distributed with this package -are in the public domain; they are so marked. +.\" .PP +.\" A few support files (\fIgetopt\fP, \fIstrtok\fP) +.\" distributed with this package +.\" are by Henry Spencer and are subject to the same terms as above. +.\" .PP +.\" A few simple support files (\fIstrtol\fP, \fIstrchr\fP) +.\" distributed with this package +.\" are in the public domain; they are so marked. +.\" +.\" enf: commented out because these support files don't seem to be included .PP The files .I tar.h @@ -387,11 +420,11 @@ with the flexibility of the System V version. .B File uses several algorithms that favor speed over accuracy, thus it can be misled about the contents of -.SM ASCII +text files. .PP The support for -.SM ASCII +text files (primarily for programming languages) is simplistic, inefficient and requires recompilation to update. .PP @@ -430,10 +463,11 @@ The program should provide a way to give an estimate of ``how good'' a guess is. We end up removing guesses (e.g. ``From '' as first 5 chars of file) because they are not as good as other guesses (e.g. ``Newsgroups:'' versus -"Return-Path:"). Still, if the others don't pan out, it should be +``Return-Path:''). Still, if the others don't pan out, it should be possible to use the first guess. .PP This program is slower than some vendors' file commands. +The new support for multiple character codes makes it even slower. .PP This manual page, and particularly this section, is too long. .SH AVAILABILITY diff --git a/usr.bin/file/file.c b/usr.bin/file/file.c index cc25ba86e92..2fdc2634e44 100644 --- a/usr.bin/file/file.c +++ b/usr.bin/file/file.c @@ -1,4 +1,4 @@ -/* $NetBSD: file.c,v 1.16 2000/05/14 22:53:38 christos Exp $ */ +/* $NetBSD: file.c,v 1.17 2000/09/22 16:34:59 pooka Exp $ */ /* * file - find type of a file or files - main program. @@ -26,13 +26,14 @@ * * 4. This notice may not be removed or altered. */ +#include <sys/types.h> +#include <sys/param.h> /* for MAXPATHLEN */ +#include <sys/stat.h> + #include "file.h" #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/types.h> -#include <sys/param.h> /* for MAXPATHLEN */ -#include <sys/stat.h> #include <fcntl.h> /* for open() */ #ifdef RESTORE_TIME # if (__COHERENT__ >= 0x420) @@ -60,7 +61,7 @@ #if 0 FILE_RCSID("@(#)Id: file.c,v 1.51 2000/05/14 17:58:36 christos Exp ") #else -__RCSID("$NetBSD: file.c,v 1.16 2000/05/14 22:53:38 christos Exp $"); +__RCSID("$NetBSD: file.c,v 1.17 2000/09/22 16:34:59 pooka Exp $"); #endif #endif /* lint */ @@ -232,7 +233,7 @@ main(argc, argv) */ static void unwrap(fn) -char *fn; + char *fn; { char buf[MAXPATHLEN]; FILE *f; @@ -277,29 +278,28 @@ char *fn; */ static int byteconv4(from, same, big_endian) - int from; - int same; - int 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 */ + 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 */ } /* @@ -312,23 +312,22 @@ byteconv2(from, same, big_endian) 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 */ + 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 @@ -337,8 +336,8 @@ byteconv2(from, same, big_endian) */ void process(inname, wid) -const char *inname; -int wid; + const char *inname; + int wid; { int fd = 0; static const char stdname[] = "standard input"; @@ -361,22 +360,22 @@ int wid; (int) (wid - strlen(inname)), ""); if (inname != stdname) { - /* - * first try judging the file based on its filesystem status - */ - if (fsmagic(inname, &sb) != 0) { - putchar('\n'); - return; - } - - if ((fd = open(inname, O_RDONLY)) < 0) { - /* We can't open it, but we were able to stat it. */ - if (sb.st_mode & 0002) ckfputs("writeable, ", stdout); - if (sb.st_mode & 0111) ckfputs("executable, ", stdout); - ckfprintf(stdout, "can't read `%s' (%s).\n", - inname, strerror(errno)); - return; - } + /* + * first try judging the file based on its filesystem status + */ + if (fsmagic(inname, &sb) != 0) { + putchar('\n'); + return; + } + + if ((fd = open(inname, O_RDONLY)) < 0) { + /* We can't open it, but we were able to stat it. */ + if (sb.st_mode & 0002) ckfputs("writeable, ", stdout); + if (sb.st_mode & 0111) ckfputs("executable, ", stdout); + ckfprintf(stdout, "can't read `%s' (%s).\n", + inname, strerror(errno)); + return; + } } @@ -396,8 +395,17 @@ int wid; } #ifdef BUILTIN_ELF - if (match == 's' && nbytes > 5) + if (match == 's' && nbytes > 5) { + /* + * We matched something in the file, so this *might* + * be an ELF file, and the file is at least 5 bytes long, + * so if it's an ELF file it has at least one byte + * past the ELF magic number - try extracting information + * from the ELF headers that can't easily be extracted + * with rules in the magic file. + */ tryelf(fd, buf, nbytes); + } #endif if (inname != stdname) { @@ -430,8 +438,8 @@ int wid; int tryit(buf, nb, zflag) -unsigned char *buf; -int nb, zflag; + unsigned char *buf; + int nb, zflag; { /* try compression stuff */ if (zflag && zmagic(buf, nb)) @@ -445,10 +453,6 @@ 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'; diff --git a/usr.bin/file/file.h b/usr.bin/file/file.h index 61daf939dea..e962f2119f7 100644 --- a/usr.bin/file/file.h +++ b/usr.bin/file/file.h @@ -1,8 +1,8 @@ -/* $NetBSD: file.h,v 1.19 2000/05/14 22:53:38 christos Exp $ */ +/* $NetBSD: file.h,v 1.20 2000/09/22 16:34:59 pooka Exp $ */ /* * file.h - definitions for file(1) program - * @(#)Id: file.h,v 1.31 2000/04/11 02:32:35 christos Exp + * @(#)Id: file.h,v 1.32 2000/05/14 22:58:53 christos Exp * * Copyright (c) Ian F. Darwin, 1987. * Written by Ian F. Darwin. diff --git a/usr.bin/file/fsmagic.c b/usr.bin/file/fsmagic.c index 61aa46c0c96..5b85f6c6605 100644 --- a/usr.bin/file/fsmagic.c +++ b/usr.bin/file/fsmagic.c @@ -1,4 +1,4 @@ -/* $NetBSD: fsmagic.c,v 1.14 2000/05/14 22:53:38 christos Exp $ */ +/* $NetBSD: fsmagic.c,v 1.15 2000/09/22 16:35:00 pooka Exp $ */ /* * fsmagic - magic based on filesystem info - directory, special files, etc. @@ -60,14 +60,14 @@ #if 0 FILE_RCSID("@(#)Id: fsmagic.c,v 1.31 2000/04/11 02:32:35 christos Exp ") #else -__RCSID("$NetBSD: fsmagic.c,v 1.14 2000/05/14 22:53:38 christos Exp $"); +__RCSID("$NetBSD: fsmagic.c,v 1.15 2000/09/22 16:35:00 pooka Exp $"); #endif #endif /* lint */ int fsmagic(fn, sb) -const char *fn; -struct stat *sb; + const char *fn; + struct stat *sb; { int ret = 0; @@ -175,7 +175,7 @@ struct stat *sb; case S_IFLNK: { char buf[BUFSIZ+4]; - register int nch; + int nch; struct stat tstatbuf; if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) { @@ -256,4 +256,3 @@ struct stat *sb; } return 0; } - diff --git a/usr.bin/file/is_tar.c b/usr.bin/file/is_tar.c index 3ace58b7dac..ef701e2269f 100644 --- a/usr.bin/file/is_tar.c +++ b/usr.bin/file/is_tar.c @@ -1,4 +1,4 @@ -/* $NetBSD: is_tar.c,v 1.11 1999/11/01 17:39:26 christos Exp $ */ +/* $NetBSD: is_tar.c,v 1.12 2000/09/22 16:35:00 pooka Exp $ */ /* * is_tar() -- figure out whether file is a tar archive. @@ -7,7 +7,7 @@ * Public 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.12 1999/02/14 17:16:08 christos Exp + * Id: is_tar.c,v 1.13 2000/08/05 17:36:48 christos Exp * * Comments changed and some code/comments reformatted * for file command by Ian Darwin. @@ -23,9 +23,9 @@ #include <sys/cdefs.h> #ifndef lint #if 0 -FILE_RCSID("@(#)Id: is_tar.c,v 1.12 1999/02/14 17:16:08 christos Exp ") +FILE_RCSID("@(#)Id: is_tar.c,v 1.13 2000/08/05 17:36:48 christos Exp ") #else -__RCSID("$NetBSD: is_tar.c,v 1.11 1999/11/01 17:39:26 christos Exp $"); +__RCSID("$NetBSD: is_tar.c,v 1.12 2000/09/22 16:35:00 pooka Exp $"); #endif #endif @@ -41,13 +41,13 @@ static int from_oct __P((int, char *)); /* Decode octal number */ */ int is_tar(buf, nbytes) -unsigned char *buf; -int nbytes; + unsigned char *buf; + int nbytes; { - register union record *header = (union record *)buf; - register int i; - register int sum, recsum; - register char *p; + union record *header = (union record *)buf; + int i; + int sum, recsum; + char *p; if (nbytes < sizeof(union record)) return 0; @@ -86,12 +86,12 @@ int nbytes; */ static int from_oct(digs, where) - register int digs; - register char *where; + int digs; + char *where; { - register int value; + int value; - while (isspace((unsigned char)*where)) { /* Skip spaces */ + while (isspace((unsigned char)*where)) { /* Skip spaces */ where++; if (--digs <= 0) return -1; /* All blank field */ diff --git a/usr.bin/file/magdir/alpha b/usr.bin/file/magdir/alpha index 1a8cb147207..c0191fb931e 100644 --- a/usr.bin/file/magdir/alpha +++ b/usr.bin/file/magdir/alpha @@ -17,5 +17,14 @@ # Basic recognition of Digital UNIX core dumps - Mike Bremford <mike@opac.bl.uk> # +# The actual magic number is just "Core", followed by a 2-byte version +# number; however, treating any file that begins with "Core" as a Digital +# UNIX core dump file may produce too many false hits, so we include one +# byte of the version number as well; DU 5.0 appears only to be up to +# version 2. +# 0 string Core\001 Alpha COFF format core dump (Digital UNIX) >24 string >\0 \b, from '%s' +0 string Core\002 Alpha COFF format core dump (Digital UNIX) +>24 string >\0 \b, from '%s' + diff --git a/usr.bin/file/magdir/animation b/usr.bin/file/magdir/animation index 5e1ce76fa5a..de0bf518286 100644 --- a/usr.bin/file/magdir/animation +++ b/usr.bin/file/magdir/animation @@ -11,8 +11,16 @@ #>4 beshort&0xfff0 x (%d x #>5 beshort&0x0fff x %d) 0 belong 0x000001ba MPEG system stream data + # MPEG Audio (*.mpx) # from dreesen@math.fu-berlin.de + +# XXX +# This conflicts with the FF FE signature for UTF-16-encoded Unicode +# text, which will be identified as an MP3 file. I don't have any MP3s +# so I don't know how to (or even if it's possible to) change this to +# tell the two apart. enf@pobox.com + 0 beshort &0xfff0 MP # MPEG 1.0 >1 byte&0x08 =0x08 \b diff --git a/usr.bin/file/magdir/apple b/usr.bin/file/magdir/apple index 20231293fe6..35dd435727d 100644 --- a/usr.bin/file/magdir/apple +++ b/usr.bin/file/magdir/apple @@ -10,3 +10,107 @@ 0 belong 0x00051600 AppleSingle encoded Macintosh file 0 belong 0x00051607 AppleDouble encoded Macintosh file +# magic for Newton PDA package formats +# from Ruda Moura <ruda@helllabs.org> +0 string package Newton package, +>7 byte 48 NOS 1.x, +>7 byte 49 NOS 2.x, +>12 belong &0x80000000 AutoRemove, +>12 belong &0x40000000 CopyProtect, +>12 belong &0x10000000 NoCompression, +>12 belong &0x04000000 Relocation, +>12 belong &0x02000000 UseFasterCompression, +>16 belong x version %d + +# The following entries for the Apple II are for files that have +# been transferred as raw binary data from an Apple, without having +# been encapsulated by any of the above archivers. +# +# In general, Apple II formats are hard to identify because Apple DOS +# and especially Apple ProDOS have strong typing in the file system and +# therefore programmers never felt much need to include type information +# in the files themselves. +# +# Eric Fischer <enf@pobox.com> + +# AppleWorks word processor: +# +# This matches the standard tab stops for an AppleWorks file, but if +# a file has a tab stop set in the first four columns this will fail. +# +# The "O" is really the magic number, but that's so common that it's +# necessary to check the tab stops that follow it to avoid false positives. + +4 string O==== AppleWorks word processor data +>85 byte&0x01 >0 \b, zoomed +>90 byte&0x01 >0 \b, paginated +>92 byte&0x01 >0 \b, with mail merge +#>91 byte x \b, left margin %d + +# AppleWorks database: +# +# This isn't really a magic number, but it's the closest thing to one +# that I could find. The 1 and 2 really mean "order in which you defined +# categories" and "left to right, top to bottom," respectively; the D and R +# mean that the cursor should move either down or right when you press Return. + +30 string \x01D AppleWorks database data +30 string \x02D AppleWorks database data +30 string \x01R AppleWorks database data +30 string \x02R AppleWorks database data + +# AppleWorks spreadsheet: +# +# Likewise, this isn't really meant as a magic number. The R or C means +# row- or column-order recalculation; the A or M means automatic or manual +# recalculation. + +131 string RA AppleWorks spreadsheet data +131 string RM AppleWorks spreadsheet data +131 string CA AppleWorks spreadsheet data +131 string CM AppleWorks spreadsheet data + +# Applesoft BASIC: +# +# This is incredibly sloppy, but will be true if the program was +# written at its usual memory location of 2048 and its first line +# number is less than 256. Yuck. + +0 belong&0xff00ff 0x80000 Applesoft BASIC program data +#>2 leshort x \b, first line number %d + +# ORCA/EZ assembler: +# +# This will not identify ORCA/M source files, since those have +# some sort of date code instead of the two zero bytes at 6 and 7 +# XXX Conflicts with ELF +#4 belong&0xff00ffff 0x01000000 ORCA/EZ assembler source data +#>5 byte x \b, build number %d + +# Broderbund Fantavision +# +# I don't know what these values really mean, but they seem to recur. +# Will they cause too many conflicts? + +# Probably :-) +#2 belong&0xFF00FF 0x040008 Fantavision movie data + +# Some attempts at images. +# +# These are actually just bit-for-bit dumps of the frame buffer, so +# there's really no reasonably way to distinguish them except for their +# address (if preserved) -- 8192 or 16384 -- and their length -- 8192 +# or, occasionally, 8184. +# +# Nevertheless this will manage to catch a lot of images that happen +# to have a solid-colored line at the bottom of the screen. + +8144 string \x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F Apple II image with white background +8144 string \x55\x2A\x55\x2A\x55\x2A\x55\x2A Apple II image with purple background +8144 string \x2A\x55\x2A\x55\x2A\x55\x2A\x55 Apple II image with green background +8144 string \xD5\xAA\xD5\xAA\xD5\xAA\xD5\xAA Apple II image with blue background +8144 string \xAA\xD5\xAA\xD5\xAA\xD5\xAA\xD5 Apple II image with orange background + +# Beagle Bros. Apple Mechanic fonts + +0 belong&0xFF00FFFF 0x6400D000 Apple Mechanic font diff --git a/usr.bin/file/magdir/commands b/usr.bin/file/magdir/commands index f7aeda45e55..16308aa67f4 100644 --- a/usr.bin/file/magdir/commands +++ b/usr.bin/file/magdir/commands @@ -44,6 +44,13 @@ 0 string/b #!\ /bin/bash Bourne-Again shell script text executable 0 string/b #!\ /usr/local/bin/bash Bourne-Again shell script text executable +# using env +0 string #!/usr/bin/env a +>15 string >\0 %s script text executable +0 string #!\ /usr/bin/env a +>16 string >\0 %s script text executable + + # generic shell magic 0 string #!\ / a >3 string >\0 %s script text executable diff --git a/usr.bin/file/magdir/database b/usr.bin/file/magdir/database index 071576c4f55..60058a61bce 100644 --- a/usr.bin/file/magdir/database +++ b/usr.bin/file/magdir/database @@ -12,84 +12,59 @@ 0 lelong 0x13579ace GNU dbm 1.x or ndbm database, little endian 0 string GDBM GNU dbm 2.x database # -0 belong 0x061561 Berkeley DB ->4 belong >2 1.86 ->4 belong <3 1.85 ->8 belong 4321 Hash/Big Endian ->8 belong 1234 Hash/Little Endian ->4 belong >0 (Version %d, ->12 belong x Bucket Size %d, ->16 belong x Bucket Shift %d, ->20 belong x Directory Size %d, ->24 belong x Segment Size %d, ->28 belong x Segment Shift %d, ->32 belong x Overflow Point %d, ->36 belong x Last Freed %d, ->40 belong x Max Bucket %d, ->44 belong x High Mask 0x%x, ->48 belong x Low Mask 0x%x, ->52 belong x Fill Factor %d, ->56 belong x Number of Keys %d) +# Berkeley DB # +# Ian Darwin's file /etc/magic files: big/little-endian version. # -0 belong 0x053162 Berkeley DB 1.85/1.86 Btree/Big Endian ->4 belong >0 (Version %d, ->8 belong x Page Size %d, ->12 belong x Free Page %d, ->16 belong x Number of Records %d, ->20 belong x Flags 0x%x) -0 lelong 0x053162 Berkeley DB 1.85/1.86 Btree/Little Endian ->4 lelong >0 (Version %d, ->8 lelong x Page Size %d, ->12 lelong x Free Page %d, ->16 lelong x Number of Records %d, ->20 lelong x Flags 0x%x) -# -# -12 belong 0x061561 Berkeley DB 2.X Hash/Big Endian ->16 belong >0 (Version %d, ->0 belong x Logical sequence number: file - %d, ->4 belong x offset - %d, ->20 belong x Bucket Size %d, ->24 belong x Overflow Point %d, ->28 belong x Last Freed %d, ->32 belong x Max Bucket %d, ->36 belong x High Mask 0x%x, ->40 belong x Low Mask 0x%x, ->44 belong x Fill Factor %d, ->48 belong x Number of Keys %d) -# -# DB2.X formats from Khimenko Victor <khim@sch57.msk.ru> -# -12 lelong 0x061561 Berkeley DB 2.X Hash/Little Endian ->16 lelong >0 (Version %d, ->0 lelong x Logical sequence number: file - %d, ->4 lelong x offset - %d, ->20 lelong x Bucket Size %d, ->24 lelong x Overflow Point %d, ->28 lelong x Last Freed %d, ->32 lelong x Max Bucket %d, ->36 lelong x High Mask 0x%x, ->40 lelong x Low Mask 0x%x, ->44 lelong x Fill Factor %d, ->48 lelong x Number of Keys %d) -# -# -12 belong 0x053162 Berkeley DB 2.X Btree/Big Endian ->16 belong >0 (Version %d, ->0 belong x Logical sequence number: file - %d, ->4 belong x offset - %d, ->20 belong x Page Size %d, ->24 belong x Maxkey %d, ->28 belong x Minkey %d, ->32 belong x Free Page %d) -# -# -12 lelong 0x053162 Berkeley DB 2.X Btree/Little Endian ->16 lelong >0 (Version %d, ->0 lelong x Logical sequence number: file - %d, ->4 lelong x offset - %d, ->20 lelong x Page Size %d, ->24 lelong x Maxkey %d, ->28 lelong x Minkey %d, ->32 lelong x Free Page %d) +# Hash 1.85/1.86 databases store metadata in network byte order. +# Btree 1.85/1.86 databases store the metadata in host byte order. +# Hash and Btree 2.X and later databases store the metadata in host byte order. + +0 long 0x00061561 Berkeley DB +>8 belong 4321 +>>4 belong >2 1.86 +>>4 belong <3 1.85 +>>4 belong >0 (Hash, version %d, native byte-order) +>8 belong 1234 +>>4 belong >2 1.86 +>>4 belong <3 1.85 +>>4 belong >0 (Hash, version %d, little-endian) + +0 belong 0x00061561 Berkeley DB +>8 belong 4321 +>>4 belong >2 1.86 +>>4 belong <3 1.85 +>>4 belong >0 (Hash, version %d, big-endian) +>8 belong 1234 +>>4 belong >2 1.86 +>>4 belong <3 1.85 +>>4 belong >0 (Hash, version %d, native byte-order) + +0 long 0x00053162 Berkeley DB 1.85/1.86 +>4 long >0 (Btree, version %d, native byte-order) +0 belong 0x00053162 Berkeley DB 1.85/1.86 +>4 belong >0 (Btree, version %d, big-endian) +0 lelong 0x00053162 Berkeley DB 1.85/1.86 +>4 lelong >0 (Btree, version %d, little-endian) + +12 long 0x00061561 Berkeley DB +>16 long >0 (Hash, version %d, native byte-order) +12 belong 0x00061561 Berkeley DB +>16 belong >0 (Hash, version %d, big-endian) +12 lelong 0x00061561 Berkeley DB +>16 lelong >0 (Hash, version %d, little-endian) + +12 long 0x00053162 Berkeley DB +>16 long >0 (Btree, version %d, native byte-order) +12 belong 0x00053162 Berkeley DB +>16 belong >0 (Btree, version %d, big-endian) +12 lelong 0x00053162 Berkeley DB +>16 lelong >0 (Btree, version %d, little-endian) + +12 long 0x00042253 Berkeley DB +>16 long >0 (Queue, version %d, native byte-order) +12 belong 0x00042253 Berkeley DB +>16 belong >0 (Queue, version %d, big-endian) +12 lelong 0x00042253 Berkeley DB +>16 lelong >0 (Queue, version %d, little-endian) + diff --git a/usr.bin/file/magdir/filesystems b/usr.bin/file/magdir/filesystems index c6f6b40b2b4..80b5ea3c879 100644 --- a/usr.bin/file/magdir/filesystems +++ b/usr.bin/file/magdir/filesystems @@ -2,7 +2,6 @@ #------------------------------------------------------------------------------ # filesystems: file(1) magic for different filesystems # -0x438 leshort 0xEF53 Linux/i386 ext2 filesystem 0 string \366\366\366\366 PC formatted floppy with no filesystem # Sun disk labels # From /usr/include/sun/dklabel.h: @@ -76,3 +75,17 @@ >8256 lelong x disk rotational speed %drps, >8320 lelong 0 TIME optimization >8320 lelong 1 SPACE optimization + +# ext2/ext3 filesystems - Andreas Dilger <adilger@turbolabs.com> +0x438 leshort 0xEF53 Linux +>0x44c lelong x rev %d +>0x43e leshort x \b.%d +>0x45c lelong ^0x0000004 ext2 filesystem data +>>0x43a leshort ^0x0000001 (mounted or unclean) +>0x45c lelong &0x0000004 ext3 filesystem data +>>0x460 lelong &0x0000004 (needs journal recovery) +>0x43a leshort &0x0000002 (errors) +>0x460 lelong &0x0000001 (compressed) +#>0x460 lelong &0x0000002 (filetype) +#>0x464 lelong &0x0000001 (sparse_super) +>0x464 lelong &0x0000002 (large files) diff --git a/usr.bin/file/magdir/images b/usr.bin/file/magdir/images index eb7a2b0350d..7b5e6cb7ebb 100644 --- a/usr.bin/file/magdir/images +++ b/usr.bin/file/magdir/images @@ -255,7 +255,10 @@ 0 beshort 0x1010 PEX Binary Archive # Visio drawings -03000 string Visio\ (TM)\ Drawing %s +03000 string Visio\ (TM)\ Drawing %s # Tgif files 0 string \%TGIF\ x Tgif file version %s + +# DICOM medical imaging data +128 string DICM DICOM medical imaging data diff --git a/usr.bin/file/magdir/mail.news b/usr.bin/file/magdir/mail.news index 6577ea625ba..9713d29b3f4 100644 --- a/usr.bin/file/magdir/mail.news +++ b/usr.bin/file/magdir/mail.news @@ -19,3 +19,6 @@ 0 string Received: RFC 822 mail text 0 string MIME-Version: MIME entity text #0 string Content- MIME entity text + +# TNEF files... +0 lelong 0x223E9F78 Transport Neutral Encapsulation Format diff --git a/usr.bin/file/magdir/netbsd b/usr.bin/file/magdir/netbsd index f370cda2b2f..27c6a74dc84 100644 --- a/usr.bin/file/magdir/netbsd +++ b/usr.bin/file/magdir/netbsd @@ -30,6 +30,7 @@ >16 lelong >0 not stripped 0 belong&0377777777 041400507 NetBSD/i386 core >12 string >\0 from '%s' +>32 lelong !0 (signal %d) 0 belong&0377777777 041600413 NetBSD/m68k demand paged >0 byte &0x80 @@ -51,6 +52,7 @@ >16 belong >0 not stripped 0 belong&0377777777 041600507 NetBSD/m68k core >12 string >\0 from '%s' +>32 belong !0 (signal %d) 0 belong&0377777777 042000413 NetBSD/m68k4k demand paged >0 byte &0x80 @@ -72,6 +74,7 @@ >16 belong >0 not stripped 0 belong&0377777777 042000507 NetBSD/m68k4k core >12 string >\0 from '%s' +>32 belong !0 (signal %d) 0 belong&0377777777 042200413 NetBSD/ns32532 demand paged >0 byte &0x80 @@ -93,6 +96,7 @@ >16 lelong >0 not stripped 0 belong&0377777777 042200507 NetBSD/ns32532 core >12 string >\0 from '%s' +>32 lelong !0 (signal %d) 0 belong&0377777777 045200507 NetBSD/powerpc core >12 string >\0 from '%s' @@ -117,6 +121,7 @@ >16 belong >0 not stripped 0 belong&0377777777 042400507 NetBSD/sparc core >12 string >\0 from '%s' +>32 belong !0 (signal %d) 0 belong&0377777777 042600413 NetBSD/pmax demand paged >0 byte &0x80 @@ -138,6 +143,7 @@ >16 lelong >0 not stripped 0 belong&0377777777 042600507 NetBSD/pmax core >12 string >\0 from '%s' +>32 lelong !0 (signal %d) 0 belong&0377777777 043000413 NetBSD/vax 1k demand paged >0 byte &0x80 @@ -159,6 +165,7 @@ >16 lelong >0 not stripped 0 belong&0377777777 043000507 NetBSD/vax 1k core >12 string >\0 from '%s' +>32 lelong !0 (signal %d) 0 belong&0377777777 045400413 NetBSD/vax 4k demand paged >0 byte &0x80 @@ -180,6 +187,7 @@ >16 lelong >0 not stripped 0 belong&0377777777 045400507 NetBSD/vax 4k core >12 string >\0 from '%s' +>32 lelong !0 (signal %d) # NetBSD/alpha does not support (and has never supported) a.out objects, # so no rules are provided for them. NetBSD/alpha ELF objects are @@ -189,6 +197,7 @@ >10 leshort 0x0000 stripped 0 belong&0377777777 043200507 NetBSD/alpha core >12 string >\0 from '%s' +>32 belong !0 (signal %d) 0 belong&0377777777 043400413 NetBSD/mips demand paged >0 byte &0x80 @@ -210,6 +219,7 @@ >16 belong >0 not stripped 0 belong&0377777777 043400507 NetBSD/mips core >12 string >\0 from '%s' +>32 belong !0 (signal %d) 0 belong&0377777777 043600413 NetBSD/arm32 demand paged >0 byte &0x80 @@ -231,3 +241,4 @@ >16 lelong >0 not stripped 0 belong&0377777777 043600507 NetBSD/arm32 core >12 string >\0 from '%s' +>32 lelong !0 (signal %d) diff --git a/usr.bin/file/magdir/sniffer b/usr.bin/file/magdir/sniffer index 7188cd23993..81cb3130c61 100644 --- a/usr.bin/file/magdir/sniffer +++ b/usr.bin/file/magdir/sniffer @@ -105,6 +105,51 @@ >16 lelong x \b, capture length %d) # +# "libpcap"-with-Alexey-Kuznetsov's-patches capture files. +# (We call them "tcpdump capture file(s)" for now, as "tcpdump" is +# the main program that uses that format, but there are other programs +# that use "libpcap", or that use the same capture file format.) +# +0 ubelong 0xa1b2cd34 extended tcpdump capture file (big-endian) +>4 beshort x - version %d +>6 beshort x \b.%d +>20 belong 0 (No link-layer encapsulation +>20 belong 1 (Ethernet +>20 belong 2 (3Mb Ethernet +>20 belong 3 (AX.25 +>20 belong 4 (ProNET +>20 belong 5 (CHAOS +>20 belong 6 (IEEE 802.x network +>20 belong 7 (ARCNET +>20 belong 8 (SLIP +>20 belong 9 (PPP +>20 belong 10 (FDDI +>20 belong 11 (RFC 1483 ATM +>20 belong 12 (raw IP +>20 belong 13 (BSD/OS SLIP +>20 belong 14 (BSD/OS PPP +>16 belong x \b, capture length %d) +0 ulelong 0xa1b2cd34 extended tcpdump capture file (little-endian) +>4 leshort x - version %d +>6 leshort x \b.%d +>20 lelong 0 (No link-layer encapsulation +>20 lelong 1 (Ethernet +>20 lelong 2 (3Mb Ethernet +>20 lelong 3 (AX.25 +>20 lelong 4 (ProNET +>20 lelong 5 (CHAOS +>20 lelong 6 (IEEE 802.x network +>20 lelong 7 (ARCNET +>20 lelong 8 (SLIP +>20 lelong 9 (PPP +>20 lelong 10 (FDDI +>20 lelong 11 (RFC 1483 ATM +>20 lelong 12 (raw IP +>20 lelong 13 (BSD/OS SLIP +>20 lelong 14 (BSD/OS PPP +>16 lelong x \b, capture length %d) + +# # AIX "iptrace" capture files. # 0 string iptrace\ 2.0 "iptrace" capture file diff --git a/usr.bin/file/magdir/troff b/usr.bin/file/magdir/troff index ea75e8516db..ec964e8e2b9 100644 --- a/usr.bin/file/magdir/troff +++ b/usr.bin/file/magdir/troff @@ -11,7 +11,7 @@ 0 string \\" troff or preprocessor input text # ditroff intermediate output text -0 string x\ T ditroff text +0 string x\ T ditroff output text >4 string cat for the C/A/T phototypesetter >4 string ps for PostScript >4 string dvi for DVI diff --git a/usr.bin/file/names.h b/usr.bin/file/names.h index 691896513f3..12664a8ceab 100644 --- a/usr.bin/file/names.h +++ b/usr.bin/file/names.h @@ -1,4 +1,4 @@ -/* $NetBSD: names.h,v 1.10 2000/05/14 22:53:38 christos Exp $ */ +/* $NetBSD: names.h,v 1.11 2000/09/22 16:35:00 pooka Exp $ */ /* * Names.h - names and types used by ascmagic in file(1). @@ -12,7 +12,7 @@ * * See LEGAL.NOTICE * - * Id: names.h,v 1.17 2000/04/11 02:32:35 christos Exp + * Id: names.h,v 1.18 2000/08/05 17:36:49 christos Exp */ /* @@ -34,24 +34,26 @@ #define L_JAVA 10 /* Java code */ #define L_HTML 11 /* HTML */ #define L_BCPL 12 /* BCPL */ +#define L_M4 13 /* M4 */ static const struct { char *human; char *mime; } types[] = { - { "C program text", "text/x-c", }, - { "C++ program text", "text/x-c++" }, - { "FORTRAN program text", "text/x-fortran" }, - { "make commands text", "text/x-makefile" }, - { "PL/1 program text", "text/x-pl1" }, - { "assembler program text", "text/x-asm" }, - { "English text", "text/plain, English" }, - { "Pascal program text", "text/x-pascal" }, - { "mail text", "text/x-mail" }, - { "news text", "text/x-news" }, - { "Java program text", "text/x-java" }, - { "HTML document text", "text/html", }, - { "BCPL program text", "text/x-bcpl" }, + { "C program", "text/x-c", }, + { "C++ program", "text/x-c++" }, + { "FORTRAN program", "text/x-fortran" }, + { "make commands", "text/x-makefile" }, + { "PL/1 program", "text/x-pl1" }, + { "assembler program", "text/x-asm" }, + { "English", "text/plain, English" }, + { "Pascal program", "text/x-pascal" }, + { "mail", "text/x-mail" }, + { "news", "text/x-news" }, + { "Java program", "text/x-java" }, + { "HTML document", "text/html", }, + { "BCPL program", "text/x-bcpl" }, + { "M4 macro language pre-processor", "text/x-m4" }, { "can't happen error on names.h/types", "error/x-error" }, { 0, 0} }; @@ -98,6 +100,7 @@ static struct names { } names[] = { /* These must be sorted by eye for optimal hit rate */ /* Add to this list only after substantial meditation */ + {"dnl", L_M4}, {"import", L_JAVA}, {"\"libhdr\"", L_BCPL}, {"\"LIBHDR\"", L_BCPL}, diff --git a/usr.bin/file/patchlevel.h b/usr.bin/file/patchlevel.h index 64b1f2c36df..64093857628 100644 --- a/usr.bin/file/patchlevel.h +++ b/usr.bin/file/patchlevel.h @@ -1,13 +1,20 @@ -/* $NetBSD: patchlevel.h,v 1.11 2000/05/14 22:53:38 christos Exp $ */ +/* $NetBSD: patchlevel.h,v 1.12 2000/09/22 16:35:00 pooka Exp $ */ #define FILE_VERSION_MAJOR 3 -#define patchlevel 31 +#define patchlevel 32 /* * Patchlevel file for Ian Darwin's MAGIC command. - * Id: patchlevel.h,v 1.31 2000/05/14 17:58:36 christos Exp + * Id: patchlevel.h,v 1.32 2000/08/05 18:24:18 christos Exp * * Log: patchlevel.h,v + * Revision 1.32 2000/08/05 18:24:18 christos + * Correct indianness detection in elf (Charles Hannum) + * FreeBSD elf core support (Guy Harris) + * Use gzip in systems that don't have uncompress (Anthon van der Neut) + * Internationalization/EBCDIC support (Eric Fisher) + * Many many magic changes + * * Revision 1.31 2000/05/14 17:58:36 christos * - new magic for claris files * - new magic for mathematica and maple files @@ -24,7 +31,7 @@ * - magic fixes * * Revision 1.29 1999/11/28 20:02:29 christos - * new string/[Bcb] magic from anton, and adjustments to the magic files to + * new string/[Bcb] magic from anthon, and adjustments to the magic files to * use it. * * Revision 1.28 1999/10/31 22:11:48 christos diff --git a/usr.bin/file/print.c b/usr.bin/file/print.c index 375b4ff7eef..771116dd61e 100644 --- a/usr.bin/file/print.c +++ b/usr.bin/file/print.c @@ -1,4 +1,4 @@ -/* $NetBSD: print.c,v 1.17 2000/05/14 22:53:38 christos Exp $ */ +/* $NetBSD: print.c,v 1.18 2000/09/22 16:35:00 pooka Exp $ */ /* * print.c - debugging printout routines @@ -45,9 +45,9 @@ #include <sys/cdefs.h> #ifndef lint #if 0 -FILE_RCSID("@(#)Id: print.c,v 1.30 1999/11/28 20:02:29 christos Exp ") +FILE_RCSID("@(#)Id: print.c,v 1.31 2000/08/05 17:36:49 christos Exp ") #else -__RCSID("$NetBSD: print.c,v 1.17 2000/05/14 22:53:38 christos Exp $"); +__RCSID("$NetBSD: print.c,v 1.18 2000/09/22 16:35:00 pooka Exp $"); #endif #endif /* lint */ @@ -55,7 +55,7 @@ __RCSID("$NetBSD: print.c,v 1.17 2000/05/14 22:53:38 christos Exp $"); void mdump(m) -struct magic *m; + struct magic *m; { static const char *typ[] = { "invalid", "byte", "short", "invalid", "long", "string", "date", "beshort", @@ -93,37 +93,37 @@ struct magic *m; (void) fprintf(stderr, ",%c", m->reln); if (m->reln != 'x') { - switch (m->type) { - case BYTE: - case SHORT: - case LONG: - case LESHORT: - case LELONG: - case BESHORT: - case BELONG: - (void) fprintf(stderr, "%d", m->value.l); - break; - case STRING: - showstr(stderr, m->value.s, -1); - break; - case DATE: - case LEDATE: - case BEDATE: - { - time_t t = m->value.l; - char *rt, *pp = ctime(&t); - - if ((rt = strchr(pp, '\n')) != NULL) - *rt = '\0'; - (void) fprintf(stderr, "%s,", pp); - if (rt) - *rt = '\n'; - } - break; - default: - (void) fputs("*bad*", stderr); - break; - } + switch (m->type) { + case BYTE: + case SHORT: + case LONG: + case LESHORT: + case LELONG: + case BESHORT: + case BELONG: + (void) fprintf(stderr, "%d", m->value.l); + break; + case STRING: + showstr(stderr, m->value.s, -1); + break; + case DATE: + case LEDATE: + case BEDATE: + { + time_t t = m->value.l; + char *rt, *pp = ctime(&t); + + if ((rt = strchr(pp, '\n')) != NULL) + *rt = '\0'; + (void) fprintf(stderr, "%s,", pp); + if (rt) + *rt = '\n'; + } + break; + default: + (void) fputs("*bad*", stderr); + break; + } } (void) fprintf(stderr, ",\"%s\"]\n", m->desc); } @@ -134,8 +134,8 @@ struct magic *m; */ void ckfputs(str, fil) - const char *str; - FILE *fil; + const char *str; + FILE *fil; { if (fputs(str,fil) == EOF) error("write failed.\n"); diff --git a/usr.bin/file/readelf.c b/usr.bin/file/readelf.c index 540cf08ca97..5eee997df35 100644 --- a/usr.bin/file/readelf.c +++ b/usr.bin/file/readelf.c @@ -1,4 +1,4 @@ -/* $NetBSD: readelf.c,v 1.7 2000/07/26 15:19:35 mycroft Exp $ */ +/* $NetBSD: readelf.c,v 1.8 2000/09/22 16:35:00 pooka Exp $ */ #include "file.h" @@ -18,9 +18,9 @@ #include <sys/cdefs.h> #ifndef lint #if 0 -FILE_RCSID("@(#)Id: readelf.c,v 1.12 2000/04/11 02:32:35 christos Exp ") +FILE_RCSID("@(#)Id: readelf.c,v 1.16 2000/08/05 18:18:50 christos Exp ") #else -__RCSID("$NetBSD: readelf.c,v 1.7 2000/07/26 15:19:35 mycroft Exp $"); +__RCSID("$NetBSD: readelf.c,v 1.8 2000/09/22 16:35:00 pooka Exp $"); #endif #endif @@ -202,8 +202,10 @@ dophn_exec(class, swap, fd, off, num, size) #ifdef ELFCORE size_t prpsoffsets32[] = { + 8, /* FreeBSD */ + 28, /* Linux 2.0.36 */ + 32, /* Linux (I forget which kernel version) */ 84, /* SunOS 5.x */ - 32, /* Linux */ }; size_t prpsoffsets64[] = { @@ -217,14 +219,23 @@ size_t prpsoffsets64[] = { /* * 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. + * for a PT_NOTE section of type NT_PRPSINFO, with a name "CORE" or + * "FreeBSD"; 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. + * + * The signal number probably appears in a section of type NT_PRSTATUS, + * but that's also rather OS-dependent, in ways that are harder to + * dissect with heuristics, so I'm not bothering with the signal number. + * (I suppose the signal number could be of interest in situations where + * you don't have the binary of the program that dropped core; if you + * *do* have that binary, the debugger will probably tell you what + * signal it was.) */ static void dophn_core(class, swap, fd, off, num, size) @@ -239,12 +250,16 @@ dophn_core(class, swap, fd, off, num, size) Elf32_Nhdr *nh32; Elf64_Phdr ph64; Elf64_Nhdr *nh64; - size_t offset, noffset, reloffset; + size_t offset, nameoffset, noffset, reloffset; unsigned char c; int i, j; char nbuf[BUFSIZ]; int bufsize; + int is_freebsd; + /* + * Loop through all the program headers. + */ for ( ; num; num--) { if (lseek(fd, off, SEEK_SET) == -1) error("lseek failed (%s).\n", strerror(errno)); @@ -253,6 +268,11 @@ dophn_core(class, swap, fd, off, num, size) off += size; if (ph_type != PT_NOTE) continue; + + /* + * This is a PT_NOTE section; loop through all the notes + * in the section. + */ if (lseek(fd, (off_t) ph_offset, SEEK_SET) == -1) error("lseek failed (%s).\n", strerror(errno)); bufsize = read(fd, nbuf, BUFSIZ); @@ -281,7 +301,8 @@ dophn_core(class, swap, fd, off, num, size) } /* - * Make sure this note has the name "CORE". + * Check whether this note has the name "CORE" or + * "FreeBSD". */ if (offset + nh_namesz >= bufsize) { /* @@ -289,58 +310,105 @@ dophn_core(class, swap, fd, off, num, size) */ break; } - if (nh_namesz != 5 - || strcmp(&nbuf[offset], "CORE") != 0) - continue; + + nameoffset = offset; offset += nh_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. + * Sigh. The 2.0.36 kernel in Debian 2.1, at + * least, doesn't correctly implement name + * sections, in core dumps, as specified by + * the "Program Linking" section of "UNIX(R) System + * V Release 4 Programmer's Guide: ANSI C and + * Programming Support Tools", because my copy + * clearly says "The first 'namesz' bytes in 'name' + * contain a *null-terminated* [emphasis mine] + * character representation of the entry's owner + * or originator", but the 2.0.36 kernel code + * doesn't include the terminating null in the + * name.... */ - 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; + if ((nh_namesz == 4 && + strncmp(&nbuf[nameoffset], "CORE", 4) == 0) || + (nh_namesz == 5 && + strcmp(&nbuf[nameoffset], "CORE") == 0)) + is_freebsd = 0; + else if ((nh_namesz == 8 && + strcmp(&nbuf[nameoffset], "FreeBSD") == 0)) + is_freebsd = 1; + else + continue; + if (nh_type == NT_PRPSINFO) { + /* + * 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 varous OSes, 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) + goto tryanother; + + /* + * Make sure we're not past + * the end of the contents; + * if we are, this obviously + * isn't the right offset. + */ + if (reloffset >= nh_descsz) + goto tryanother; + + c = nbuf[noffset]; + if (c == '\0') { + /* + * A '\0' at the + * beginning is + * obviously wrong. + * Any other '\0' + * means we're done. + */ + if (j == 0) + goto tryanother; + else + break; + } else { + /* + * A nonprintable + * character is also + * wrong. + */ +#define isquote(c) (strchr("'\"`", (c)) != NULL) + if (!isprint(c) || + isquote(c)) + goto tryanother; + } + } /* - * Make sure we're not past the - * end of the contents; if we - * are, this obviously isn't - * the right offset. + * Well, that worked. */ - if (reloffset >= nh_descsz) - goto tryanother; + printf(", from '%.16s'", + &nbuf[offset + prpsoffsets(i)]); + break; - c = nbuf[noffset]; - if (c != '\0' && !isprint(c)) - goto tryanother; + tryanother: + ; } - - /* - * Well, that worked. - */ - printf(", from '%.16s'", - &nbuf[offset + prpsoffsets(i)]); - return; - - tryanother: - ; + break; } offset += nh_descsz; offset = ((offset + 3)/4)*4; diff --git a/usr.bin/file/softmagic.c b/usr.bin/file/softmagic.c index b34a07b99f5..8410e5e2c8f 100644 --- a/usr.bin/file/softmagic.c +++ b/usr.bin/file/softmagic.c @@ -1,4 +1,4 @@ -/* $NetBSD: softmagic.c,v 1.18 2000/05/14 22:53:38 christos Exp $ */ +/* $NetBSD: softmagic.c,v 1.19 2000/09/22 16:35:00 pooka Exp $ */ /* * softmagic - interpret variable magic from MAGIC @@ -41,7 +41,7 @@ #if 0 FILE_RCSID("@(#)Id: softmagic.c,v 1.41 2000/05/14 17:58:36 christos Exp ") #else -__RCSID("$NetBSD: softmagic.c,v 1.18 2000/05/14 22:53:38 christos Exp $"); +__RCSID("$NetBSD: softmagic.c,v 1.19 2000/09/22 16:35:00 pooka Exp $"); #endif #endif /* lint */ @@ -61,8 +61,8 @@ static int mconvert __P((union VALUETYPE *, struct magic *)); /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ int softmagic(buf, nbytes) -unsigned char *buf; -int nbytes; + unsigned char *buf; + int nbytes; { if (match(buf, nbytes)) return 1; @@ -99,8 +99,8 @@ int nbytes; */ static int match(s, nbytes) -unsigned char *s; -int nbytes; + unsigned char *s; + int nbytes; { int magindex = 0; int cont_level = 0; @@ -210,8 +210,8 @@ int nbytes; static int32 mprint(p, m) -union VALUETYPE *p; -struct magic *m; + union VALUETYPE *p; + struct magic *m; { char *pp, *rt; uint32 v; @@ -284,8 +284,8 @@ struct magic *m; */ static int mconvert(p, m) -union VALUETYPE *p; -struct magic *m; + union VALUETYPE *p; + struct magic *m; { switch (m->type) { case BYTE: @@ -328,9 +328,9 @@ struct magic *m; static void mdebug(offset, str, len) -int32 offset; -char *str; -int len; + int32 offset; + char *str; + int len; { (void) fprintf(stderr, "mget @%d: ", offset); showstr(stderr, (char *) str, len); @@ -340,10 +340,10 @@ int len; static int mget(p, s, m, nbytes) -union VALUETYPE* p; -unsigned char *s; -struct magic *m; -int nbytes; + union VALUETYPE* p; + unsigned char *s; + struct magic *m; + int nbytes; { int32 offset = m->offset; @@ -415,11 +415,11 @@ int nbytes; static int mcheck(p, m) -union VALUETYPE* p; -struct magic *m; + union VALUETYPE* p; + struct magic *m; { - register uint32 l = m->value.l; - register uint32 v; + uint32 l = m->value.l; + uint32 v; int matched; if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) { @@ -455,9 +455,9 @@ struct magic *m; * but ignoring any nulls. bcmp doesn't give -/+/0 * and isn't universally available anyway. */ - register unsigned char *a = (unsigned char*)m->value.s; - register unsigned char *b = (unsigned char*)p->s; - register int len = m->vallen; + unsigned char *a = (unsigned char*)m->value.s; + unsigned char *b = (unsigned char*)p->s; + int len = m->vallen; l = 0; v = 0; if (0L == m->mask) { /* normal string: do it fast */ |
