TOOLS = chflags chmod chown compress cp dd df du install ln ls\
mkdir mkfifo mknod mtree mv pax rm rmdir rmt shar tcopy\
- touch
+ touch file
OTHERSRCS = PROJECT Makefile.preamble Makefile Makefile.postamble
PROF_LIBS = $(LIBS)
-NEXTSTEP_PB_CFLAGS = -Wall -Werror
+NEXTSTEP_PB_CFLAGS = -no-cpp-precomp
NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/$(NAME)/Build
uid = gid = -1;
if (ischown) {
-#ifdef SUPPORT_DOT
- if ((cp = strchr(*argv, '.')) != NULL) {
+ if ((cp = strchr(*argv, ':')) != NULL) {
*cp++ = '\0';
a_gid(cp);
- } else
-#endif
- if ((cp = strchr(*argv, ':')) != NULL) {
+ }
+#ifdef SUPPORT_DOT
+ else if ((cp = strchr(*argv, '.')) != NULL) {
*cp++ = '\0';
a_gid(cp);
- }
+ }
+#endif
a_uid(*argv);
} else
a_gid(*argv);
-/* $NetBSD: crc.c,v 1.8 1997/10/17 11:37:03 lukem Exp $ */
-
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 6/17/93";
-#else
-__RCSID("$NetBSD: crc.c,v 1.8 1997/10/17 11:37:03 lukem Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/usr.bin/cksum/crc.c,v 1.4 1999/12/05 20:03:21 charnier Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <unistd.h>
-#include "extern.h"
-
static const u_int32_t crctab[] = {
0x0,
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
* locations to store the crc and the number of bytes read. It returns 0 on
* success and 1 on failure. Errno is set on failure.
*/
-u_int32_t crc_total = ~0; /* The crc over a number of files. */
+u_int32_t crc_total = ~0; /* The crc over a number of files. */
int
crc(fd, cval, clen)
PROF_LIBS = $(LIBS)
-NEXTSTEP_PB_CFLAGS = -DVM_AND_BUFFER_CACHE_SYNCHRONIZED
+NEXTSTEP_PB_CFLAGS =
NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/$(NAME)/Build
MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
NEXTSTEP_BUILDDIR = "/tmp/$(NAME)/Build";
NEXTSTEP_BUILDTOOL = /bin/gnumake;
- NEXTSTEP_COMPILEROPTIONS = "-DVM_AND_BUFFER_CACHE_SYNCHRONIZED";
+ NEXTSTEP_COMPILEROPTIONS = "";
NEXTSTEP_INSTALLDIR = /bin;
NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
Created directories have the same mode as the corresponding source
directory, unmodified by the process' umask.
.It Fl f
-Foreach existing destination pathname, attempt to overwrite it. If permissions
+For each existing destination pathname, attempt to overwrite it. If permissions
do not allow copy to succeed, remove it and create a new file, without
prompting for confirmation.
(The
-/* $NetBSD: args.c,v 1.13 1998/07/28 03:47:15 mycroft Exp $ */
-
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94";
-#else
-__RCSID("$NetBSD: args.c,v 1.13 1998/07/28 03:47:15 mycroft Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/bin/dd/args.c,v 1.31 2002/02/22 20:51:00 markm Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <limits.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dd.h"
#include "extern.h"
-static int c_arg __P((const void *, const void *));
-static int c_conv __P((const void *, const void *));
-static void f_bs __P((char *));
-static void f_cbs __P((char *));
-static void f_conv __P((char *));
-static void f_count __P((char *));
-static void f_files __P((char *));
-static void f_ibs __P((char *));
-static void f_if __P((char *));
-static void f_obs __P((char *));
-static void f_of __P((char *));
-static void f_seek __P((char *));
-static void f_skip __P((char *));
-static u_long get_bsz __P((char *));
+static int c_arg(const void *, const void *);
+static int c_conv(const void *, const void *);
+static void f_bs(char *);
+static void f_cbs(char *);
+static void f_conv(char *);
+static void f_count(char *);
+static void f_files(char *);
+static void f_ibs(char *);
+static void f_if(char *);
+static void f_obs(char *);
+static void f_of(char *);
+static void f_seek(char *);
+static void f_skip(char *);
+static quad_t get_num(char *);
+static off_t get_offset(char *);
static const struct arg {
- char *name;
- void (*f) __P((char *));
+ const char *name;
+ void (*f)(char *);
u_int set, noset;
} args[] = {
{ "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC },
{ "files", f_files, C_FILES, C_FILES },
{ "ibs", f_ibs, C_IBS, C_BS|C_IBS },
{ "if", f_if, C_IF, C_IF },
+ { "iseek", f_skip, C_SKIP, C_SKIP },
{ "obs", f_obs, C_OBS, C_BS|C_OBS },
{ "of", f_of, C_OF, C_OF },
+ { "oseek", f_seek, C_SEEK, C_SEEK },
{ "seek", f_seek, C_SEEK, C_SEEK },
{ "skip", f_skip, C_SKIP, C_SKIP },
};
* args -- parse JCL syntax of dd.
*/
void
-jcl(argv)
- char **argv;
+jcl(char **argv)
{
struct arg *ap, tmp;
char *arg;
in.dbsz = out.dbsz = 512;
while ((oper = *++argv) != NULL) {
+ if ((oper = strdup(oper)) == NULL)
+ errx(1, "unable to allocate space for the argument \"%s\"", *argv);
if ((arg = strchr(oper, '=')) == NULL)
errx(1, "unknown operand %s", oper);
*arg++ = '\0';
* just wanted to set both the input and output block sizes
* and didn't want the bs semantics, so we don't warn.
*/
- if (ddflags & (C_BLOCK|C_LCASE|C_SWAB|C_UCASE|C_UNBLOCK))
+ if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE |
+ C_UNBLOCK))
ddflags &= ~C_BS;
/* Bs supersedes ibs and obs. */
- if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))
+ if (ddflags & C_BS && ddflags & (C_IBS | C_OBS))
warnx("bs supersedes ibs and obs");
}
* Ascii/ebcdic and cbs implies block/unblock.
* Block/unblock requires cbs and vice-versa.
*/
- if (ddflags & (C_BLOCK|C_UNBLOCK)) {
+ if (ddflags & (C_BLOCK | C_UNBLOCK)) {
if (!(ddflags & C_CBS))
errx(1, "record operations require cbs");
if (cbsz == 0)
errx(1, "cbs cannot be zero");
cfunc = ddflags & C_BLOCK ? block : unblock;
} else if (ddflags & C_CBS) {
- if (ddflags & (C_ASCII|C_EBCDIC)) {
+ if (ddflags & (C_ASCII | C_EBCDIC)) {
if (ddflags & C_ASCII) {
ddflags |= C_UNBLOCK;
cfunc = unblock;
}
} else
errx(1, "cbs meaningless if not doing record operations");
- if (cbsz == 0)
- errx(1, "cbs cannot be zero");
} else
cfunc = def;
- if (in.dbsz == 0 || out.dbsz == 0)
- errx(1, "buffer sizes cannot be zero");
-
/*
- * Check to make sure that the buffers are not too large.
- */
- if (in.dbsz > INT_MAX || out.dbsz > INT_MAX)
- errx(1, "buffer sizes cannot be greater than %d", INT_MAX);
-
- /* Read, write and seek calls take off_t as arguments.
- *
- * The following check is not done because an off_t is a quad
- * for current NetBSD implementations.
- *
- * if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
- * errx(1, "seek offsets cannot be larger than %d", INT_MAX);
+ * Bail out if the calculation of a file offset would overflow.
*/
+ if (in.offset > QUAD_MAX / in.dbsz || out.offset > QUAD_MAX / out.dbsz)
+ errx(1, "seek offsets cannot be larger than %qd", QUAD_MAX);
}
static int
-c_arg(a, b)
- const void *a, *b;
+c_arg(const void *a, const void *b)
{
return (strcmp(((const struct arg *)a)->name,
}
static void
-f_bs(arg)
- char *arg;
+f_bs(char *arg)
{
+ quad_t res;
- in.dbsz = out.dbsz = (int)get_bsz(arg);
+ res = get_num(arg);
+ if (res < 1 || res > SSIZE_MAX)
+ errx(1, "bs must be between 1 and %d", SSIZE_MAX);
+ in.dbsz = out.dbsz = (size_t)res;
}
static void
-f_cbs(arg)
- char *arg;
+f_cbs(char *arg)
{
+ quad_t res;
- cbsz = (int)get_bsz(arg);
+ res = get_num(arg);
+ if (res < 1 || res > SSIZE_MAX)
+ errx(1, "cbs must be between 1 and %d", SSIZE_MAX);
+ cbsz = (size_t)res;
}
static void
-f_count(arg)
- char *arg;
+f_count(char *arg)
{
- cpy_cnt = (u_int)get_bsz(arg);
- if (!cpy_cnt)
- terminate(0);
+ cpy_cnt = get_num(arg);
+ if (cpy_cnt < 0)
+ errx(1, "count cannot be negative");
+ if (cpy_cnt == 0)
+ cpy_cnt = -1;
}
static void
-f_files(arg)
- char *arg;
+f_files(char *arg)
{
- files_cnt = (int)get_bsz(arg);
+ files_cnt = get_num(arg);
+ if (files_cnt < 1)
+ errx(1, "files must be between 1 and %qd", QUAD_MAX);
}
static void
-f_ibs(arg)
- char *arg;
+f_ibs(char *arg)
{
+ quad_t res;
- if (!(ddflags & C_BS))
- in.dbsz = (int)get_bsz(arg);
+ if (!(ddflags & C_BS)) {
+ res = get_num(arg);
+ if (res < 1 || res > SSIZE_MAX)
+ errx(1, "ibs must be between 1 and %d", SSIZE_MAX);
+ in.dbsz = (size_t)res;
+ }
}
static void
-f_if(arg)
- char *arg;
+f_if(char *arg)
{
in.name = arg;
}
static void
-f_obs(arg)
- char *arg;
+f_obs(char *arg)
{
+ quad_t res;
- if (!(ddflags & C_BS))
- out.dbsz = (int)get_bsz(arg);
+ if (!(ddflags & C_BS)) {
+ res = get_num(arg);
+ if (res < 1 || res > SSIZE_MAX)
+ errx(1, "obs must be between 1 and %d", SSIZE_MAX);
+ out.dbsz = (size_t)res;
+ }
}
static void
-f_of(arg)
- char *arg;
+f_of(char *arg)
{
out.name = arg;
}
static void
-f_seek(arg)
- char *arg;
+f_seek(char *arg)
{
- out.offset = (u_int)get_bsz(arg);
+ out.offset = get_offset(arg);
}
static void
-f_skip(arg)
- char *arg;
+f_skip(char *arg)
{
- in.offset = (u_int)get_bsz(arg);
-}
-
-#ifdef NO_CONV
-/* Build a small version (i.e. for a ramdisk root) */
-static void
-f_conv(arg)
- char *arg;
-{
- errx(1, "conv option disabled");
+ in.offset = get_offset(arg);
}
-#else /* NO_CONV */
static const struct conv {
- char *name;
+ const char *name;
u_int set, noset;
const u_char *ctab;
} clist[] = {
{ "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V },
{ "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V },
{ "osync", C_OSYNC, C_BS, NULL },
+ { "sparse", C_SPARSE, 0, NULL },
{ "swab", C_SWAB, 0, NULL },
{ "sync", C_SYNC, 0, NULL },
{ "ucase", C_UCASE, C_LCASE, NULL },
};
static void
-f_conv(arg)
- char *arg;
+f_conv(char *arg)
{
struct conv *cp, tmp;
while (arg != NULL) {
tmp.name = strsep(&arg, ",");
- if (!(cp = (struct conv *)bsearch(&tmp, clist,
- sizeof(clist)/sizeof(struct conv), sizeof(struct conv),
- c_conv)))
+ cp = bsearch(&tmp, clist, sizeof(clist) / sizeof(struct conv),
+ sizeof(struct conv), c_conv);
+ if (cp == NULL)
errx(1, "unknown conversion %s", tmp.name);
if (ddflags & cp->noset)
errx(1, "%s: illegal conversion combination", tmp.name);
}
static int
-c_conv(a, b)
- const void *a, *b;
+c_conv(const void *a, const void *b)
{
return (strcmp(((const struct conv *)a)->name,
((const struct conv *)b)->name));
}
-#endif /* NO_CONV */
-
/*
- * Convert an expression of the following forms to an unsigned long.
+ * Convert an expression of the following forms to a quad_t.
* 1) A positive decimal number.
* 2) A positive decimal number followed by a b (mult by 512).
- * 3) A positive decimal number followed by a k (mult by 1024).
- * 4) A positive decimal number followed by a m (mult by 512).
- * 5) A positive decimal number followed by a w (mult by sizeof int)
- * 6) Two or more positive decimal numbers (with/without k,b or w).
- * seperated by x (also * for backwards compatibility), specifying
+ * 3) A positive decimal number followed by a k (mult by 1 << 10).
+ * 4) A positive decimal number followed by a m (mult by 1 << 20).
+ * 5) A positive decimal number followed by a g (mult by 1 << 30).
+ * 5) A positive decimal number followed by a w (mult by sizeof int).
+ * 6) Two or more positive decimal numbers (with/without [bkmgw])
+ * separated by x (also * for backwards compatibility), specifying
* the product of the indicated values.
*/
-static u_long
-get_bsz(val)
- char *val;
+static quad_t
+get_num(char *val)
{
- u_long num, t;
+ quad_t num, t;
char *expr;
- num = strtoul(val, &expr, 0);
- if (num == ULONG_MAX) /* Overflow. */
+ errno = 0;
+ num = strtoq(val, &expr, 0);
+ if (errno != 0) /* Overflow or underflow. */
err(1, "%s", oper);
- if (expr == val) /* No digits. */
+
+ if (expr == val) /* No valid digits. */
errx(1, "%s: illegal numeric value", oper);
switch (*expr) {
break;
case 'k':
t = num;
- num *= 1024;
+ num *= 1 << 10;
if (t > num)
goto erange;
++expr;
break;
case 'm':
t = num;
- num *= 1048576;
+ num *= 1 << 20;
+ if (t > num)
+ goto erange;
+ ++expr;
+ break;
+ case 'g':
+ t = num;
+ num *= 1 << 30;
if (t > num)
goto erange;
++expr;
}
switch (*expr) {
- case '\0':
- break;
- case '*': /* Backward compatible. */
- case 'x':
- t = num;
- num *= get_bsz(expr + 1);
- if (t > num)
-erange: errx(1, "%s: %s", oper, strerror(ERANGE));
- break;
- default:
- errx(1, "%s: illegal numeric value", oper);
+ case '\0':
+ break;
+ case '*': /* Backward compatible. */
+ case 'x':
+ t = num;
+ num *= get_num(expr + 1);
+ if (t <= num)
+ break;
+erange:
+ errx(1, "%s: %s", oper, strerror(ERANGE));
+ default:
+ errx(1, "%s: illegal numeric value", oper);
}
return (num);
}
+
+static off_t
+get_offset(char *val)
+{
+ quad_t num;
+
+ num = get_num(val);
+ if (num > QUAD_MAX) /* XXX can't happen && quad_t != off_t */
+ errx(1, "%s: illegal offset", oper); /* Too big. */
+ return ((off_t)num);
+}
-/* $NetBSD: conv.c,v 1.8 1998/07/28 05:15:46 mycroft Exp $ */
-
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)conv.c 8.3 (Berkeley) 4/2/94";
-#else
-__RCSID("$NetBSD: conv.c,v 1.8 1998/07/28 05:15:46 mycroft Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/bin/dd/conv.c,v 1.16 2002/02/02 06:24:12 imp Exp $";
#endif /* not lint */
#include <sys/param.h>
* Worst case buffer calculation is (ibs + obs - 1).
*/
void
-def()
+def(void)
{
- int cnt;
u_char *inp;
const u_char *t;
+ size_t cnt;
if ((t = ctab) != NULL)
for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)
}
void
-def_close()
+def_close(void)
{
/* Just update the count, everything is already in the buffer. */
if (in.dbcnt)
out.dbcnt = in.dbcnt;
}
-#ifdef NO_CONV
-/* Build a smaller version (i.e. for a miniroot) */
-/* These can not be called, but just in case... */
-static char no_block[] = "unblock and -DNO_CONV?";
-void block() { errx(1, no_block + 2); }
-void block_close() { errx(1, no_block + 2); }
-void unblock() { errx(1, no_block); }
-void unblock_close() { errx(1, no_block); }
-#else /* NO_CONV */
-
/*
* Copy variable length newline terminated records with a max size cbsz
* bytes to output. Records less than cbs are padded with spaces.
* max out buffer: obs + cbsz
*/
void
-block()
+block(void)
{
- static int intrunc;
- int ch = 0; /* pacify gcc */
- int cnt, maxlen;
u_char *inp, *outp;
const u_char *t;
+ size_t cnt, maxlen;
+ static int intrunc;
+ int ch;
/*
* Record truncation can cross block boundaries. If currently in a
* left empty.
*/
if (intrunc) {
- for (inp = in.db, cnt = in.dbrcnt;
- cnt && *inp++ != '\n'; --cnt);
+ for (inp = in.db, cnt = in.dbrcnt; cnt && *inp++ != '\n'; --cnt)
+ ;
if (!cnt) {
in.dbcnt = 0;
in.dbp = in.db;
* Copy records (max cbsz size chunks) into the output buffer. The
* translation is done as we copy into the output buffer.
*/
+ ch = 0;
for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
maxlen = MIN(cbsz, in.dbcnt);
if ((t = ctab) != NULL)
- for (cnt = 0;
- cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
+ for (cnt = 0; cnt < maxlen && (ch = *inp++) != '\n';
+ ++cnt)
*outp++ = t[ch];
else
- for (cnt = 0;
- cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
+ for (cnt = 0; cnt < maxlen && (ch = *inp++) != '\n';
+ ++cnt)
*outp++ = ch;
/*
* Check for short record without a newline. Reassemble the
}
void
-block_close()
+block_close(void)
{
/*
* Copy any remaining data into the output buffer and pad to a record.
if (in.dbcnt) {
++st.trunc;
(void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);
- (void)memset(out.dbp + in.dbcnt,
- ctab ? ctab[' '] : ' ', cbsz - in.dbcnt);
+ (void)memset(out.dbp + in.dbcnt, ctab ? ctab[' '] : ' ',
+ cbsz - in.dbcnt);
out.dbcnt += cbsz;
}
}
* max out buffer: obs + cbsz
*/
void
-unblock()
+unblock(void)
{
- int cnt;
u_char *inp;
const u_char *t;
+ size_t cnt;
/* Translation and case conversion. */
if ((t = ctab) != NULL)
* spaces.
*/
for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
- for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t);
+ for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t)
+ ;
if (t >= inp) {
cnt = t - inp + 1;
(void)memmove(out.dbp, inp, cnt);
out.dbp += cnt;
out.dbcnt += cnt;
}
- ++out.dbcnt;
*out.dbp++ = '\n';
- if (out.dbcnt >= out.dbsz)
+ if (++out.dbcnt >= out.dbsz)
dd_out(0);
}
if (in.dbcnt)
}
void
-unblock_close()
+unblock_close(void)
{
- int cnt;
u_char *t;
+ size_t cnt;
if (in.dbcnt) {
warnx("%s: short input record", in.name);
- for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t);
+ for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t)
+ ;
if (t >= in.db) {
cnt = t - in.db + 1;
(void)memmove(out.dbp, in.db, cnt);
*out.dbp++ = '\n';
}
}
-
-#endif /* NO_CONV */
-/* $NetBSD: conv_tab.c,v 1.8 1997/07/20 21:58:38 christos Exp $ */
-
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)conv_tab.c 8.1 (Berkeley) 5/31/93";
-#else
-__RCSID("$NetBSD: conv_tab.c,v 1.8 1997/07/20 21:58:38 christos Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/bin/dd/conv_tab.c,v 1.10 1999/09/12 16:51:53 green Exp $";
#endif /* not lint */
#include <sys/types.h>
-.\" $NetBSD: dd.1,v 1.7 1998/02/06 05:39:31 perry Exp $
-.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
+.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
+.\" $FreeBSD: src/bin/dd/dd.1,v 1.19 2002/03/31 20:49:37 keramida Exp $
.\"
.Dd January 13, 1994
.Dt DD 1
.Nd convert and copy a file
.Sh SYNOPSIS
.Nm
-.Op operands ...
+.Op Ar operands ...
.Sh DESCRIPTION
The
.Nm
and truncated input records to the standard error output.
.Pp
The following operands are available:
+.\" XXX
.Bl -tag -width of=file
-.It Cm bs= Ns Ar n
-Set both input and output block size, superseding the
+.It Cm bs Ns = Ns Ar n
+Set both input and output block size to
+.Ar n
+bytes, superseding the
.Cm ibs
and
.Cm obs
.Cm sync
are specified, then each input block is copied to the output as a
single block without any aggregation of short blocks.
-.It Cm cbs= Ns Ar n
+.It Cm cbs Ns = Ns Ar n
Set the conversion record size to
-.Va n
+.Ar n
bytes.
The conversion record size is required by the record oriented conversion
values.
-.It Cm count= Ns Ar n
+.It Cm count Ns = Ns Ar n
Copy only
-.Va n
+.Ar n
input blocks.
-.It Cm files= Ns Ar n
+.It Cm files Ns = Ns Ar n
Copy
-.Va n
+.Ar n
input files before terminating.
This operand is only applicable when the input device is a tape.
-.It Cm ibs= Ns Ar n
+.It Cm ibs Ns = Ns Ar n
Set the input block size to
-.Va n
+.Ar n
bytes instead of the default 512.
-.It Cm if= Ns Ar file
+.It Cm if Ns = Ns Ar file
Read input from
.Ar file
instead of the standard input.
-.It Cm obs= Ns Ar n
+.It Cm iseek Ns = Ns Ar n
+Seek on the input file
+.Ar n
+blocks.
+This is synonymous with
+.Cm skip Ns = Ns Ar n .
+.It Cm obs Ns = Ns Ar n
Set the output block size to
-.Va n
+.Ar n
bytes instead of the default 512.
-.It Cm of= Ns Ar file
+.It Cm of Ns = Ns Ar file
Write output to
.Ar file
instead of the standard output.
Any regular output file is truncated unless the
.Cm notrunc
conversion value is specified.
-If an initial portion of the output file is skipped (see the
-.Cm seek
-operand)
+If an initial portion of the output file is seeked past (see the
+.Cm oseek
+operand),
the output file is truncated at that point.
-.It Cm seek= Ns Ar n
+.It Cm oseek Ns = Ns Ar n
+Seek on the output file
+.Ar n
+blocks.
+This is synonymous with
+.Cm seek Ns = Ns Ar n .
+.It Cm seek Ns = Ns Ar n
Seek
-.Va n
+.Ar n
blocks from the beginning of the output before copying.
-On non-tape devices, a
+On non-tape devices, an
.Xr lseek 2
operation is used.
Otherwise, existing blocks are read and the data discarded.
function calls.
If the seek operation is past the end of file, space from the current
end of file to the specified offset is filled with blocks of
-.Tn NUL
+.Dv NUL
bytes.
-.It Cm skip= Ns Ar n
+.It Cm skip Ns = Ns Ar n
Skip
-.Va n
+.Ar n
blocks from the beginning of the input before copying.
-On input which supports seeks, a
+On input which supports seeks, an
.Xr lseek 2
operation is used.
Otherwise, input data is read and discarded.
For pipes, the correct number of bytes is read.
For all other devices, the correct number of blocks is read without
distinguishing between a partial or complete block being read.
-.It Xo
-.Cm conv=
-.Ns Cm value Ns Op \&, Cm value \&...
-.Xc
+.It Cm conv Ns = Ns Ar value Ns Op , Ns Ar value ...
Where
.Cm value
is one of the symbols from the following list.
-.Bl -tag -width unblock
+.Bl -tag -width ".Cm unblock"
.It Cm ascii , oldascii
The same as the
.Cm unblock
.Tn ASCII .
The value
.Cm ascii
-specifies the recommended one which is compatible with
+specifies the recommended one which is compatible with
.At V .
The value
.Cm oldascii
specifies the one used in historic
-.Tn AT&T
-and pre-
-.Bx 4.3 Reno
+.At
+and
+.No pre- Ns Bx 4.3 reno
systems.
.It Cm block
Treats the input as a sequence of newline or end-of-file terminated variable
and
.Cm oldibm
are maps used in historic
-.Tn AT&T
-and pre
-.Bx 4.3 Reno
+.At
+and
+.No pre- Ns Bx 4.3 reno
systems.
.It Cm lcase
Transform uppercase characters into lowercase characters.
.Cm sync
conversion is also specified, any missing input data will be replaced
with
-.Tn NUL
+.Dv NUL
bytes (or with spaces if a block oriented conversion value was
specified) and processed as a normal input buffer.
If the
Do not truncate the output file.
This will preserve any blocks in the output file not explicitly written
by
-.Nm "" .
+.Nm .
The
.Cm notrunc
value is not supported for tapes.
to be the same size as preceding blocks for use on devices that require
regularly sized blocks to be written.
This option is incompatible with use of the
-.Cm bs= Ns Ar n
+.Cm bs Ns = Ns Ar n
block size specification.
+.It Cm sparse
+If one or more output blocks would consist solely of
+.Dv NUL
+bytes, try to seek the output file by the required space instead of
+filling them with
+.Dv NUL Ns s ,
+resulting in a sparse file.
.It Cm swab
Swap every pair of input bytes.
If an input buffer has an odd number of bytes, the last byte will be
Pad every input block to the input buffer size.
Spaces are used for pad bytes if a block oriented conversion value is
specified, otherwise
-.Tn NUL
+.Dv NUL
bytes are used.
.It Cm ucase
Transform lowercase characters into uppercase characters.
.El
.El
.Pp
-Where sizes are specified, a decimal number of bytes is expected.
-If the number ends with a ``b'', ``k'', ``m'' or ``w'', the number
-is multiplied by 512, 1024 (1K), 1048576 (1M) or the number of bytes
-in an integer, respectively.
-Two or more numbers may be separated by an ``x'' to indicate a product.
+Where sizes are specified, a decimal, octal, or hexadecimal number of
+bytes is expected.
+If the number ends with a
+.Dq Li b ,
+.Dq Li k ,
+.Dq Li m ,
+.Dq Li g ,
+or
+.Dq Li w ,
+the
+number is multiplied by 512, 1024 (1K), 1048576 (1M), 1073741824 (1G)
+or the number of bytes in an integer, respectively.
+Two or more numbers may be separated by an
+.Dq Li x
+to indicate a product.
.Pp
When finished,
.Nm
.Nm
receives a
.Dv SIGINFO
-(see the ``status'' argument for
+(see the
+.Cm status
+argument for
.Xr stty 1 )
signal, the current input and output block counts will
be written to the standard error output
in the same format as the standard completion message and
.Nm
will exit.
-.Pp
-The
-.Nm
-utility exits 0 on success and >0 if an error occurred.
+.Sh DIAGNOSTICS
+.Ex -std
.Sh SEE ALSO
.Xr cp 1 ,
.Xr mt 1 ,
and
.Cm oldibm
values are extensions to the
-.Tn POSIX
+\*[Px]
standard.
-/* $NetBSD: dd.c,v 1.12 1998/08/19 01:32:44 thorpej Exp $ */
-
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\n\
- The Regents of the University of California. All rights reserved.\n");
+static char const copyright[] =
+"@(#) Copyright (c) 1991, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94";
-#else
-__RCSID("$NetBSD: dd.c,v 1.12 1998/08/19 01:32:44 thorpej Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/bin/dd/dd.c,v 1.36 2002/03/07 14:00:33 markm Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/conf.h>
+#include <sys/filio.h>
+#include <sys/time.h>
+
+#ifdef __APPLE__
#include <sys/ioctl.h>
-#include <sys/mtio.h>
+#else
+#include <sys/disklabel.h>
+#endif
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
-#include <signal.h>
+#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
#include <unistd.h>
#include "dd.h"
#include "extern.h"
-static void dd_close __P((void));
-static void dd_in __P((void));
-static void getfdtype __P((IO *));
-static void setup __P((void));
-
-int main __P((int, char *[]));
+static void dd_close(void);
+static void dd_in(void);
+static void getfdtype(IO *);
+static void setup(void);
IO in, out; /* input/output state */
STAT st; /* statistics */
-void (*cfunc) __P((void)); /* conversion function */
-u_long cpy_cnt; /* # of blocks to copy */
+void (*cfunc)(void); /* conversion function */
+quad_t cpy_cnt; /* # of blocks to copy */
+off_t pending = 0; /* pending seek if sparse */
u_int ddflags; /* conversion options */
-u_int cbsz; /* conversion block size */
-u_int files_cnt = 1; /* # of files to copy */
-const u_char *ctab; /* conversion table */
+size_t cbsz; /* conversion block size */
+quad_t files_cnt = 1; /* # of files to copy */
+const u_char *ctab; /* conversion table */
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(int argc, char *argv[])
{
+ (void)setlocale(LC_CTYPE, "");
jcl(argv);
setup();
(void)signal(SIGINFO, summaryx);
(void)signal(SIGINT, terminate);
- (void)atexit(summary);
+ atexit(summary);
while (files_cnt--)
dd_in();
dd_close();
exit(0);
- /* NOTREACHED */
}
static void
-setup()
+setup(void)
{
u_int cnt;
+ struct timeval tv;
if (in.name == NULL) {
in.name = "stdin";
in.fd = STDIN_FILENO;
} else {
in.fd = open(in.name, O_RDONLY, 0);
- if (in.fd < 0)
+ if (in.fd == -1)
err(1, "%s", in.name);
}
* Without read we may have a problem if output also does
* not support seeks.
*/
- if (out.fd < 0) {
+ if (out.fd == -1) {
out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE);
out.flags |= NOREAD;
}
- if (out.fd < 0)
+ if (out.fd == -1)
err(1, "%s", out.name);
}
* Allocate space for the input and output buffers. If not doing
* record oriented I/O, only need a single buffer.
*/
- if (!(ddflags & (C_BLOCK|C_UNBLOCK))) {
+ if (!(ddflags & (C_BLOCK | C_UNBLOCK))) {
if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL)
- err(1, "%s", "");
+ err(1, "input buffer");
out.db = in.db;
- } else if ((in.db =
- malloc((u_int)(MAX(in.dbsz, cbsz) + cbsz))) == NULL ||
- (out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL)
- err(1, "%s", "");
+ } else if ((in.db = malloc(MAX(in.dbsz, cbsz) + cbsz)) == NULL ||
+ (out.db = malloc(out.dbsz + cbsz)) == NULL)
+ err(1, "output buffer");
in.dbp = in.db;
out.dbp = out.db;
pos_out();
/*
- * Truncate the output file; ignore errors because it fails on some
- * kinds of output files, tapes, for example.
+ * Truncate the output file. If it fails on a type of output file
+ * that it should _not_ fail on, error out.
*/
- if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK))
- (void)ftruncate(out.fd, (off_t)out.offset * out.dbsz);
+ if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK) &&
+ out.flags & ISTRUNC)
+ if (ftruncate(out.fd, out.offset * out.dbsz) == -1)
+ err(1, "truncating %s", out.name);
/*
* If converting case at the same time as another conversion, build a
* table that does both at once. If just converting case, use the
* built-in tables.
*/
- if (ddflags & (C_LCASE|C_UCASE)) {
-#ifdef NO_CONV
- /* Should not get here, but just in case... */
- errx(1, "case conv and -DNO_CONV");
-#else /* NO_CONV */
- if (ddflags & C_ASCII || ddflags & C_EBCDIC) {
+ if (ddflags & (C_LCASE | C_UCASE)) {
+ if (ddflags & (C_ASCII | C_EBCDIC)) {
if (ddflags & C_LCASE) {
- for (cnt = 0; cnt < 0377; ++cnt)
+ for (cnt = 0; cnt <= 0377; ++cnt)
casetab[cnt] = tolower(ctab[cnt]);
} else {
- for (cnt = 0; cnt < 0377; ++cnt)
+ for (cnt = 0; cnt <= 0377; ++cnt)
casetab[cnt] = toupper(ctab[cnt]);
}
} else {
if (ddflags & C_LCASE) {
- for (cnt = 0; cnt < 0377; ++cnt)
- casetab[cnt] = tolower(cnt);
+ for (cnt = 0; cnt <= 0377; ++cnt)
+ casetab[cnt] = tolower((int)cnt);
} else {
- for (cnt = 0; cnt < 0377; ++cnt)
- casetab[cnt] = toupper(cnt);
+ for (cnt = 0; cnt <= 0377; ++cnt)
+ casetab[cnt] = toupper((int)cnt);
}
}
-
ctab = casetab;
-#endif /* NO_CONV */
}
- (void)time(&st.start); /* Statistics timestamp. */
+ (void)gettimeofday(&tv, (struct timezone *)NULL);
+ st.start = tv.tv_sec + tv.tv_usec * 1e-6;
}
static void
-getfdtype(io)
- IO *io;
+getfdtype(IO *io)
{
- struct mtget mt;
struct stat sb;
+ int type;
- if (fstat(io->fd, &sb))
+ if (fstat(io->fd, &sb) == -1)
err(1, "%s", io->name);
- if (S_ISCHR(sb.st_mode))
- io->flags |= ioctl(io->fd, MTIOCGET, &mt) ? ISCHR : ISTAPE;
- else if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
- io->flags |= ISPIPE; /* XXX fixed in 4.4BSD */
+ if (S_ISREG(sb.st_mode))
+ io->flags |= ISTRUNC;
+ if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) {
+ if (ioctl(io->fd, FIODTYPE, &type) == -1) {
+ err(1, "%s", io->name);
+ } else {
+ if (type & D_TAPE)
+ io->flags |= ISTAPE;
+#ifdef __APPLE__
+ else if (type & D_DISK) {
+#else
+ else if (type & (D_DISK | D_MEM)) {
+ if (type & D_DISK) {
+ const int one = 1;
+
+ (void)ioctl(io->fd, DIOCWLABEL, &one);
+ }
+#endif
+ io->flags |= ISSEEK;
+ }
+ if (S_ISCHR(sb.st_mode) && (type & D_TAPE) == 0)
+ io->flags |= ISCHR;
+ }
+ return;
+ }
+ errno = 0;
+ if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
+ io->flags |= ISPIPE;
+ else
+ io->flags |= ISSEEK;
}
static void
-dd_in()
+dd_in(void)
{
- int flags, n;
+ ssize_t n;
- for (flags = ddflags;;) {
- if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
+ for (;;) {
+ switch (cpy_cnt) {
+ case -1: /* count=0 was specified */
return;
+ case 0:
+ break;
+ default:
+ if (st.in_full + st.in_part >= (u_quad_t)cpy_cnt)
+ return;
+ break;
+ }
/*
- * Clear the buffer first if doing "sync" on input.
- * If doing block operations use spaces. This will
- * affect not only the C_NOERROR case, but also the
- * last partial input block which should be padded
- * with zero and not garbage.
+ * Zero the buffer first if sync; if doing block operations,
+ * use spaces.
*/
- if (flags & C_SYNC) {
- if (flags & (C_BLOCK|C_UNBLOCK))
- (void)memset(in.dbp, ' ', in.dbsz);
+ if (ddflags & C_SYNC) {
+ if (ddflags & (C_BLOCK | C_UNBLOCK))
+ memset(in.dbp, ' ', in.dbsz);
else
- (void)memset(in.dbp, 0, in.dbsz);
+ memset(in.dbp, 0, in.dbsz);
}
n = read(in.fd, in.dbp, in.dbsz);
}
/* Read error. */
- if (n < 0) {
+ if (n == -1) {
/*
* If noerror not specified, die. POSIX requires that
* the warning message be followed by an I/O display.
*/
- if (!(flags & C_NOERROR))
+ if (!(ddflags & C_NOERROR))
err(1, "%s", in.name);
warn("%s", in.name);
summary();
/*
- * If it's not a tape drive or a pipe, seek past the
+ * If it's a seekable file descriptor, seek past the
* error. If your OS doesn't do the right thing for
* raw disks this section should be modified to re-read
* in sector size chunks.
*/
- if (!(in.flags & (ISPIPE|ISTAPE)) &&
+ if (in.flags & ISSEEK &&
lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
warn("%s", in.name);
++st.in_full;
/* Handle full input blocks. */
- } else if (n == in.dbsz) {
+ } else if ((size_t)n == in.dbsz) {
in.dbcnt += in.dbrcnt = n;
++st.in_full;
}
if (ddflags & C_SWAB) {
- if ((n = in.dbcnt) & 1) {
+ if ((n = in.dbrcnt) & 1) {
++st.swab;
--n;
}
- swab(in.dbp, in.dbp, n);
+ swab(in.dbp, in.dbp, (size_t)n);
}
in.dbp += in.dbrcnt;
}
/*
- * Cleanup any remaining I/O and flush output. If necesssary, output file
+ * Clean up any remaining I/O and flush output. If necessary, the output file
* is truncated.
*/
static void
-dd_close()
+dd_close(void)
{
if (cfunc == def)
def_close();
block_close();
else if (cfunc == unblock)
unblock_close();
- if (ddflags & C_OSYNC && out.dbcnt < out.dbsz) {
- (void)memset(out.dbp, 0, out.dbsz - out.dbcnt);
+ if (ddflags & C_OSYNC && out.dbcnt && out.dbcnt < out.dbsz) {
+ if (ddflags & (C_BLOCK | C_UNBLOCK))
+ memset(out.dbp, ' ', out.dbsz - out.dbcnt);
+ else
+ memset(out.dbp, 0, out.dbsz - out.dbcnt);
out.dbcnt = out.dbsz;
}
- if (out.dbcnt)
+ if (out.dbcnt || pending)
dd_out(1);
}
void
-dd_out(force)
- int force;
+dd_out(int force)
{
- static int warned;
- int cnt, n, nw;
u_char *outp;
+ size_t cnt, i, n;
+ ssize_t nw;
+ static int warned;
+ int sparse;
/*
* Write one or more blocks out. The common case is writing a full
outp = out.db;
for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {
for (cnt = n;; cnt -= nw) {
- nw = write(out.fd, outp, cnt);
+ sparse = 0;
+ if (ddflags & C_SPARSE) {
+ sparse = 1; /* Is buffer sparse? */
+ for (i = 0; i < cnt; i++)
+ if (outp[i] != 0) {
+ sparse = 0;
+ break;
+ }
+ }
+ if (sparse && !force) {
+ pending += cnt;
+ nw = cnt;
+ } else {
+ if (pending != 0) {
+ if (force)
+ pending--;
+ if (lseek(out.fd, pending, SEEK_CUR) ==
+ -1)
+ err(2, "%s: seek error creating sparse file",
+ out.name);
+ if (force)
+ write(out.fd, outp, 1);
+ pending = 0;
+ }
+ if (cnt)
+ nw = write(out.fd, outp, cnt);
+ else
+ return;
+ }
+
if (nw <= 0) {
if (nw == 0)
errx(1, "%s: end of device", out.name);
}
outp += nw;
st.bytes += nw;
- if (nw == n) {
+ if ((size_t)nw == n) {
if (n != out.dbsz)
++st.out_part;
else
break;
}
++st.out_part;
- if (nw == cnt)
+ if ((size_t)nw == cnt)
break;
+ if (out.flags & ISTAPE)
+ errx(1, "%s: short write on tape device",
+ out.name);
if (out.flags & ISCHR && !warned) {
warned = 1;
warnx("%s: short write on character device",
out.name);
}
- if (out.flags & ISTAPE)
- errx(1, "%s: short write on tape device", out.name);
}
if ((out.dbcnt -= n) < out.dbsz)
break;
-/* $NetBSD: dd.h,v 1.5 1998/02/04 06:42:31 enami Exp $ */
-
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*
* @(#)dd.h 8.3 (Berkeley) 4/2/94
+ * $FreeBSD: src/bin/dd/dd.h,v 1.17 2002/02/22 20:51:00 markm Exp $
*/
/* Input/output stream state. */
typedef struct {
- u_char *db; /* buffer address */
- u_char *dbp; /* current buffer I/O address */
- u_long dbcnt; /* current buffer byte count */
- int dbrcnt; /* last read byte count */
- u_long dbsz; /* buffer size */
+ u_char *db; /* buffer address */
+ u_char *dbp; /* current buffer I/O address */
+ /* XXX ssize_t? */
+ size_t dbcnt; /* current buffer byte count */
+ size_t dbrcnt; /* last read byte count */
+ size_t dbsz; /* buffer size */
#define ISCHR 0x01 /* character device (warn on short) */
-#define ISPIPE 0x02 /* pipe (not truncatable) */
-#define ISTAPE 0x04 /* tape (not seekable) */
-#define NOREAD 0x08 /* not readable */
- u_int flags;
+#define ISPIPE 0x02 /* pipe-like (see position.c) */
+#define ISTAPE 0x04 /* tape */
+#define ISSEEK 0x08 /* valid to seek on */
+#define NOREAD 0x10 /* not readable */
+#define ISTRUNC 0x20 /* valid to ftruncate() */
+ u_int flags;
- char *name; /* name */
- int fd; /* file descriptor */
- u_long offset; /* # of blocks to skip */
+ const char *name; /* name */
+ int fd; /* file descriptor */
+ off_t offset; /* # of blocks to skip */
- u_long f_stats; /* # of full blocks processed */
- u_long p_stats; /* # of partial blocks processed */
- u_long s_stats; /* # of odd swab blocks */
- u_long t_stats; /* # of truncations */
} IO;
typedef struct {
- u_long in_full; /* # of full input blocks */
- u_long in_part; /* # of partial input blocks */
- u_long out_full; /* # of full output blocks */
- u_long out_part; /* # of partial output blocks */
- u_long trunc; /* # of truncated records */
- u_long swab; /* # of odd-length swab blocks */
- u_quad_t bytes; /* # of bytes written */
- time_t start; /* start time of dd */
+ u_quad_t in_full; /* # of full input blocks */
+ u_quad_t in_part; /* # of partial input blocks */
+ u_quad_t out_full; /* # of full output blocks */
+ u_quad_t out_part; /* # of partial output blocks */
+ u_quad_t trunc; /* # of truncated records */
+ u_quad_t swab; /* # of odd-length swab blocks */
+ u_quad_t bytes; /* # of bytes written */
+ double start; /* start time of dd */
} STAT;
/* Flags (in ddflags). */
#define C_UCASE 0x40000
#define C_UNBLOCK 0x80000
#define C_OSYNC 0x100000
+#define C_SPARSE 0x200000
-/* $NetBSD: extern.h,v 1.8 1997/07/20 21:58:40 christos Exp $ */
-
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*
* @(#)extern.h 8.3 (Berkeley) 4/2/94
+ * $FreeBSD: src/bin/dd/extern.h,v 1.12 2002/02/02 06:24:12 imp Exp $
*/
#include <sys/cdefs.h>
-void block __P((void));
-void block_close __P((void));
-void dd_out __P((int));
-void def __P((void));
-void def_close __P((void));
-void jcl __P((char **));
-void pos_in __P((void));
-void pos_out __P((void));
-void summary __P((void));
-void summaryx __P((int));
-void terminate __P((int));
-void unblock __P((void));
-void unblock_close __P((void));
+void block(void);
+void block_close(void);
+void dd_out(int);
+void def(void);
+void def_close(void);
+void jcl(char **);
+void pos_in(void);
+void pos_out(void);
+void summary(void);
+void summaryx(int);
+void terminate(int);
+void unblock(void);
+void unblock_close(void);
extern IO in, out;
extern STAT st;
-extern void (*cfunc) __P((void));
-extern u_long cpy_cnt;
-extern u_int cbsz;
+extern void (*cfunc)(void);
+extern quad_t cpy_cnt;
+extern size_t cbsz;
extern u_int ddflags;
-extern u_int files_cnt;
+extern quad_t files_cnt;
extern const u_char *ctab;
extern const u_char a2e_32V[], a2e_POSIX[];
extern const u_char e2a_32V[], e2a_POSIX[];
-/* $NetBSD: misc.c,v 1.8 1998/07/28 05:31:23 mycroft Exp $ */
-
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94";
-#else
-__RCSID("$NetBSD: misc.c,v 1.8 1998/07/28 05:31:23 mycroft Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/bin/dd/misc.c,v 1.23 2002/02/02 06:24:12 imp Exp $";
#endif /* not lint */
#include <sys/types.h>
+#include <sys/time.h>
-#include <err.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <time.h>
+#include <strings.h>
#include <unistd.h>
#include "dd.h"
#include "extern.h"
void
-summary()
+summary(void)
{
- time_t secs;
+ struct timeval tv;
+ double secs;
char buf[100];
- (void)time(&secs);
- if ((secs -= st.start) == 0)
- secs = 1;
+ (void)gettimeofday(&tv, (struct timezone *)NULL);
+ secs = tv.tv_sec + tv.tv_usec * 1e-6 - st.start;
+ if (secs < 1e-6)
+ secs = 1e-6;
/* Use snprintf(3) so that we don't reenter stdio(3). */
(void)snprintf(buf, sizeof(buf),
- "%lu+%lu records in\n%lu+%lu records out\n",
+ "%qu+%qu records in\n%qu+%qu records out\n",
st.in_full, st.in_part, st.out_full, st.out_part);
(void)write(STDERR_FILENO, buf, strlen(buf));
if (st.swab) {
- (void)snprintf(buf, sizeof(buf), "%lu odd length swab %s\n",
+ (void)snprintf(buf, sizeof(buf), "%qu odd length swab %s\n",
st.swab, (st.swab == 1) ? "block" : "blocks");
(void)write(STDERR_FILENO, buf, strlen(buf));
}
if (st.trunc) {
- (void)snprintf(buf, sizeof(buf), "%lu truncated %s\n",
+ (void)snprintf(buf, sizeof(buf), "%qu truncated %s\n",
st.trunc, (st.trunc == 1) ? "block" : "blocks");
(void)write(STDERR_FILENO, buf, strlen(buf));
}
(void)snprintf(buf, sizeof(buf),
- "%qu bytes transferred in %lu secs (%qu bytes/sec)\n",
- (long long) st.bytes, (long) secs, (long long) (st.bytes / secs));
+ "%qu bytes transferred in %.6f secs (%.0f bytes/sec)\n",
+ st.bytes, secs, st.bytes / secs);
(void)write(STDERR_FILENO, buf, strlen(buf));
}
/* ARGSUSED */
void
-summaryx(notused)
- int notused;
+summaryx(int notused)
{
+ int save_errno = errno;
summary();
+ errno = save_errno;
}
/* ARGSUSED */
void
-terminate(notused)
- int notused;
+terminate(int sig)
{
- exit(0);
- /* NOTREACHED */
+ summary();
+ _exit(sig == 0 ? 0 : 1);
}
-/* $NetBSD: position.c,v 1.6 1997/07/25 06:46:24 phil Exp $ */
-
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)position.c 8.3 (Berkeley) 4/2/94";
-#else
-__RCSID("$NetBSD: position.c,v 1.6 1997/07/25 06:46:24 phil Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/bin/dd/position.c,v 1.20 2002/02/02 06:24:12 imp Exp $";
#endif /* not lint */
#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
#include <sys/mtio.h>
+#ifdef __APPLE__
+#include <sys/ioctl.h>
+#endif
+
#include <err.h>
#include <errno.h>
-#include <string.h>
#include <unistd.h>
#include "dd.h"
* output.
*/
void
-pos_in()
+pos_in(void)
{
- int bcnt, cnt, nr, warned;
-
- /* If not a character, pipe or tape device, try to seek on it. */
- if (!(in.flags & (ISCHR|ISPIPE|ISTAPE))) {
- if (lseek(in.fd, (off_t)in.offset * (off_t)in.dbsz, SEEK_CUR)
- == -1)
+ off_t cnt;
+ int warned;
+ ssize_t nr;
+ size_t bcnt;
+
+ /* If known to be seekable, try to seek on it. */
+ if (in.flags & ISSEEK) {
+ errno = 0;
+ if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1 &&
+ errno != 0)
err(1, "%s", in.name);
return;
}
+ /* Don't try to read a really weird amount (like negative). */
+ if (in.offset < 0)
+ errx(1, "%s: illegal offset", "iseek/skip");
+
/*
* Read the data. If a pipe, read until satisfy the number of bytes
* being skipped. No differentiation for reading complete and partial
}
void
-pos_out()
+pos_out(void)
{
struct mtop t_op;
- int cnt, n;
+ off_t cnt;
+ ssize_t n;
/*
* If not a tape, try seeking on the file. Seeking on a pipe is
* going to fail, but don't protect the user -- they shouldn't
* have specified the seek operand.
*/
- if (!(out.flags & ISTAPE)) {
- if (lseek(out.fd,
- (off_t)out.offset * (off_t)out.dbsz, SEEK_SET) == -1)
+ if (out.flags & (ISSEEK | ISPIPE)) {
+ errno = 0;
+ if (lseek(out.fd, out.offset * out.dbsz, SEEK_CUR) == -1 &&
+ errno != 0)
err(1, "%s", out.name);
return;
}
+ /* Don't try to read a really weird amount (like negative). */
+ if (out.offset < 0)
+ errx(1, "%s: illegal offset", "oseek/seek");
+
/* If no read access, try using mtio. */
if (out.flags & NOREAD) {
t_op.mt_op = MTFSR;
t_op.mt_count = out.offset;
- if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)
+ if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
err(1, "%s", out.name);
return;
}
if ((n = read(out.fd, out.db, out.dbsz)) > 0)
continue;
- if (n < 0)
+ if (n == -1)
err(1, "%s", out.name);
/*
if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
err(1, "%s", out.name);
- while (cnt++ < out.offset)
- if ((n = write(out.fd, out.db, out.dbsz)) != out.dbsz)
+ while (cnt++ < out.offset) {
+ n = write(out.fd, out.db, out.dbsz);
+ if (n == -1)
err(1, "%s", out.name);
+ if ((size_t)n != out.dbsz)
+ errx(1, "%s: write failure", out.name);
+ }
break;
}
}
--- /dev/null
+$NetBSD: LEGAL.NOTICE,v 1.7 1998/09/24 12:50:27 christos Exp $
+Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995.
+Software written by Ian F. Darwin and others;
+maintained 1994-1995 Christos Zoulas.
+
+This software is not subject to any export provision of the United States
+Department of Commerce, and may be exported to any country or planet.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice immediately at the beginning of the file, without modification,
+ this list of conditions, and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by Ian F. Darwin and others.
+4. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
--- /dev/null
+$NetBSD: MAINT,v 1.4 1998/09/20 15:27:15 christos Exp $
+Id: MAINT,v 1.3 1997/11/05 16:03:18 christos Exp
+
+Maintenance notes:
+
+I am continuing to maintain the file command. I welcome your help,
+but to make my life easier I'd like to request the following:
+
+- Don't change the version numbers!
+
+If your changes are extensive, I will have to work hard to
+integrate them into my version. If you check it into SCCS locally,
+the version numbers will likely be kept. IF you check it into RCS
+or CVS locally, please use -k to keep the version numbers, and
+please use branch deltas (1.21.1, 1.21.2, ...). If you don't do
+this, I will likely be unable to use your changes; life's just too
+short.
+
+- Do not distribute changed versions.
+
+People trying to be helpful occasionally put up their hacked versions
+of the file command for FTP, then the "archie" server finds and publishes
+the hacked version, and people all over the world get copies of it.
+Within a day or two I am getting email from around the world
+asking me why "my" file command won't compile!!! Needless to say this
+detracts from the limited time I have available to work on the actual
+software. Therefore I ask you again to please NOT distribute
+your changed version.
+
+
+Thank you for your assistance and cooperation.
+
+Mark Moraes Christos Zoulas
+moraes@deshaw.com christos@astron.com
--- /dev/null
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = file
+
+PROJECTVERSION = 2.6
+PROJECT_TYPE = Tool
+LANGUAGE = English
+
+HFILES = file.h names.h patchlevel.h readelf.h tar.h
+
+CFILES = apprentice.c ascmagic.c compress.c file.c fsmagic.c\
+ internat.c is_tar.c print.c readelf.c softmagic.c readfat.c
+
+OTHERSRCS = Makefile Makefile.preamble Makefile.postamble file.1\
+ LEGAL.NOTICE magic.5 MAINT PORTING README \
+magdir/386bsd \
+magdir/Header \
+magdir/Localstuff \
+magdir/OpenBSD \
+magdir/adventure \
+magdir/alliant \
+magdir/alpha \
+magdir/amanda \
+magdir/amigaos \
+magdir/animation \
+magdir/apl \
+magdir/apple \
+magdir/applix \
+magdir/archive \
+magdir/asterix \
+magdir/att3b \
+magdir/audio \
+magdir/blit \
+magdir/bsdi \
+magdir/c-lang \
+magdir/chi \
+magdir/cisco \
+magdir/clipper \
+magdir/commands \
+magdir/compress \
+magdir/convex \
+magdir/database \
+magdir/diamond \
+magdir/diff \
+magdir/digital \
+magdir/dump \
+magdir/elf \
+magdir/encore \
+magdir/filesystems \
+magdir/flash \
+magdir/fonts \
+magdir/frame \
+magdir/freebsd \
+magdir/gimp \
+magdir/gnu \
+magdir/hp \
+magdir/ibm370 \
+magdir/ibm6000 \
+magdir/iff \
+magdir/images \
+magdir/intel \
+magdir/interleaf \
+magdir/island \
+magdir/ispell \
+magdir/java \
+magdir/karma \
+magdir/lecter \
+magdir/lex \
+magdir/lif \
+magdir/linux \
+magdir/lisp \
+magdir/mach \
+magdir/macintosh \
+magdir/magic \
+magdir/mail.news \
+magdir/microsoft \
+magdir/mime \
+magdir/mirage \
+magdir/mkid \
+magdir/mmdf \
+magdir/modem \
+magdir/motorola \
+magdir/msdos \
+magdir/ncr \
+magdir/netbsd \
+magdir/news \
+magdir/octave \
+magdir/olf \
+magdir/os2 \
+magdir/os9 \
+magdir/osf1 \
+magdir/pbm \
+magdir/pdf \
+magdir/pdp \
+magdir/pgp \
+magdir/pkgadd \
+magdir/plus5 \
+magdir/printer \
+magdir/psdbms \
+magdir/pyramid \
+magdir/riff \
+magdir/rpm \
+magdir/rtf \
+magdir/sc \
+magdir/sccs \
+magdir/sendmail \
+magdir/sequent \
+magdir/sgi \
+magdir/sgml \
+magdir/sniffer \
+magdir/softquad \
+magdir/sun \
+magdir/teapot \
+magdir/terminfo \
+magdir/tex \
+magdir/ti-8x \
+magdir/timezone \
+magdir/troff \
+magdir/typeset \
+magdir/unknown \
+magdir/uuencode \
+magdir/varied.out \
+magdir/vax \
+magdir/vicar \
+magdir/visx \
+magdir/vms \
+magdir/wordperfect \
+magdir/xenix \
+magdir/zilog \
+magdir/zyxel
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/bin
+LIBS =
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_BUILD_OUTPUT_DIR = /tmp/developer_cmds/Build
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
--- /dev/null
+include $(CoreOSMakefiles)/ProjectBuilder/Makefile.Postamble.Common
+
+MAGFILES = $(SRCROOT)/file/magdir/Header \
+ $(SRCROOT)/file/magdir/Localstuff \
+ $(SRCROOT)/file/magdir/OpenBSD \
+ $(SRCROOT)/file/magdir/[a-z]*
+after_install:
+ mkdir -p $(DSTROOT)/private/etc/
+ cat $(MAGFILES) > $(DSTROOT)/private/etc/magic
--- /dev/null
+include $(CoreOSMakefiles)/ProjectBuilder/Makefile.Preamble.Common
+OTHER_CFLAGS = -DBUILTIN_FAT
--- /dev/null
+{
+ DYNAMIC_CODE_GEN = YES;
+ FILESTABLE = {
+ FRAMEWORKS = ();
+ H_FILES = (file.h, names.h, patchlevel.h, readelf.h, tar.h);
+ OTHER_LINKED = (
+ apprentice.c,
+ ascmagic.c,
+ compress.c,
+ file.c,
+ fsmagic.c,
+ internat.c,
+ is_tar.c,
+ print.c,
+ readelf.c,
+ softmagic.c
+ );
+ OTHER_SOURCES = (
+ Makefile,
+ Makefile.preamble,
+ Makefile.postamble,
+ file.1,
+ LEGAL.NOTICE,
+ magic.5,
+ MAINT,
+ PORTING,
+ README
+ );
+ };
+ LANGUAGE = English;
+ LOCALIZABLE_FILES = {};
+ MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
+ NEXTSTEP_BUILDDIR = /tmp/developer_cmds/Build;
+ NEXTSTEP_BUILDTOOL = /bin/gnumake;
+ NEXTSTEP_INSTALLDIR = /usr/bin;
+ PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make;
+ PROJECTNAME = file;
+ PROJECTTYPE = Tool;
+ PROJECTVERSION = 2.6;
+ WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make;
+}
--- /dev/null
+$NetBSD: PORTING,v 1.5 1998/09/20 15:27:15 christos Exp $
+Portability of the new file(1) command.
+@(#) Id: PORTING,v 1.11 1993/09/23 21:47:23 christos Exp
+
+Read this file only if the program doesn't compile on your system.
+
+This release has been around UNIX; it has been compiled and tested
+in the following environments:
+
+SunOS sqarc 4.1.1 8 sun4
+ No problems.
+ULTRIX squint 4.2 0 RISC
+ No problems.
+A/UX sqmac 3.0a9 SVR22 mc68020
+ No problems.
+AIX sqibm 2 3 000XXXXXX100
+ Had weird "make" problems making "magic" file automatically; just
+ built it by hand. Your mileage may vary.
+SCO sqwang 3.2 2 i386
+ Compiles fine; their weird make can't handle "[a-z]*" as a dependancy,
+ so build magic by hand. Runs fine.
+sqzme sqzme 3.1.1 3 3B2
+ The 3B2 SVR3 needed a few tweaks as well as COPTS = -Ilocalinc
+ in order to compile.
+
+This version, reluctanly, includes <stdlib.h>, which won't exist
+on older systems or those that aren't even close to the ANSI C
+standard. There is a null "stdlib.h", and some other bogus headers,
+in subdirectory "localinc"; if you get complaints about missing
+stdlib.h and others, uncomment the line with COPTS=-Ilocalinc
+in the Makefile, and try again.
+
+You must have either <stdarg.h> or the older <varargs.h>, otherwise you'll
+have to butcher some routines in print.c.
+
+Beyond that, I have tried to make a program that doesn't need any
+command-line defines (-D) to specify what version of UNIX is in use,
+by using the definitions available in the system #include
+files. For example, the lstat(2) call is normally found in
+4BSD systems, but might be grafted into some other variant
+of UNIX. If it's done right (ie., using the same definitions),
+my program will compile and work correctly. Look at the #ifdefs
+to see how it's done.
+
+I've also tried to include source for all the non-portable library routines
+I used (getopt, str*). Non-portable here means `not in every
+reasonably standard UNIX out there: V7, System V, 4BSD'.
+These are in subdirectory "localsrc", and not used unless you
+need them; again, see the Makefile.
+
+There is one area that just might cause problems. On System
+V, they moved the definition of major() and minor() out of
+<sys/types.h> into <sys/sysmacros.h>. Hence, if major isn't
+defined after including types.h, I automatically include sys/sysmacros.h.
+This will work for 99% of the systems out there. ONLY if you
+have a system in which neither types.h nor sysmacros.h defines
+`major' will this automatic include fail (I hope). On such
+systems, you will get a compilation error in trying to compile
+a warning message. Please do the following:
+
+ 1) change the appropriate #include at the start of fsmagic.c
+and 2) let me know the name of the system, the release number,
+ and the name of the header file that *does* include
+ this "standard" definition.
+
+If you are running the old Ritchie PDP-11 C compiler or
+some other compiler that doesn't know about `void', you will have
+to include `-Dvoid=int' in the variable COPTS in the Makefile.
+
+Other than this, there should be no portability problems,
+but one never knows these days. Please let me know of any
+other problems you find porting to a UNIX system. I don't much
+care about non-UNIX systems but will collect widely-used magic
+numbers for them as well as for UNIX systems.
+
+Mark Moraes and Christos Zoulas
+(address in README)
--- /dev/null
+$NetBSD: README,v 1.6 1998/09/20 15:27:15 christos Exp $
+** README for file(1) Command **
+@(#) Id: README,v 1.22 1997/11/05 16:03:18 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,
+*BSD, and other systems. (See "patchlevel.h" for the exact release number).
+
+UNIX is a trademark of UNIX System Laboratories.
+
+The prime contributor to Release 3.8 was Guy Harris, who put in megachanges
+including byte-order independance.
+
+The prime contributor to Release 3.0 was Christos Zoulas, who put
+in hundreds of lines of source code changes, including his own
+ANSIfication of the code (I liked my own ANSIfication better, but
+his (__P()) is the "Berkeley standard" way of doing it, and I wanted UCB
+to include the code...), his HP-like "indirection" (a feature of
+the HP file command, I think), and his mods that finally got the
+uncompress (-z) mode finished and working.
+
+This release has compiled in numerous environments; see PORTING
+for a list and problems.
+
+This fine freeware file(1) follows the USG (System V) model of the file
+command, rather than the Research (V7) version or the V7-derived 4.[23]
+Berkeley one. That is, the file /etc/magic contains much of the ritual
+information that is the source of this program's power. My version
+knows a little more magic (including tar archives) than System V; the
+/etc/magic parsing seems to be compatible with the (poorly documented)
+System V /etc/magic format (with one exception; see the man page).
+
+In addition, the /etc/magic file is built from a subdirectory
+for easier(?) maintenance. I will act as a clearinghouse for
+magic numbers assigned to all sorts of data files that
+are in reasonable circulation. Send your magic numbers,
+in magic(4) format please, to the maintainer, Christos Zoulas.
+
+LEGAL.NOTICE - read this first.
+README - read this second (you are currently reading this file).
+PORTING - read this only if the program won't compile.
+Makefile - read this next, adapt it as needed (particularly
+ the location of the old existing file command and
+ the man page layouts), type "make" to compile,
+ "make try" to try it out against your old version.
+ Expect some diffs, particularly since your original
+ file(1) may not grok the imbedded-space ("\ ") in
+ the current magic file, or may even not use the
+ magic file.
+apprentice.c - parses /etc/magic to learn magic
+ascmagic.c - third & last set of tests, based on hardwired assumptions.
+core - not included in distribution due to mailer limitations.
+debug.c - includes -c printout routine
+file.1 - man page for the command
+magic.4 - man page for the magic file, courtesy Guy Harris.
+ Install as magic.4 on USG and magic.5 on V7 or Berkeley; cf Makefile.
+file.c - main program
+file.h - header file
+fsmagic.c - first set of tests the program runs, based on filesystem info
+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
+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@astron.com, moraes@deshaw.com
+
+Phone: Do not even think of telephoning me about this program. Send cash first!
+
+Parts of this software were developed at SoftQuad Inc., 56 Aberfoyle
+Cres, # 810, Toronto, Ontario CANADA M8X 2W4. Phone: 416-239-4801 or
+800-387-2777. Email: mail@sq.com. Call for information on SGML editing
+and browsing, Unix text processing, and customised products on Unix,
+DOS and Mac.
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: apprentice.c,v 1.4 1997/02/09 23:58:16 millert Exp $ */
+
+/*
+ * apprentice - make one pass through /etc/magic, learning its secrets.
+ *
+ * Copyright (c) Ian F. Darwin, 1987.
+ * Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include "file.h"
+
+#ifndef lint
+#if 0
+static char *moduleid = "$OpenBSD: apprentice.c,v 1.4 1997/02/09 23:58:16 millert Exp $";
+#endif
+#endif /* lint */
+
+#define EATAB {while (isascii((unsigned char) *l) && \
+ isspace((unsigned char) *l)) ++l;}
+#define LOWCASE(l) (isupper((unsigned char) (l)) ? \
+ tolower((unsigned char) (l)) : (l))
+
+
+static int getvalue __P((struct magic *, char **));
+static int hextoint __P((int));
+static char *getstr __P((char *, char *, int, int *));
+static int parse __P((char *, int *, int));
+static void eatsize __P((char **));
+
+static int maxmagic = 0;
+
+static int apprentice_1 __P((char *, int));
+
+int
+apprentice(fn, check)
+char *fn; /* list of magic files */
+int check; /* non-zero? checking-only run. */
+{
+ char *p, *mfn;
+ int file_err, errs = -1;
+
+ maxmagic = MAXMAGIS;
+ magic = (struct magic *) calloc(sizeof(struct magic), maxmagic);
+ mfn = malloc(strlen(fn)+1);
+ if (magic == NULL || mfn == NULL) {
+ (void) fprintf(stderr, "%s: Out of memory.\n", progname);
+ if (check)
+ return -1;
+ else
+ exit(1);
+ }
+ fn = strcpy(mfn, fn);
+
+ while (fn) {
+ p = strchr(fn, ':');
+ if (p)
+ *p++ = '\0';
+ file_err = apprentice_1(fn, check);
+ if (file_err > errs)
+ errs = file_err;
+ fn = p;
+ }
+ if (errs == -1)
+ (void) fprintf(stderr, "%s: couldn't find any magic files!\n",
+ progname);
+ if (!check && errs)
+ exit(1);
+
+ free(mfn);
+ return errs;
+}
+
+static int
+apprentice_1(fn, check)
+char *fn; /* name of magic file */
+int check; /* non-zero? checking-only run. */
+{
+ static const char hdr[] =
+ "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
+ FILE *f;
+ char line[BUFSIZ+1];
+ int errs = 0;
+
+ f = fopen(fn, "r");
+ if (f==NULL) {
+ if (errno != ENOENT)
+ (void) fprintf(stderr,
+ "%s: can't read magic file %s (%s)\n",
+ progname, fn, strerror(errno));
+ return -1;
+ }
+
+ /* parse it */
+ if (check) /* print silly verbose header for USG compat. */
+ (void) printf("%s\n", hdr);
+
+ for (lineno = 1;fgets(line, BUFSIZ, f) != NULL; lineno++) {
+ if (line[0]=='#') /* comment, do not parse */
+ continue;
+ if (strlen(line) <= (unsigned)1) /* null line, garbage, etc */
+ continue;
+ line[strlen(line)-1] = '\0'; /* delete newline */
+ if (parse(line, &nmagic, check) != 0)
+ errs = 1;
+ }
+
+ (void) fclose(f);
+ return errs;
+}
+
+/*
+ * extend the sign bit if the comparison is to be signed
+ */
+uint32
+signextend(m, v)
+struct magic *m;
+uint32 v;
+{
+ if (!(m->flag & UNSIGNED))
+ switch(m->type) {
+ /*
+ * Do not remove the casts below. They are
+ * vital. When later compared with the data,
+ * the sign extension must have happened.
+ */
+ case BYTE:
+ v = (char) v;
+ break;
+ case SHORT:
+ case BESHORT:
+ case LESHORT:
+ v = (short) v;
+ break;
+ case DATE:
+ case BEDATE:
+ case LEDATE:
+ case LONG:
+ case BELONG:
+ case LELONG:
+ v = (int32) v;
+ break;
+ case STRING:
+ break;
+ default:
+ magwarn("can't happen: m->type=%d\n",
+ m->type);
+ return -1;
+ }
+ return v;
+}
+
+/*
+ * parse one line from magic file, put into magic[index++] if valid
+ */
+static int
+parse(l, ndx, check)
+char *l;
+int *ndx, check;
+{
+ int i = 0, nd = *ndx;
+ struct magic *m;
+ char *t, *s;
+
+#define ALLOC_INCR 20
+ if (nd+1 >= maxmagic){
+ maxmagic += ALLOC_INCR;
+ if ((magic = (struct magic *) realloc(magic,
+ sizeof(struct magic) *
+ maxmagic)) == NULL) {
+ (void) fprintf(stderr, "%s: Out of memory.\n", progname);
+ if (check)
+ return -1;
+ else
+ exit(1);
+ }
+ memset(&magic[*ndx], 0, sizeof(struct magic) * ALLOC_INCR);
+ }
+ m = &magic[*ndx];
+ m->flag = 0;
+ m->cont_level = 0;
+
+ while (*l == '>') {
+ ++l; /* step over */
+ m->cont_level++;
+ }
+
+ if (m->cont_level != 0 && *l == '(') {
+ ++l; /* step over */
+ m->flag |= INDIR;
+ }
+ if (m->cont_level != 0 && *l == '&') {
+ ++l; /* step over */
+ m->flag |= ADD;
+ }
+
+ /* get offset, then skip over it */
+ m->offset = (int) strtoul(l,&t,0);
+ if (l == t)
+ magwarn("offset %s invalid", l);
+ l = t;
+
+ if (m->flag & INDIR) {
+ m->in.type = LONG;
+ m->in.offset = 0;
+ /*
+ * read [.lbs][+-]nnnnn)
+ */
+ if (*l == '.') {
+ l++;
+ switch (LOWCASE(*l)) {
+ case 'l':
+ m->in.type = LONG;
+ break;
+ case 'h':
+ case 's':
+ m->in.type = SHORT;
+ break;
+ case 'c':
+ case 'b':
+ m->in.type = BYTE;
+ break;
+ default:
+ magwarn("indirect offset type %c invalid", *l);
+ break;
+ }
+ l++;
+ }
+ s = l;
+ if (*l == '+' || *l == '-') l++;
+ if (isdigit((unsigned char)*l)) {
+ m->in.offset = strtoul(l, &t, 0);
+ if (*s == '-') m->in.offset = - m->in.offset;
+ }
+ else
+ t = l;
+ if (*t++ != ')')
+ magwarn("missing ')' in indirect offset");
+ l = t;
+ }
+
+
+ while (isascii((unsigned char)*l) && isdigit((unsigned char)*l))
+ ++l;
+ EATAB;
+
+#define NBYTE 4
+#define NSHORT 5
+#define NLONG 4
+#define NSTRING 6
+#define NDATE 4
+#define NBESHORT 7
+#define NBELONG 6
+#define NBEDATE 6
+#define NLESHORT 7
+#define NLELONG 6
+#define NLEDATE 6
+
+ if (*l == 'u') {
+ ++l;
+ m->flag |= UNSIGNED;
+ }
+
+ /* get type, skip it */
+ if (strncmp(l, "byte", NBYTE)==0) {
+ m->type = BYTE;
+ l += NBYTE;
+ } else if (strncmp(l, "short", NSHORT)==0) {
+ m->type = SHORT;
+ l += NSHORT;
+ } else if (strncmp(l, "long", NLONG)==0) {
+ m->type = LONG;
+ l += NLONG;
+ } else if (strncmp(l, "string", NSTRING)==0) {
+ m->type = STRING;
+ l += NSTRING;
+ } else if (strncmp(l, "date", NDATE)==0) {
+ m->type = DATE;
+ l += NDATE;
+ } else if (strncmp(l, "beshort", NBESHORT)==0) {
+ m->type = BESHORT;
+ l += NBESHORT;
+ } else if (strncmp(l, "belong", NBELONG)==0) {
+ m->type = BELONG;
+ l += NBELONG;
+ } else if (strncmp(l, "bedate", NBEDATE)==0) {
+ m->type = BEDATE;
+ l += NBEDATE;
+ } else if (strncmp(l, "leshort", NLESHORT)==0) {
+ m->type = LESHORT;
+ l += NLESHORT;
+ } else if (strncmp(l, "lelong", NLELONG)==0) {
+ m->type = LELONG;
+ l += NLELONG;
+ } else if (strncmp(l, "ledate", NLEDATE)==0) {
+ m->type = LEDATE;
+ l += NLEDATE;
+ } else {
+ magwarn("type %s invalid", l);
+ return -1;
+ }
+ /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */
+ if (*l == '&') {
+ ++l;
+ m->mask = signextend(m, strtoul(l, &l, 0));
+ eatsize(&l);
+ } else
+ m->mask = ~0L;
+ EATAB;
+
+ switch (*l) {
+ case '>':
+ case '<':
+ /* Old-style anding: "0 byte &0x80 dynamically linked" */
+ case '&':
+ case '^':
+ case '=':
+ m->reln = *l;
+ ++l;
+ break;
+ case '!':
+ if (m->type != STRING) {
+ m->reln = *l;
+ ++l;
+ break;
+ }
+ /* FALL THROUGH */
+ default:
+ if (*l == 'x' && isascii((unsigned char)l[1]) &&
+ isspace((unsigned char)l[1])) {
+ m->reln = *l;
+ ++l;
+ goto GetDesc; /* Bill The Cat */
+ }
+ m->reln = '=';
+ break;
+ }
+ EATAB;
+
+ if (getvalue(m, &l))
+ return -1;
+ /*
+ * TODO finish this macro and start using it!
+ * #define offsetcheck {if (offset > HOWMANY-1)
+ * magwarn("offset too big"); }
+ */
+
+ /*
+ * now get last part - the description
+ */
+GetDesc:
+ EATAB;
+ if (l[0] == '\b') {
+ ++l;
+ m->nospflag = 1;
+ } else if ((l[0] == '\\') && (l[1] == 'b')) {
+ ++l;
+ ++l;
+ m->nospflag = 1;
+ } else
+ m->nospflag = 0;
+ while ((m->desc[i++] = *l++) != '\0' && i<MAXDESC)
+ /* NULLBODY */;
+
+ if (check) {
+ mdump(m);
+ }
+ ++(*ndx); /* make room for next */
+ return 0;
+}
+
+/*
+ * Read a numeric value from a pointer, into the value union of a magic
+ * pointer, according to the magic type. Update the string pointer to point
+ * just after the number read. Return 0 for success, non-zero for failure.
+ */
+static int
+getvalue(m, p)
+struct magic *m;
+char **p;
+{
+ int slen;
+
+ if (m->type == STRING) {
+ *p = getstr(*p, m->value.s, sizeof(m->value.s), &slen);
+ m->vallen = slen;
+ } else
+ if (m->reln != 'x') {
+ m->value.l = signextend(m, strtoul(*p, p, 0));
+ eatsize(p);
+ }
+ return 0;
+}
+
+/*
+ * Convert a string containing C character escapes. Stop at an unescaped
+ * space or tab.
+ * Copy the converted version to "p", returning its length in *slen.
+ * Return updated scan pointer as function result.
+ */
+static char *
+getstr(s, p, plen, slen)
+register char *s;
+register char *p;
+int plen, *slen;
+{
+ char *origs = s, *origp = p;
+ char *pmax = p + plen - 1;
+ register int c;
+ register int val;
+
+ while ((c = *s++) != '\0') {
+ if (isspace((unsigned char) c))
+ break;
+ if (p >= pmax) {
+ fprintf(stderr, "String too long: %s\n", origs);
+ break;
+ }
+ if(c == '\\') {
+ switch(c = *s++) {
+
+ case '\0':
+ goto out;
+
+ default:
+ *p++ = (char) c;
+ break;
+
+ case 'n':
+ *p++ = '\n';
+ break;
+
+ case 'r':
+ *p++ = '\r';
+ break;
+
+ case 'b':
+ *p++ = '\b';
+ break;
+
+ case 't':
+ *p++ = '\t';
+ break;
+
+ case 'f':
+ *p++ = '\f';
+ break;
+
+ case 'v':
+ *p++ = '\v';
+ break;
+
+ /* \ and up to 3 octal digits */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ val = c - '0';
+ c = *s++; /* try for 2 */
+ if(c >= '0' && c <= '7') {
+ val = (val<<3) | (c - '0');
+ c = *s++; /* try for 3 */
+ if(c >= '0' && c <= '7')
+ val = (val<<3) | (c-'0');
+ else
+ --s;
+ }
+ else
+ --s;
+ *p++ = (char)val;
+ break;
+
+ /* \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)
+ val = (val << 4) + c;
+ else
+ --s;
+ } else
+ --s;
+ *p++ = (char)val;
+ break;
+ }
+ } else
+ *p++ = (char)c;
+ }
+out:
+ *p = '\0';
+ *slen = p - origp;
+ return s;
+}
+
+
+/* Single hex char to int; -1 if not a hex char. */
+static int
+hextoint(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;
+}
+
+
+/*
+ * Print a string containing C character escapes.
+ */
+void
+showstr(fp, s, len)
+FILE *fp;
+const char *s;
+int len;
+{
+ register char c;
+
+ for (;;) {
+ c = *s++;
+ if (len == -1) {
+ if (c == '\0')
+ break;
+ }
+ else {
+ if (len-- == 0)
+ break;
+ }
+ if(c >= 040 && c <= 0176) /* TODO isprint && !iscntrl */
+ (void) fputc(c, fp);
+ else {
+ (void) fputc('\\', fp);
+ switch (c) {
+
+ case '\n':
+ (void) fputc('n', fp);
+ break;
+
+ case '\r':
+ (void) fputc('r', fp);
+ break;
+
+ case '\b':
+ (void) fputc('b', fp);
+ break;
+
+ case '\t':
+ (void) fputc('t', fp);
+ break;
+
+ case '\f':
+ (void) fputc('f', fp);
+ break;
+
+ case '\v':
+ (void) fputc('v', fp);
+ break;
+
+ default:
+ (void) fprintf(fp, "%.3o", c & 0377);
+ break;
+ }
+ }
+ }
+}
+
+/*
+ * eatsize(): Eat the size spec from a number [eg. 10UL]
+ */
+static void
+eatsize(p)
+char **p;
+{
+ char *l = *p;
+
+ if (LOWCASE(*l) == 'u')
+ l++;
+
+ switch (LOWCASE(*l)) {
+ case 'l': /* long */
+ case 's': /* short */
+ case 'h': /* short */
+ case 'b': /* char/byte */
+ case 'c': /* char/byte */
+ l++;
+ /*FALLTHROUGH*/
+ default:
+ break;
+ }
+
+ *p = l;
+}
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: ascmagic.c,v 1.3 1997/02/09 23:58:18 millert Exp $ */
+
+/*
+ * ASCII magic -- file types that we know based on keywords
+ * that can appear anywhere in the file.
+ *
+ * Copyright (c) Ian F. Darwin, 1987.
+ * Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "file.h"
+#include "names.h"
+
+#ifndef lint
+#if 0
+static char *moduleid = "$OpenBSD: ascmagic.c,v 1.3 1997/02/09 23:58:18 millert Exp $";
+#endif
+#endif /* lint */
+
+ /* an optimisation over plain strcmp() */
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+int
+ascmagic(buf, nbytes)
+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;
+
+ /*
+ * Do the tar test first, because if the first file in the tar
+ * archive starts with a dot, we can confuse it with an nroff file.
+ */
+ switch (is_tar(buf, nbytes)) {
+ case 1:
+ ckfputs("tar archive", stdout);
+ return 1;
+ case 2:
+ ckfputs("POSIX tar archive", stdout);
+ return 1;
+ }
+
+ /*
+ * for troff, look for . + letter + letter or .\";
+ * this must be done to disambiguate tar archives' ./file
+ * and other trash from real troff input.
+ */
+ if (*buf == '.') {
+ unsigned char *tp = buf + 1;
+
+ while (isascii(*tp) && isspace(*tp))
+ ++tp; /* skip leading whitespace */
+ if ((isascii(*tp) && (isalnum(*tp) || *tp=='\\') &&
+ isascii(tp[1]) && (isalnum(tp[1]) || tp[1] == '"'))) {
+ ckfputs("troff or preprocessor input text", stdout);
+ return 1;
+ }
+ }
+ if ((*buf == 'c' || *buf == 'C') &&
+ isascii(buf[1]) && isspace(buf[1])) {
+ ckfputs("fortran program text", stdout);
+ 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);
+ 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(types[p->type], stdout);
+ if (has_escapes)
+ ckfputs(" (with escape sequences)",
+ stdout);
+ return 1;
+ }
+ }
+ }
+
+ /* all else fails, but it is ASCII... */
+ ckfputs("ASCII text", stdout);
+ if (has_escapes) {
+ ckfputs(" (with escape sequences)", stdout);
+ }
+ return 1;
+}
+
+
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: compress.c,v 1.3 1997/02/09 23:58:19 millert Exp $ */
+
+/*
+ * compress routines:
+ * zmagic() - returns 0 if not recognized, uncompresses and prints
+ * information if recognized
+ * uncompress(method, old, n, newch) - uncompress old into new,
+ * using method, return sizeof new
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/wait.h>
+
+#include "file.h"
+
+static struct {
+ char *magic;
+ int maglen;
+ char *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 */
+};
+
+static int ncompr = sizeof(compr) / sizeof(compr[0]);
+
+
+static int uncompress __P((int, const unsigned char *, unsigned char **, int));
+
+int
+zmagic(buf, nbytes)
+unsigned char *buf;
+int nbytes;
+{
+ unsigned char *newbuf;
+ int newsize;
+ int i;
+
+ for (i = 0; i < ncompr; i++) {
+ if (nbytes < compr[i].maglen)
+ continue;
+ if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0)
+ break;
+ }
+
+ 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 fdin[2], fdout[2];
+
+ if (pipe(fdin) == -1 || pipe(fdout) == -1) {
+ error("cannot create pipe (%s).\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+ switch (fork()) {
+ case 0: /* child */
+ (void) close(0);
+ (void) dup(fdin[0]);
+ (void) close(fdin[0]);
+ (void) close(fdin[1]);
+
+ (void) close(1);
+ (void) dup(fdout[1]);
+ (void) close(fdout[0]);
+ (void) close(fdout[1]);
+ if (compr[method].silent)
+ (void) close(2);
+
+ execvp(compr[method].argv[0], compr[method].argv);
+ error("could not execute `%s' (%s).\n",
+ compr[method].argv[0], strerror(errno));
+ /*NOTREACHED*/
+ case -1:
+ error("could not fork (%s).\n", strerror(errno));
+ /*NOTREACHED*/
+
+ 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*/
+ }
+ (void) close(fdin[1]);
+ if ((*newch = (unsigned char *) malloc(n)) == NULL) {
+ error("out of memory.\n");
+ /*NOTREACHED*/
+ }
+ if ((n = read(fdout[0], *newch, n)) <= 0) {
+ free(*newch);
+ error("read failed (%s).\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+ (void) close(fdout[0]);
+ (void) wait(NULL);
+ return n;
+ }
+}
--- /dev/null
+.\" $OpenBSD: file.1,v 1.4 1997/02/09 23:58:20 millert Exp $
+.TH FILE 1 "Copyrighted but distributable"
+.SH NAME
+file
+\- determine file type
+.SH SYNOPSIS
+.B file
+[
+.B \-vczL
+]
+[
+.B \-f
+namefile ]
+[
+.B \-m
+magicfiles ]
+file ...
+.SH DESCRIPTION
+This manual page documents version 3.22 of the
+.B file
+command.
+.B File
+tests each argument in an attempt to classify it.
+There are three sets of tests, performed in this order:
+filesystem tests, magic number tests, and language tests.
+The
+.I first
+test that succeeds causes the file type to be printed.
+.PP
+The type printed will usually contain one of the words
+.B text
+(the file contains only
+.SM ASCII
+characters and is probably safe to read on an
+.SM ASCII
+terminal),
+.B executable
+(the file contains the result of compiling a program
+in a form understandable to some \s-1UNIX\s0 kernel or another),
+or
+.B data
+meaning anything else (data is usually `binary' or non-printable).
+Exceptions are well-known file formats (core files, tar archives)
+that are known to contain binary data.
+When modifying the file
+.I /etc/magic
+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''
+to ``shell script''.
+.PP
+The filesystem tests are based on examining the return from a
+.BR stat (2)
+system call.
+The program checks to see if the file is empty,
+or if it's some sort of special file.
+Any known file types appropriate to the system you are running on
+(sockets, symbolic links, or named pipes (FIFOs) on those systems that
+implement them)
+are intuited if they are defined in
+the system header file
+.IR sys/stat.h .
+.PP
+The magic number tests are used to check for files with data in
+particular fixed formats.
+The canonical example of this is a binary executable (compiled program)
+.I a.out
+file, whose format is defined in
+.I a.out.h
+and possibly
+.I exec.h
+in the standard include directory.
+These files have a `magic number' stored in a particular place
+near the beginning of the file that tells the \s-1UNIX\s0 operating system
+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 /etc/magic.
+.PP
+If an argument appears to be an
+.SM ASCII
+file,
+.B file
+attempts to guess its language.
+The language tests look for particular strings (cf
+.IR names.h )
+that can appear anywhere in the first few blocks of a file.
+For example, the keyword
+.B .br
+indicates that the file is most likely a
+.BR troff (1)
+input file, just as the keyword
+.B struct
+indicates a C program.
+These tests are less reliable than the previous
+two groups, so they are performed last.
+The language test routines also test for some miscellany
+(such as
+.BR tar (1)
+archives) and determine whether an unknown file should be
+labelled as `ascii text' or `data'.
+.SH OPTIONS
+.TP 8
+.B \-v
+Print the version of the program and exit.
+.TP 8
+.B \-m list
+Specify an alternate list of files containing magic numbers.
+This can be a single file, or a colon-separated list of files.
+.TP 8
+.B \-z
+Try to look inside compressed files.
+.TP 8
+.B \-c
+Cause a checking printout of the parsed form of the magic file.
+This is usually used in conjunction with
+.B \-m
+to debug a new magic file before installing it.
+.TP 8
+.B \-f namefile
+Read the names of the files to be examined from
+.I namefile
+(one per line)
+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.
+.TP 8
+.B \-L
+option causes symlinks to be followed, as the like-named option in
+.BR ls (1).
+(on systems that support symbolic links).
+.SH FILES
+.I /etc/magic
+\- default list of magic numbers
+.SH ENVIRONMENT
+The environment variable
+.B MAGIC
+can be used to set the default magic number files.
+.SH SEE ALSO
+.BR magic (5)
+\- description of magic file format.
+.br
+.BR strings (1), " od" (1)
+\- tools for examining non-textfiles.
+.SH STANDARDS CONFORMANCE
+This program is believed to exceed the System V Interface Definition
+of FILE(CMD), as near as one can determine from the vague language
+contained therein.
+Its behaviour is mostly compatible with the System V program of the same name.
+This version knows more magic, however, so it will produce
+different (albeit more accurate) output in many cases.
+.PP
+The one significant difference
+between this version and System V
+is that this version treats any white space
+as a delimiter, so that spaces in pattern strings must be escaped.
+For example,
+.br
+>10 string language impress\ (imPRESS data)
+.br
+in an existing magic file would have to be changed to
+.br
+>10 string language\e impress (imPRESS data)
+.br
+In addition, in this version, if a pattern string contains a backslash,
+it must be escaped. For example
+.br
+0 string \ebegindata Andrew Toolkit document
+.br
+in an existing magic file would have to be changed to
+.br
+0 string \e\ebegindata Andrew Toolkit document
+.br
+.PP
+SunOS releases 3.2 and later from Sun Microsystems include a
+.BR file (1)
+command derived from the System V one, but with some extensions.
+My version differs from Sun's only in minor ways.
+It includes the extension of the `&' operator, used as,
+for example,
+.br
+>16 long&0x7fffffff >0 not stripped
+.SH MAGIC DIRECTORY
+The magic file entries have been collected from various sources,
+mainly USENET, and contributed by various authors.
+Christos Zoulas (address below) will collect additional
+or corrected magic file entries.
+A consolidation of magic file entries
+will be distributed periodically.
+.PP
+The order of entries in the magic file is significant.
+Depending on what system you are using, the order that
+they are put together may be incorrect.
+If your old
+.B file
+command uses a magic file,
+keep the old magic file around for comparison purposes
+(rename it to
+.IR /etc/magic.orig ).
+.SH HISTORY
+There has been a
+.B file
+command in every \s-1UNIX\s0 since at least Research Version 6
+(man page dated January, 1975).
+The System V version introduced one significant major change:
+the external list of magic number types.
+This slowed the program down slightly but made it a lot more flexible.
+.PP
+This program, based on the System V version,
+was written by Ian Darwin without looking at anybody else's source code.
+.PP
+John Gilmore revised the code extensively, making it better than
+the first version.
+Geoff Collyer found several inadequacies
+and provided some magic file entries.
+The program has undergone continued evolution since.
+.SH AUTHOR
+Written by Ian F. Darwin, UUCP address {utzoo | ihnp4}!darwin!ian,
+Internet address ian@sq.com,
+postal address: P.O. Box 603, Station F, Toronto, Ontario, CANADA M4Y 2L8.
+.PP
+Altered by Rob McMahon, cudcv@warwick.ac.uk, 1989, to extend the `&' operator
+from simple `x&y != 0' to `x&y op z'.
+.PP
+Altered by Guy Harris, guy@auspex.com, 1993, to:
+.RS
+.PP
+put the ``old-style'' `&'
+operator back the way it was, because 1) Rob McMahon's change broke the
+previous style of usage, 2) the SunOS ``new-style'' `&' operator,
+which this version of
+.B file
+supports, also handles `x&y op z', and 3) Rob's change wasn't documented
+in any case;
+.PP
+put in multiple levels of `>';
+.PP
+put in ``beshort'', ``leshort'', etc. keywords to look at numbers in the
+file in a specific byte order, rather than in the native byte order of
+the process running
+.BR file .
+.RE
+.PP
+Changes by Ian Darwin and various authors including
+Christos Zoulas (christos@deshaw.com), 1990-1997.
+.SH LEGAL NOTICE
+Copyright (c) Ian F. Darwin, Toronto, Canada,
+1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993.
+.PP
+This software is not subject to and may not be made subject to any
+license of the American Telephone and Telegraph Company, Sun
+Microsystems Inc., Digital Equipment Inc., Lotus Development Inc., the
+Regents of the University of California, The X Consortium or MIT, or
+The Free Software Foundation.
+.PP
+This software is not subject to any export provision of the United States
+Department of Commerce, and may be exported to any country or planet.
+.PP
+Permission is granted to anyone to use this software for any purpose on
+any computer system, and to alter it and redistribute it freely, subject
+to the following restrictions:
+.PP
+1. The author is not responsible for the consequences of use of this
+software, no matter how awful, even if they arise from flaws in it.
+.PP
+2. The origin of this software must not be misrepresented, either by
+explicit claim or by omission. Since few users ever read sources,
+credits must appear in the documentation.
+.PP
+3. Altered versions must be plainly marked as such, and must not be
+misrepresented as being the original software. Since few users
+ever read sources, credits must appear in the documentation.
+.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
+The files
+.I tar.h
+and
+.I is_tar.c
+were written by John Gilmore from his public-domain
+.B tar
+program, and are not covered by the above restrictions.
+.SH BUGS
+There must be a better way to automate the construction of the Magic
+file from all the glop in Magdir. What is it?
+Better yet, the magic file should be compiled into binary (say,
+.BR ndbm (3)
+or, better yet, fixed-length
+.SM ASCII
+strings for use in heterogenous network environments) for faster startup.
+Then the program would run as fast as the Version 7 program of the same name,
+with the flexibility of the System V version.
+.PP
+.B File
+uses several algorithms that favor speed over accuracy,
+thus it can be misled about the contents of
+.SM ASCII
+files.
+.PP
+The support for
+.SM ASCII
+files (primarily for programming languages)
+is simplistic, inefficient and requires recompilation to update.
+.PP
+There should be an ``else'' clause to follow a series of continuation lines.
+.PP
+The magic file and keywords should have regular expression support.
+Their use of
+.SM "ASCII TAB"
+as a field delimiter is ugly and makes
+it hard to edit the files, but is entrenched.
+.PP
+It might be advisable to allow upper-case letters in keywords
+for e.g.,
+.BR troff (1)
+commands vs man page macros.
+Regular expression support would make this easy.
+.PP
+The program doesn't grok \s-2FORTRAN\s0.
+It should be able to figure \s-2FORTRAN\s0 by seeing some keywords which
+appear indented at the start of line.
+Regular expression support would make this easy.
+.PP
+The list of keywords in
+.I ascmagic
+probably belongs in the Magic file.
+This could be done by using some keyword like `*' for the offset value.
+.PP
+Another optimisation would be to sort
+the magic file so that we can just run down all the
+tests for the first byte, first word, first long, etc, once we
+have fetched it. Complain about conflicts in the magic file entries.
+Make a rule that the magic entries sort based on file offset rather
+than position within the magic file?
+.PP
+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
+possible to use the first guess.
+.PP
+This program is slower than some vendors' file commands.
+.PP
+This manual page, and particularly this section, is too long.
+.SH AVAILABILITY
+You can obtain the original author's latest version by anonymous FTP
+on
+.B ftp.deshaw.com
+in the directory
+.I /pub/file/file-X.YY.tar.gz
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: file.c,v 1.5 1997/02/09 23:58:22 millert Exp $ */
+
+/*
+ * file - find type of a file or files - main program.
+ *
+ * Copyright (c) Ian F. Darwin, 1987.
+ * Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ */
+#ifndef lint
+#if 0
+static char *moduleid = "$OpenBSD: file.c,v 1.5 1997/02/09 23:58:22 millert Exp $";
+#endif
+#endif /* lint */
+
+#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() */
+#if (__COHERENT__ >= 0x420)
+# include <sys/utime.h>
+#else
+# ifdef USE_UTIMES
+# include <sys/time.h>
+# else
+# include <utime.h>
+# endif
+#endif
+#include <unistd.h> /* for read() */
+
+#include <netinet/in.h> /* for byte swapping */
+
+#include "patchlevel.h"
+#include "file.h"
+
+#ifdef BUILTIN_FAT
+#include <mach-o/fat.h>
+#endif /* BUILTIN_FAT */
+
+#ifdef S_IFLNK
+# define USAGE "Usage: %s [-vczL] [-f namefile] [-m magicfiles] file...\n"
+#else
+# define USAGE "Usage: %s [-vcz] [-f namefile] [-m magicfiles] file...\n"
+#endif
+
+#ifndef MAGIC
+# define MAGIC "/etc/magic"
+#endif
+
+int /* Global command-line options */
+ debug = 0, /* debugging */
+ lflag = 0, /* follow Symlinks (BSD only) */
+ zflag = 0; /* follow (uncompress) compressed files */
+
+int /* Misc globals */
+ nmagic = 0; /* number of valid magic[]s */
+
+struct magic *magic; /* array of magic entries */
+
+char *magicfile; /* where magic be found */
+
+char *progname; /* used throughout */
+int lineno; /* line number in the magic file */
+
+
+static void unwrap __P((char *fn));
+#if 0
+static int byteconv4 __P((int, int, int));
+static short byteconv2 __P((int, int, int));
+#endif
+
+/*
+ * main - parse arguments and handle options
+ */
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int c;
+ int check = 0, didsomefiles = 0, errflg = 0, ret = 0, app = 0;
+
+ if ((progname = strrchr(argv[0], '/')) != NULL)
+ progname++;
+ else
+ progname = argv[0];
+
+ if (!(magicfile = getenv("MAGIC")))
+ magicfile = MAGIC;
+
+ while ((c = getopt(argc, argv, "vcdf:Lm:z")) != -1)
+ switch (c) {
+ case 'v':
+ (void) fprintf(stdout, "%s-%d.%d\n", progname,
+ FILE_VERSION_MAJOR, patchlevel);
+ return 1;
+ case 'c':
+ ++check;
+ break;
+ case 'd':
+ ++debug;
+ break;
+ case 'f':
+ if (!app) {
+ ret = apprentice(magicfile, check);
+ if (check)
+ exit(ret);
+ app = 1;
+ }
+ unwrap(optarg);
+ ++didsomefiles;
+ break;
+#ifdef S_IFLNK
+ case 'L':
+ ++lflag;
+ break;
+#endif
+ case 'm':
+ magicfile = optarg;
+ break;
+ case 'z':
+ zflag++;
+ break;
+ case '?':
+ default:
+ errflg++;
+ break;
+ }
+
+ if (errflg) {
+ (void) fprintf(stderr, USAGE, progname);
+ exit(2);
+ }
+
+ if (!app) {
+ ret = apprentice(magicfile, check);
+ if (check)
+ exit(ret);
+ app = 1;
+ }
+
+ if (optind == argc) {
+ if (!didsomefiles) {
+ (void)fprintf(stderr, USAGE, progname);
+ exit(2);
+ }
+ }
+ else {
+ int i, wid, nw;
+ for (wid = 0, i = optind; i < argc; i++) {
+ nw = strlen(argv[i]);
+ if (nw > wid)
+ wid = nw;
+ }
+ for (; optind < argc; optind++)
+ process(argv[optind], wid);
+ }
+
+ return 0;
+}
+
+
+/*
+ * unwrap -- read a file of filenames, do each one.
+ */
+static void
+unwrap(fn)
+char *fn;
+{
+ char buf[MAXPATHLEN];
+ FILE *f;
+ int wid = 0, cwid;
+
+ if (strcmp("-", fn) == 0) {
+ f = stdin;
+ wid = 1;
+ } else {
+ if ((f = fopen(fn, "r")) == NULL) {
+ error("Cannot open `%s' (%s).\n", fn, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ cwid = strlen(buf) - 1;
+ if (cwid > wid)
+ wid = cwid;
+ }
+
+ rewind(f);
+ }
+
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ buf[strlen(buf)-1] = '\0';
+ process(buf, wid);
+ }
+
+ (void) fclose(f);
+}
+
+
+#if 0
+/*
+ * byteconv4
+ * Input:
+ * from 4 byte quantity to convert
+ * same whether to perform byte swapping
+ * big_endian whether we are a big endian host
+ */
+static int
+byteconv4(from, same, big_endian)
+ int from;
+ int same;
+ int big_endian;
+{
+ if (same)
+ return from;
+ else if (big_endian) /* lsb -> msb conversion on msb */
+ {
+ union {
+ int i;
+ char c[4];
+ } retval, tmpval;
+
+ tmpval.i = from;
+ retval.c[0] = tmpval.c[3];
+ retval.c[1] = tmpval.c[2];
+ retval.c[2] = tmpval.c[1];
+ retval.c[3] = tmpval.c[0];
+
+ return retval.i;
+ }
+ else
+ return ntohl(from); /* msb -> lsb conversion on lsb */
+}
+
+/*
+ * byteconv2
+ * Same as byteconv4, but for shorts
+ */
+static short
+byteconv2(from, same, big_endian)
+ int from;
+ int same;
+ int big_endian;
+{
+ if (same)
+ return from;
+ else if (big_endian) /* lsb -> msb conversion on msb */
+ {
+ union {
+ short s;
+ char c[2];
+ } retval, tmpval;
+
+ tmpval.s = (short) from;
+ retval.c[0] = tmpval.c[1];
+ retval.c[1] = tmpval.c[0];
+
+ return retval.s;
+ }
+ else
+ return ntohs(from); /* msb -> lsb conversion on lsb */
+}
+#endif
+
+/*
+ * process - process input file
+ */
+void
+process(inname, wid)
+const char *inname;
+int wid;
+{
+ int fd = 0;
+ static const char stdname[] = "standard input";
+ unsigned char buf[HOWMANY+1]; /* one extra for terminating '\0' */
+ struct stat sb;
+ int nbytes = 0; /* number of bytes read from a datafile */
+ char match = '\0';
+#ifdef BUILTIN_FAT
+ unsigned magic;
+#endif /* BUILTIN_FAT */
+
+ if (strcmp("-", inname) == 0) {
+ if (fstat(0, &sb)<0) {
+ error("cannot fstat `%s' (%s).\n", stdname,
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+ inname = stdname;
+ }
+
+ if (wid > 0)
+ (void) printf("%s:%*s ", inname,
+ (int) (wid - strlen(inname)), "");
+
+ if (inname != stdname) {
+ /*
+ * first try judging the file based on its filesystem status
+ */
+ if (fsmagic(inname, &sb) != 0) {
+ putchar('\n');
+ return;
+ }
+
+ if ((fd = open(inname, O_RDONLY)) < 0) {
+ /* We can't open it, but we were able to stat it. */
+ if (sb.st_mode & 0002) ckfputs("writeable, ", stdout);
+ if (sb.st_mode & 0111) ckfputs("executable, ", stdout);
+ ckfprintf(stdout, "can't read `%s' (%s).\n",
+ inname, strerror(errno));
+ return;
+ }
+ }
+
+
+ /*
+ * try looking at the first HOWMANY bytes
+ */
+ if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) {
+ error("read failed (%s).\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ if (nbytes == 0)
+ ckfputs("empty", stdout);
+ else {
+ buf[nbytes++] = '\0'; /* null-terminate it */
+ match = tryit(buf, nbytes, zflag);
+ }
+
+#ifdef BUILTIN_ELF
+ if (match == 's' && nbytes > 5)
+ tryelf(fd, buf, nbytes);
+#endif
+
+ if (inname != stdname) {
+#ifdef RESTORE_TIME
+ /*
+ * Try to restore access, modification times if read it.
+ */
+# 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
+
+#ifdef BUILTIN_FAT
+ memcpy(&magic, buf, sizeof(unsigned long));
+#ifdef __BIG_ENDIAN__
+ if(nbytes >= sizeof(unsigned long) && magic == FAT_MAGIC)
+#endif /* __BIG_ENDIAN__ */
+#ifdef __LITTLE_ENDIAN__
+ if(nbytes >= sizeof(unsigned long) && magic == FAT_CIGAM)
+#endif /* __LITTLE_ENDIAN__ */
+ tryfat(inname, fd, (char *)buf, nbytes);
+#endif /* BUILTIN_FAT */
+
+ (void) close(fd);
+ }
+ (void) putchar('\n');
+}
+
+
+int
+tryit(buf, nb, zflag)
+unsigned char *buf;
+int nb, zflag;
+{
+ /* try compression stuff */
+ if (zflag && zmagic(buf, nb))
+ return 'z';
+
+ /* try tests in /etc/magic (or surrogate magic file) */
+ if (softmagic(buf, nb))
+ return 's';
+
+ /* try known keywords, check whether it is ASCII */
+ if (ascmagic(buf, nb))
+ return 'a';
+
+ /* see if it's international language text */
+ if (internatmagic(buf, nb))
+ return 'i';
+
+ /* abandon hope, all ye who remain here */
+ ckfputs("data", stdout);
+ return '\0';
+}
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: file.h,v 1.3 1997/02/09 23:58:23 millert Exp $ */
+
+/*
+ * file.h - definitions for file(1) program
+ *
+ * Copyright (c) Ian F. Darwin, 1987.
+ * Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ */
+
+#ifndef __file_h__
+#define __file_h__
+
+typedef int32_t int32;
+typedef u_int32_t uint32;
+
+#ifndef HOWMANY
+# define HOWMANY 8192 /* how much of the file to look at */
+#endif
+#define MAXMAGIS 1000 /* max entries in /etc/magic */
+#define MAXDESC 50 /* max leng of text description */
+#define MAXstring 32 /* max leng of "string" types */
+
+struct magic {
+ short flag;
+#define INDIR 1 /* if '>(...)' appears, */
+#define UNSIGNED 2 /* comparison is unsigned */
+#define ADD 4 /* if '>&' appears, */
+ short cont_level; /* level of ">" */
+ struct {
+ char type; /* byte short long */
+ int32 offset; /* offset from indirection */
+ } in;
+ 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 */
+#define BYTE 1
+#define SHORT 2
+#define LONG 4
+#define STRING 5
+#define DATE 6
+#define BESHORT 7
+#define BELONG 8
+#define BEDATE 9
+#define LESHORT 10
+#define LELONG 11
+#define LEDATE 12
+ union VALUETYPE {
+ unsigned char b;
+ unsigned short h;
+ 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 */
+ uint32 mask; /* mask before comparison with value */
+ char nospflag; /* supress space character */
+ char desc[MAXDESC]; /* description */
+};
+
+#include <stdio.h> /* Include that here, to make sure __P gets defined */
+
+#ifndef __P
+# if __STDC__ || __cplusplus
+# define __P(a) a
+# else
+# define __P(a) ()
+# define const
+# endif
+#endif
+
+extern int apprentice __P((char *, int));
+extern int ascmagic __P((unsigned char *, int));
+extern void error __P((const char *, ...));
+extern void ckfputs __P((const char *, FILE *));
+struct stat;
+extern int fsmagic __P((const char *, struct stat *));
+extern int is_compress __P((const unsigned char *, int *));
+extern int is_tar __P((unsigned char *, int));
+extern void magwarn __P((const char *, ...));
+extern void mdump __P((struct magic *));
+extern void process __P((const char *, int));
+extern void showstr __P((FILE *, const char *, int));
+extern int softmagic __P((unsigned char *, int));
+extern int tryit __P((unsigned char *, int, int));
+extern int zmagic __P((unsigned char *, int));
+extern void ckfprintf __P((FILE *, const char *, ...));
+extern uint32 signextend __P((struct magic *, unsigned int32));
+extern int internatmagic __P((unsigned char *, int));
+extern void tryelf __P((int, char *, int));
+extern void tryfat __P((const char *, int, char *, int));
+
+
+extern int errno; /* Some unixes don't define this.. */
+
+extern char *progname; /* the program name */
+extern char *magicfile; /* name of the magic file */
+extern int lineno; /* current line number in magic file */
+
+extern struct magic *magic; /* array of magic entries */
+extern int nmagic; /* number of valid magic[]s */
+
+
+extern int debug; /* enable debugging? */
+extern int zflag; /* process compressed files? */
+extern int lflag; /* follow symbolic links? */
+
+extern int optind; /* From getopt(3) */
+extern char *optarg;
+
+#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) \
+ (((e) >= 0 && (e) < sys_nerr) ? sys_errlist[(e)] : "Unknown error")
+#define strtoul(a, b, c) strtol(a, b, c)
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 512
+#endif
+
+#endif /* __file_h__ */
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: fsmagic.c,v 1.3 1997/02/09 23:58:24 millert Exp $ */
+
+/*
+ * fsmagic - magic based on filesystem info - directory, special files, etc.
+ *
+ * Copyright (c) Ian F. Darwin, 1987.
+ * Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifndef major
+# if defined(__SVR4) || defined(_SVR4_SOURCE)
+# include <sys/mkdev.h>
+# endif
+#endif
+#ifndef major /* if `major' not defined in types.h, */
+#include <sys/sysmacros.h> /* try this one. */
+#endif
+#ifndef major /* still not defined? give up, manual intervention needed */
+ /* If cc tries to compile this, read and act on it. */
+ /* On most systems cpp will discard it automatically */
+ Congratulations, you have found a portability bug.
+ Please grep /usr/include/sys and edit the above #include
+ to point at the file that defines the "major" macro.
+#endif /*major*/
+
+#include "file.h"
+
+#ifndef lint
+#if 0
+static char *moduleid = "$OpenBSD: fsmagic.c,v 1.3 1997/02/09 23:58:24 millert Exp $";
+#endif
+#endif /* lint */
+
+int
+fsmagic(fn, sb)
+const char *fn;
+struct stat *sb;
+{
+ int ret = 0;
+
+ /*
+ * Fstat is cheaper but fails for files you don't have read perms on.
+ * On 4.2BSD and similar systems, use lstat() to identify symlinks.
+ */
+#ifdef S_IFLNK
+ if (!lflag)
+ ret = lstat(fn, sb);
+ else
+#endif
+ ret = stat(fn, sb); /* don't merge into if; see "ret =" above */
+
+ if (ret) {
+ ckfprintf(stdout,
+ /* Yes, I do mean stdout. */
+ /* No \n, caller will provide. */
+ "can't stat `%s' (%s).", fn, strerror(errno));
+ return 1;
+ }
+
+ if (sb->st_mode & S_ISUID) ckfputs("setuid ", stdout);
+ if (sb->st_mode & S_ISGID) ckfputs("setgid ", stdout);
+ if (sb->st_mode & S_ISVTX) ckfputs("sticky ", stdout);
+
+ switch (sb->st_mode & S_IFMT) {
+ case S_IFDIR:
+ ckfputs("directory", stdout);
+ return 1;
+ case S_IFCHR:
+ (void) printf("character special (%ld/%ld)",
+ (long) major(sb->st_rdev), (long) minor(sb->st_rdev));
+ return 1;
+ case S_IFBLK:
+ (void) printf("block special (%ld/%ld)",
+ (long) major(sb->st_rdev), (long) minor(sb->st_rdev));
+ return 1;
+ /* TODO add code to handle V7 MUX and Blit MUX files */
+#ifdef S_IFIFO
+ case S_IFIFO:
+ ckfputs("fifo (named pipe)", stdout);
+ return 1;
+#endif
+#ifdef S_IFLNK
+ case S_IFLNK:
+ {
+ char buf[BUFSIZ+4];
+ register int nch;
+ struct stat tstatbuf;
+
+ if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) {
+ ckfprintf(stdout, "unreadable symlink (%s).",
+ strerror(errno));
+ return 1;
+ }
+ buf[nch] = '\0'; /* readlink(2) forgets this */
+
+ /* If broken symlink, say so and quit early. */
+ if (*buf == '/') {
+ if (stat(buf, &tstatbuf) < 0) {
+ ckfprintf(stdout,
+ "broken symbolic link to %s", buf);
+ return 1;
+ }
+ }
+ else {
+ char *tmp;
+ char buf2[BUFSIZ+BUFSIZ+4];
+
+ if ((tmp = strrchr(fn, '/')) == NULL) {
+ tmp = buf; /* in current directory anyway */
+ }
+ else {
+ strcpy (buf2, fn); /* take directory part */
+ buf2[tmp-fn+1] = '\0';
+ strcat (buf2, buf); /* plus (relative) symlink */
+ tmp = buf2;
+ }
+ if (stat(tmp, &tstatbuf) < 0) {
+ ckfprintf(stdout,
+ "broken symbolic link to %s", buf);
+ return 1;
+ }
+ }
+
+ /* Otherwise, handle it. */
+ if (lflag) {
+ process(buf, strlen(buf));
+ return 1;
+ } else { /* just print what it points to */
+ ckfputs("symbolic link to ", stdout);
+ ckfputs(buf, stdout);
+ }
+ }
+ return 1;
+#endif
+#ifdef S_IFSOCK
+#ifndef __COHERENT__
+ case S_IFSOCK:
+ ckfputs("socket", stdout);
+ return 1;
+#endif
+#endif
+ case S_IFREG:
+ break;
+ default:
+ error("invalid mode 0%o.\n", sb->st_mode);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * regular file, check next possibility
+ */
+ if (sb->st_size == 0) {
+ ckfputs("empty", stdout);
+ return 1;
+ }
+ return 0;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: internat.c,v 1.1 1997/02/09 23:58:26 millert Exp $ */
+
+#include <string.h>
+#include <sys/types.h>
+
+#include "file.h"
+
+#define F 0
+#define T 1
+
+/*
+ * List of characters that look "reasonable" in international
+ * language texts. That's almost all characters :), except a
+ * few in the control range of ASCII (all the known international
+ * charactersets share the bottom half with ASCII).
+ */
+static char maybe_internat[256] = {
+ F, F, F, F, F, F, F, F, T, T, T, T, T, T, F, F, /* 0x0X */
+ F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x3X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x4X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x5X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x6X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, /* 0x7X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x8X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x9X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0xaX */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0xbX */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0xcX */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0xdX */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0xeX */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T /* 0xfX */
+};
+
+/* Maximal length of a line we consider "reasonable". */
+#define MAXLINELEN 300
+
+int
+internatmagic(buf, nbytes)
+ unsigned char *buf;
+ int nbytes;
+{
+ int i;
+ unsigned char *cp;
+
+ nbytes--;
+
+ /* First, look whether there are "unreasonable" characters. */
+ for (i = 0, cp = buf; i < nbytes; i++, cp++)
+ if (!maybe_internat[*cp])
+ return 0;
+
+ /*
+ * Now, look whether the file consists of lines of
+ * "reasonable" length.
+ */
+
+ for (i = 0; i < nbytes;) {
+ cp = memchr(buf, '\n', nbytes - i);
+ if (cp == NULL) {
+ /* Don't fail if we hit the end of buffer. */
+ if (i + MAXLINELEN >= nbytes)
+ break;
+ else
+ return 0;
+ }
+ if (cp - buf > MAXLINELEN)
+ return 0;
+ i += (cp - buf + 1);
+ buf = cp + 1;
+ }
+ ckfputs("International language text", stdout);
+ return 1;
+}
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: is_tar.c,v 1.3 1997/02/09 23:58:27 millert Exp $ */
+
+/*
+ * is_tar() -- figure out whether file is a tar archive.
+ *
+ * Stolen (by the author!) from the public domain tar program:
+ * Pubic Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
+ *
+ * @(#)list.c 1.18 9/23/86 Public Domain - gnu
+ *
+ * Comments changed and some code/comments reformatted
+ * for file command by Ian Darwin.
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include "tar.h"
+
+#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
+
+#if defined(__STDC__) || defined(__cplusplus)
+static int from_oct(int, char*); /* Decode octal number */
+#else
+static int from_oct();
+#endif
+
+/*
+ * Return
+ * 0 if the checksum is bad (i.e., probably not a tar archive),
+ * 1 for old UNIX tar file,
+ * 2 for Unix Std (POSIX) tar file.
+ */
+int
+is_tar(buf, nbytes)
+unsigned char *buf;
+int nbytes;
+{
+ register union record *header = (union record *)buf;
+ register int i;
+ register int sum, recsum;
+ register char *p;
+
+ if (nbytes < sizeof(union record))
+ return 0;
+
+ recsum = from_oct(8, header->header.chksum);
+
+ sum = 0;
+ p = header->charptr;
+ for (i = sizeof(union record); --i >= 0;) {
+ /*
+ * We can't use unsigned char here because of old compilers,
+ * e.g. V7.
+ */
+ sum += 0xFF & *p++;
+ }
+
+ /* Adjust checksum to count the "chksum" field as blanks. */
+ for (i = sizeof(header->header.chksum); --i >= 0;)
+ sum -= 0xFF & header->header.chksum[i];
+ sum += ' '* sizeof header->header.chksum;
+
+ if (sum != recsum)
+ return 0; /* Not a tar archive */
+
+ if (0==strcmp(header->header.magic, TMAGIC))
+ return 2; /* Unix Standard tar archive */
+
+ return 1; /* Old fashioned tar archive */
+}
+
+
+/*
+ * Quick and dirty octal conversion.
+ *
+ * Result is -1 if the field is invalid (all blank, or nonoctal).
+ */
+static int
+from_oct(digs, where)
+ register int digs;
+ register char *where;
+{
+ register int value;
+
+ while (isspace(*where)) { /* Skip spaces */
+ where++;
+ if (--digs <= 0)
+ return -1; /* All blank field */
+ }
+ value = 0;
+ while (digs > 0 && isodigit(*where)) { /* Scan til nonoctal */
+ value = (value << 3) | (*where++ - '0');
+ --digs;
+ }
+
+ if (digs > 0 && *where && !isspace(*where))
+ return -1; /* Ended on non-space/nul */
+
+ return value;
+}
--- /dev/null
+
+#------------------------------------------------------------------------------
+# 386bsd: file(1) magic for 386BSD objects
+#
+0 lelong 000000413 386BSD demand paged executable
+>16 lelong >0 not stripped
--- /dev/null
+#! file
+# $OpenBSD: Header,v 1.2 1996/06/26 05:33:03 deraadt Exp $
+
+# Magic data for file(1) command.
+# Machine-genererated from src/cmd/file/magdir/*; edit there only!
+# Format is described in magic(files), where:
+# files is 4 on V7 and BSD, 4 on SV, and ?? in the SVID.
--- /dev/null
+#------------------------------------------------------------------------------
+# Localstuff: file(1) magic for locally observed files
+#
+# $OpenBSD: Localstuff,v 1.3 1997/02/09 23:58:40 millert Exp $
+# Add any locally observed files here. Remember:
+# text if readable, executable if runnable binary, data if unreadable.
--- /dev/null
+
+#------------------------------------------------------------------------------
+# OpenBSD: file(1) magic for OpenBSD objects
+#
+# All new-style magic numbers are in network byte order.
+#
+
+0 lelong 000000407 OpenBSD little-endian object file
+>16 lelong >0 not stripped
+0 belong 000000407 OpenBSD big-endian object file
+>16 belong >0 not stripped
+
+0 belong&0377777777 041400413 OpenBSD/i386 demand paged
+>0 byte &0x80
+>>20 lelong <4096 shared library
+>>20 lelong =4096 dynamically linked executable
+>>20 lelong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 041400410 OpenBSD/i386 pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 041400407 OpenBSD/i386
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 041400507 OpenBSD/i386 core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 041600413 OpenBSD/m68k demand paged
+>0 byte &0x80
+>>20 belong <8192 shared library
+>>20 belong =8192 dynamically linked executable
+>>20 belong >8192 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 041600410 OpenBSD/m68k pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 041600407 OpenBSD/m68k
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 belong !0 executable
+>>20 belong =0 object file
+>16 belong >0 not stripped
+0 belong&0377777777 041600507 OpenBSD/m68k core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 042000413 OpenBSD/m68k4k demand paged
+>0 byte &0x80
+>>20 belong <4096 shared library
+>>20 belong =4096 dynamically linked executable
+>>20 belong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 042000410 OpenBSD/m68k4k pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 042000407 OpenBSD/m68k4k
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 belong !0 executable
+>>20 belong =0 object file
+>16 belong >0 not stripped
+0 belong&0377777777 042000507 OpenBSD/m68k4k core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 042200413 OpenBSD/ns32532 demand paged
+>0 byte &0x80
+>>20 lelong <4096 shared library
+>>20 lelong =4096 dynamically linked executable
+>>20 lelong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 042200410 OpenBSD/ns32532 pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 042200407 OpenBSD/ns32532
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 042200507 OpenBSD/ns32532 core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 042400413 OpenBSD/sparc demand paged
+>0 byte &0x80
+>>20 belong <8192 shared library
+>>20 belong =8192 dynamically linked executable
+>>20 belong >8192 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 042400410 OpenBSD/sparc pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 042400407 OpenBSD/sparc
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 belong !0 executable
+>>20 belong =0 object file
+>16 belong >0 not stripped
+0 belong&0377777777 042400507 OpenBSD/sparc core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 042600413 OpenBSD/pmax demand paged
+>0 byte &0x80
+>>20 lelong <4096 shared library
+>>20 lelong =4096 dynamically linked executable
+>>20 lelong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 042600410 OpenBSD/pmax pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 042600407 OpenBSD/pmax
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 042600507 OpenBSD/pmax core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 043000413 OpenBSD/vax demand paged
+>0 byte &0x80
+>>20 lelong <4096 shared library
+>>20 lelong =4096 dynamically linked executable
+>>20 lelong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 043000410 OpenBSD/vax pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 043000407 OpenBSD/vax
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 043000507 OpenBSD/vax core
+>12 string >\0 from '%s'
+
+# OpenBSD/alpha does not support (and has never supported) a.out objects,
+# so no rules are provided for them. OpenBSD/alpha ELF objects are
+# dealt with in "elf".
+0 leshort 0x00070185 ECOFF OpenBSD/alpha binary
+>10 leshort 0x0001 not stripped
+>10 leshort 0x0000 stripped
+0 belong&0377777777 043200507 OpenBSD/alpha core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 043400413 OpenBSD/mips demand paged
+>0 byte &0x80
+>>20 belong <8192 shared library
+>>20 belong =8192 dynamically linked executable
+>>20 belong >8192 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 043400410 OpenBSD/mips pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 043400407 OpenBSD/mips
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 belong !0 executable
+>>20 belong =0 object file
+>16 belong >0 not stripped
+0 belong&0377777777 043400507 OpenBSD/mips core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 043600413 OpenBSD/arm32 demand paged
+>0 byte &0x80
+>>20 lelong <8192 shared library
+>>20 lelong =8192 dynamically linked executable
+>>20 lelong >8192 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 043600410 OpenBSD/arm32 pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 043600407 OpenBSD/arm32
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 043600507 OpenBSD/arm32 core
+>12 string >\0 from '%s'
--- /dev/null
+
+#------------------------------------------------------------------------------
+# adventure: file(1) magic for Adventure game files
+#
+# from Allen Garvin <earendil@faeryland.tamu-commerce.edu>
+# Edited by Dave Chapeskie <dchapes@ddm.on.ca> Jun 28, 1998
+#
+# ALAN
+# I assume there are other, lower versions, but these are the only ones I
+# saw in the archive.
+0 beshort 0x0206 ALAN text adventure code data
+>2 byte <10 version 2.6%d
+
+# Conflicts with too much other stuff!
+# Infocom
+# (Note: to avoid false matches Z-machine version 1 and 2 are not
+# recognized since only the oldest Zork I and II used them. Similarly
+# there are 4 Infocom games that use verion 4 that are not recognized.)
+#0 byte 3 Infocom game data (Z-machine 3,
+#>2 beshort <0x7fff Release %3d,
+#>26 beshort >0 Size %d*2
+#>18 string >\0 Serial %.6s)
+#0 byte 5 Infocom game data (Z-machine 5,
+#>2 beshort <0x7fff Release %3d,
+#>26 beshort >0 Size %d*4
+#>18 string >\0 Serial %.6s)
+#0 byte 6 Infocom game data (Z-machine 6,
+#>2 beshort <0x7fff Release %3d,
+#>26 beshort >0 Size %d*8
+#>18 string >\0 Serial %.6s)
+#0 byte 8 Infocom game data (Z-machine 8,
+#>2 beshort <0x7fff Release %3d,
+#>26 beshort >0 Size %d*8
+#>18 string >\0 Serial %.6s)
+
+# TADS (Text Adventure Development System)
+0 string TADS TADS game data
+>13 string >\0 (ver. %.6s,
+>22 string >\0 date %s)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# alliant: file(1) magic for Alliant FX series a.out files
+#
+# If the FX series is the one that had a processor with a 68K-derived
+# instruction set, the "short" should probably become "beshort" and the
+# "long" should probably become "belong".
+# If it's the i860-based one, they should probably become either the
+# big-endian or little-endian versions, depending on the mode they ran
+# the 860 in....
+#
+0 short 0420 0420 Alliant virtual executable
+>2 short &0x0020 common library
+>16 long >0 not stripped
+0 short 0421 0421 Alliant compact executable
+>2 short &0x0020 common library
+>16 long >0 not stripped
--- /dev/null
+#------------------------------------------------------------------------------
+# alpha architecture description
+#
+
+0 leshort 0603 COFF format alpha
+>22 leshort&030000 !020000 executable
+>24 leshort 0410 pure
+>24 leshort 0413 paged
+>22 leshort&020000 !0 dynamically linked
+>16 lelong !0 not stripped
+>16 lelong 0 stripped
+>22 leshort&030000 020000 shared library
+>24 leshort 0407 object
+>27 byte x - version %d
+>26 byte x \b.%d
+>28 byte x \b-%d
+
+# Basic recognition of Digital UNIX core dumps - Mike Bremford <mike@opac.bl.uk>
+#
+0 string Core\001 Alpha COFF format core dump (Digital UNIX)
+>24 string >\0 \b, from '%s'
--- /dev/null
+#------------------------------------------------------------------------------
+# amanda: file(1) magic for amanda file format
+#
+0 string AMANDA:\ TAPESTART\ DATE AMANDA dump header file,
+>23 string X
+>>25 string >\ Unused %s
+>23 string >\ DATE %s
--- /dev/null
+#------------------------------------------------------------------------------
+# amigaos: file(1) magic for AmigaOS binary formats:
+
+#
+# From ignatios@cs.uni-bonn.de (Ignatios Souvatzis)
+# Some formats are still missing: AmigaOS special IFF's, e.g.: FORM....CTLG
+# (the others should be seperate, anyway)
+#
+0 belong 0x000003f3 AmigaOS loadseg()ble executable/binary
+0 belong 0x000003e7 AmigaOS object/library data
--- /dev/null
+
+#------------------------------------------------------------------------------
+# animation: file(1) magic for animation/movie formats
+#
+# animation formats
+# MPEG, FLI, DL originally from vax@ccwf.cc.utexas.edu (VaX#n8)
+# FLC, SGI, Apple originally from Daniel Quinlan (quinlan@yggdrasil.com)
+
+# MPEG animation format
+0 string \000\000\001\263 MPEG file
+
+# FLI animation format
+4 leshort 0xAF11 FLI file
+>6 leshort x - %d frames,
+>8 leshort x width=%d pixels,
+>10 leshort x height=%d pixels,
+>12 leshort x depth=%d,
+>16 leshort x ticks/frame=%d
+# FLC animation format
+4 leshort 0xAF12 FLC file
+>6 leshort x - %d frames
+>8 leshort x width=%d pixels,
+>10 leshort x height=%d pixels,
+>12 leshort x depth=%d,
+>16 leshort x ticks/frame=%d
+
+# DL animation format
+# XXX - collision with most `mips' magic
+#
+# I couldn't find a real magic number for these, however, this
+# -appears- to work. Note that it might catch other files, too, so be
+# careful!
+#
+# Note that title and author appear in the two 20-byte chunks
+# at decimal offsets 2 and 22, respectively, but they are XOR'ed with
+# 255 (hex FF)! The DL format is really bad.
+#
+#0 byte 1 DL version 1, medium format (160x100, 4 images/screen)
+#>42 byte x - %d screens,
+#>43 byte x %d commands
+#0 byte 2 DL version 2
+#>1 byte 1 - large format (320x200,1 image/screen),
+#>1 byte 2 - medium format (160x100,4 images/screen),
+#>1 byte >2 - unknown format,
+#>42 byte x %d screens,
+#>43 byte x %d commands
+# Based on empirical evidence, DL version 3 have several nulls following the
+# \003. Most of them start with non-null values at hex offset 0x34 or so.
+#0 string \3\0\0\0\0\0\0\0\0\0\0\0 DL version 3
+
+# SGI and Apple formats
+0 string MOVI Silicon Graphics movie file
+4 string moov Apple QuickTime movie file (moov)
+4 string mdat Apple QuickTime movie file (mdat)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# apl: file(1) magic for APL (see also "pdp" and "vax" for other APL
+# workspaces)
+#
+0 long 0100554 APL workspace (Ken's original?)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# apple: file(1) magic for Apple II file formats
+#
+0 string FiLeStArTfIlEsTaRt binscii (apple ][) text
+0 string \x0aGL Binary II (apple ][) data
+0 string \x76\xff Squeezed (apple ][) data
+0 string N\365F\351l\345 NuFile archive (apple ][) data
+# apple: PEF
+0 string Joy! PEF binary
--- /dev/null
+
+#------------------------------------------------------------------------------
+# applix: file(1) magic for Applixware
+# From: Peter Soos <sp@osb.hu>
+#
+0 string *BEGIN Applixware
+>7 string WORDS Words Document
+>7 string GRAPHICS Graphic
+>7 string RASTER Bitmap
+>7 string SPREADSHEETS Spreadsheet
+>7 string MACRO Macro
+>7 string BUILDER Builder Object
--- /dev/null
+
+#------------------------------------------------------------------------------
+# archive: file(1) magic for archive formats (see also "msdos" for self-
+# extracting compressed archives)
+#
+# cpio, ar, arc, arj, hpack, lha/lharc, rar, squish, uc2, zip, zoo, etc.
+# pre-POSIX "tar" archives are handled in the C code.
+
+# POSIX tar archives
+257 string ustar\0 POSIX tar archive
+257 string ustar\040\040\0 GNU tar archive
+
+# cpio archives
+#
+# Yes, the top two "cpio archive" formats *are* supposed to just be "short".
+# The idea is to indicate archives produced on machines with the same
+# byte order as the machine running "file" with "cpio archive", and
+# to indicate archives produced on machines with the opposite byte order
+# from the machine running "file" with "byte-swapped cpio archive".
+#
+# The SVR4 "cpio(4)" hints that there are additional formats, but they
+# are defined as "short"s; I think all the new formats are
+# character-header formats and thus are strings, not numbers.
+0 short 070707 cpio archive
+0 short 0143561 byte-swapped cpio archive
+0 string 070707 ASCII cpio archive (pre-SVR4 or odc)
+0 string 070701 ASCII cpio archive (SVR4 with no CRC)
+0 string 070702 ASCII cpio archive (SVR4 with CRC)
+
+# other archives
+0 long 0177555 very old archive
+0 short 0177555 very old PDP-11 archive
+0 long 0177545 old archive
+0 short 0177545 old PDP-11 archive
+0 long 0100554 apl workspace
+0 string =<ar> archive
+
+# MIPS archive (needs to go first)
+#
+0 string !<arch>\n__________E MIPS archive
+>20 string U with MIPS Ucode members
+>21 string L with MIPSEL members
+>21 string B with MIPSEB members
+>19 string L and an EL hash table
+>19 string B and an EB hash table
+>22 string X -- out of date
+
+0 string -h- Software Tools format archive text
+
+#
+# XXX - why are there multiple <ar> thingies? Note that 0x213c6172 is
+# "!<ar", so, for new-style (4.xBSD/SVR2andup) archives, we have:
+#
+# 0 string !<arch> current ar archive
+# 0 long 0x213c6172 archive file
+#
+# and for SVR1 archives, we have:
+#
+# 0 string \<ar> System V Release 1 ar archive
+# 0 string =<ar> archive
+#
+# XXX - did Aegis really store shared libraries, breakpointed modules,
+# and absolute code program modules in the same format as new-style
+# "ar" archives?
+#
+0 string !<arch> current ar archive
+>8 string __.SYMDEF random library
+>8 string debian-split part of multipart Debian package
+>8 string debian-binary Debian binary package
+>0 belong =65538 - pre SR9.5
+>0 belong =65539 - post SR9.5
+>0 beshort 2 - object archive
+>0 beshort 3 - shared library module
+>0 beshort 4 - debug break-pointed module
+>0 beshort 5 - absolute code program module
+0 string \<ar> System V Release 1 ar archive
+0 string =<ar> archive
+#
+# XXX - from "vax", which appears to collect a bunch of byte-swapped
+# thingies, to help you recognize VAX files on big-endian machines;
+# with "leshort", "lelong", and "string", that's no longer necessary....
+#
+0 belong 0x65ff0000 VAX 3.0 archive
+0 belong 0x3c61723e VAX 5.0 archive
+#
+0 long 0x213c6172 archive file
+0 lelong 0177555 very old VAX archive
+0 leshort 0177555 very old PDP-11 archive
+#
+# XXX - "pdp" claims that 0177545 can have an __.SYMDEF member and thus
+# be a random library (it said 0xff65 rather than 0177545).
+#
+0 lelong 0177545 old VAX archive
+>8 string __.SYMDEF random library
+0 leshort 0177545 old PDP-11 archive
+>8 string __.SYMDEF random library
+#
+# From "pdp" (but why a 4-byte quantity?)
+#
+0 lelong 0x39bed PDP-11 old archive
+0 lelong 0x39bee PDP-11 4.0 archive
+
+# ARC archiver, from Daniel Quinlan (quinlan@yggdrasil.com)
+#
+# The first byte is the magic (0x1a), byte 2 is the compression type for
+# the first file (0x01 through 0x09), and bytes 3 to 15 are the MS-DOS
+# filename of the first file (null terminated). Since some types collide
+# we only test some types on basis of frequency: 0x08 (83%), 0x09 (5%),
+# 0x02 (5%), 0x03 (3%), 0x04 (2%), 0x06 (2%). 0x01 collides with terminfo.
+0 lelong&0x8080ffff 0x0000081a ARC archive data, dynamic LZW
+0 lelong&0x8080ffff 0x0000091a ARC archive data, squashed
+0 lelong&0x8080ffff 0x0000021a ARC archive data, uncompressed
+0 lelong&0x8080ffff 0x0000031a ARC archive data, packed
+0 lelong&0x8080ffff 0x0000041a ARC archive data, squeezed
+0 lelong&0x8080ffff 0x0000061a ARC archive data, crunched
+
+# Acorn archive formats (Disaster prone simpleton, m91dps@ecs.ox.ac.uk)
+# I can't create either SPARK or ArcFS archives so I have not tested this stuff
+# [GRR: the original entries collide with ARC, above; replaced with combined
+# version (not tested)]
+#0 byte 0x1a RISC OS archive
+#>1 string archive (ArcFS format)
+0 string \032archive RISC OS archive (ArcFS format)
+
+# ARJ archiver (jason@jarthur.Claremont.EDU)
+0 leshort 0xea60 ARJ archive data
+>5 byte x \b, v%d,
+>8 byte &0x04 multi-volume,
+>8 byte &0x10 slash-switched,
+>8 byte &0x20 backup,
+>34 string x original name: %s,
+>7 byte 0 os: MS-DOS
+>7 byte 1 os: PRIMOS
+>7 byte 2 os: Unix
+>7 byte 3 os: Amiga
+>7 byte 4 os: Macintosh
+>7 byte 5 os: OS/2
+>7 byte 6 os: Apple ][ GS
+>7 byte 7 os: Atari ST
+>7 byte 8 os: NeXT
+>7 byte 9 os: VAX/VMS
+>3 byte >0 %d]
+
+# HA archiver (Greg Roelofs, newt@uchicago.edu)
+# This is a really bad format. A file containing HAWAII will match this...
+#0 string HA HA archive data,
+#>2 leshort =1 1 file,
+#>2 leshort >1 %u files,
+#>4 byte&0x0f =0 first is type CPY
+#>4 byte&0x0f =1 first is type ASC
+#>4 byte&0x0f =2 first is type HSC
+#>4 byte&0x0f =0x0e first is type DIR
+#>4 byte&0x0f =0x0f first is type SPECIAL
+
+# HPACK archiver (Peter Gutmann, pgut1@cs.aukuni.ac.nz)
+0 string HPAK HPACK archive data
+
+# JAM Archive volume format, by Dmitry.Kohmanyuk@UA.net
+0 string \351,\001JAM\ JAM archive,
+>7 string >\0 version %.4s
+>0x26 byte =0x27 -
+>>0x2b string >\0 label %.11s,
+>>0x27 lelong x serial %08x,
+>>0x36 string >\0 fstype %.8s
+
+# LHARC/LHA archiver (Greg Roelofs, newt@uchicago.edu)
+2 string -lh0- LHarc 1.x archive data [lh0]
+2 string -lh1- LHarc 1.x archive data [lh1]
+2 string -lz4- LHarc 1.x archive data [lz4]
+2 string -lz5- LHarc 1.x archive data [lz5]
+# [never seen any but the last; -lh4- reported in comp.compression:]
+2 string -lzs- LHa 2.x? archive data [lzs]
+2 string -lh - LHa 2.x? archive data [lh ]
+2 string -lhd- LHa 2.x? archive data [lhd]
+2 string -lh2- LHa 2.x? archive data [lh2]
+2 string -lh3- LHa 2.x? archive data [lh3]
+2 string -lh4- LHa (2.x) archive data [lh4]
+2 string -lh5- LHa (2.x) archive data [lh5]
+>20 byte x - header level %d
+
+# RAR archiver (Greg Roelofs, newt@uchicago.edu)
+0 string Rar! RAR archive data
+
+# SQUISH archiver (Greg Roelofs, newt@uchicago.edu)
+0 string SQSH squished archive data (Acorn RISCOS)
+
+# UC2 archiver (Greg Roelofs, newt@uchicago.edu)
+# I can't figure out the self-extracting form of these buggers...
+0 string UC2\x1a UC2 archive data
+
+# ZIP archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu)
+0 string PK\003\004 Zip archive data
+>4 byte 0x09 \b, at least v0.9 to extract
+>4 byte 0x0a \b, at least v1.0 to extract
+>4 byte 0x0b \b, at least v1.1 to extract
+>4 byte 0x14 \b, at least v2.0 to extract
+
+# Zoo archiver
+20 lelong 0xfdc4a7dc Zoo archive data
+>4 byte >48 \b, v%c.
+>>6 byte >47 \b%c
+>>>7 byte >47 \b%c
+>32 byte >0 \b, modify: v%d
+>>33 byte x \b.%d+
+>42 lelong 0xfdc4a7dc \b,
+>>70 byte >0 extract: v%d
+>>>71 byte x \b.%d+
+
+# Shell archives
+10 string #\ This\ is\ a\ shell\ archive shell archive text
--- /dev/null
+
+#------------------------------------------------------------------------------
+# asterix: file(1) magic for Aster*x; SunOS 5.5.1 gave the 4-character
+# strings as "long" - we assume they're just strings:
+# From: guy@netapp.com (Guy Harris)
+#
+0 string *STA Aster*x
+>7 string WORD Words Document
+>7 string GRAP Graphic
+>7 string SPRE Spreadsheet
+>7 string MACR Macro
+0 string 2278 Aster*x Version 2
+>29 byte 0x36 Words Document
+>29 byte 0x35 Graphic
+>29 byte 0x32 Spreadsheet
+>29 byte 0x38 Macro
+
--- /dev/null
+
+#------------------------------------------------------------------------------
+# att3b: file(1) magic for AT&T 3B machines
+#
+# The `versions' should be un-commented if they work for you.
+# (Was the problem just one of endianness?)
+#
+# 3B20
+#
+0 beshort 0550 3b20 COFF executable
+>12 belong >0 not stripped
+#>22 beshort >0 - version %ld
+0 beshort 0551 3b20 COFF executable (TV)
+>12 belong >0 not stripped
+#>22 beshort >0 - version %ld
+#
+# WE32K
+#
+0 beshort 0560 WE32000 COFF
+>18 beshort ^00000020 object
+>18 beshort &00000020 executable
+>12 belong >0 not stripped
+>18 beshort ^00010000 N/A on 3b2/300 w/paging
+>18 beshort &00020000 32100 required
+>18 beshort &00040000 and MAU hardware required
+>20 beshort 0407 (impure)
+>20 beshort 0410 (pure)
+>20 beshort 0413 (demand paged)
+>20 beshort 0443 (target shared library)
+>22 beshort >0 - version %ld
+0 beshort 0561 WE32000 COFF executable (TV)
+>12 belong >0 not stripped
+#>18 beshort &00020000 - 32100 required
+#>18 beshort &00040000 and MAU hardware required
+#>22 beshort >0 - version %ld
+#
+# core file for 3b2
+0 string \000\004\036\212\200 3b2 core file
+>364 string >\0 of '%s'
--- /dev/null
+
+#------------------------------------------------------------------------------
+# audio: file(1) magic for sound formats (see also "iff")
+#
+# Jan Nicolai Langfeldt (janl@ifi.uio.no), Dan Quinlan (quinlan@yggdrasil.com),
+# and others
+#
+
+# Sun/NeXT audio data
+0 string .snd Sun/NeXT audio data:
+>12 belong 1 8-bit ISDN u-law,
+>12 belong 2 8-bit linear PCM [REF-PCM],
+>12 belong 3 16-bit linear PCM,
+>12 belong 4 24-bit linear PCM,
+>12 belong 5 32-bit linear PCM,
+>12 belong 6 32-bit IEEE floating point,
+>12 belong 7 64-bit IEEE floating point,
+>12 belong 23 8-bit ISDN u-law compressed (CCITT G.721 ADPCM voice data encoding),
+>12 belong 24 compressed (8-bit G.722 ADPCM)
+>12 belong 25 compressed (3-bit G.723 ADPCM),
+>12 belong 26 compressed (5-bit G.723 ADPCM),
+>12 belong 27 8-bit A-law,
+>20 belong 1 mono,
+>20 belong 2 stereo,
+>20 belong 4 quad,
+>16 belong >0 %d Hz
+
+# DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format
+# that uses little-endian encoding and has a different magic number
+0 lelong 0x0064732E DEC audio data:
+>12 lelong 1 8-bit ISDN u-law,
+>12 lelong 2 8-bit linear PCM [REF-PCM],
+>12 lelong 3 16-bit linear PCM,
+>12 lelong 4 24-bit linear PCM,
+>12 lelong 5 32-bit linear PCM,
+>12 lelong 6 32-bit IEEE floating point,
+>12 lelong 7 64-bit IEEE floating point,
+>12 lelong 23 8-bit ISDN u-law compressed (CCITT G.721 ADPCM voice data encoding),
+>20 lelong 1 mono,
+>20 lelong 2 stereo,
+>20 lelong 4 quad,
+>16 lelong >0 %d Hz
+
+# Creative Labs AUDIO stuff
+0 string MThd Standard MIDI data
+>9 byte >0 (format %d)
+>11 byte >1 using %d channels
+0 string CTMF Creative Music (CMF) data
+0 string SBI SoundBlaster instrument data
+0 string Creative\ Voice\ File Creative Labs voice data
+# is this next line right? it came this way...
+>19 byte 0x1A
+>23 byte >0 - version %d
+>22 byte >0 \b.%d
+
+# first entry is also the string "NTRK"
+0 belong 0x4e54524b MultiTrack sound data
+>4 belong x - version %ld
+
+# Microsoft WAVE format (*.wav)
+0 string RIFF Microsoft RIFF
+>8 string WAVE \b, WAVE audio data
+>>34 leshort >0 \b, %d bit
+>>22 leshort =1 \b, mono
+>>22 leshort =2 \b, stereo
+>>22 leshort >2 \b, %d channels
+>>24 lelong >0 %d Hz
+# AVI == Audio Video Interleave
+>8 string AVI\ \b, AVI data
+
+# Extended MOD format (*.emd) (Greg Roelofs, newt@uchicago.edu); NOT TESTED
+# [based on posting 940824 by "Dirk/Elastik", husberg@lehtori.cc.tut.fi]
+0 string EMOD Extended MOD sound data,
+>4 byte&0xf0 x version %d
+>4 byte&0x0f x \b.%d,
+>45 byte x %d instruments
+>83 byte 0 (module)
+>83 byte 1 (song)
+
+# Real Audio (Magic .ra\0375)
+0 belong 0x2e7261fd realaudio sound file
+
+# MTM/669/FAR/S3M/ULT/XM format checking [Aaron Eppert, aeppert@dialin.ind.net]
+# Oct 31, 1995
+0 string MTM MultiTracker Module sound file
+0 string if Composer 669 Module sound data
+0 string FAR Module sound data
+0 string MAS_U ULT(imate) Module sound data
+0x2c string SCRM ScreamTracker III Module sound data
+0 string Extended Module Extended Module sound data
--- /dev/null
+
+#------------------------------------------------------------------------------
+# blit: file(1) magic for 68K Blit stuff as seen from 680x0 machine
+#
+# Note that this 0407 conflicts with several other a.out formats...
+#
+# XXX - should this be redone with "be" and "le", so that it works on
+# little-endian machines as well? If so, what's the deal with
+# "VAX-order" and "VAX-order2"?
+#
+#0 long 0407 68K Blit (standalone) executable
+#0 short 0407 VAX-order2 68K Blit (standalone) executable
+0 short 03401 VAX-order 68K Blit (standalone) executable
+0 long 0406 68k Blit mpx/mux executable
+0 short 0406 VAX-order2 68k Blit mpx/mux executable
+0 short 03001 VAX-order 68k Blit mpx/mux executable
+# Need more values for WE32 DMD executables.
+# Note that 0520 is the same as COFF
+#0 short 0520 tty630 layers executable
--- /dev/null
+
+#------------------------------------------------------------------------------
+# bsdi: file(1) magic for BSD/OS (from BSDI) objects
+#
+0 lelong 000000314 BSD/OS i386 compact demand paged executable
+>16 lelong >0 not stripped
+>32 byte 0x6a (uses shared libs)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# c-lang: file(1) magic for C programs (or REXX)
+#
+
+# XPM icons (Greg Roelofs, newt@uchicago.edu)
+# if you uncomment "/*" for C/REXX below, also uncomment this entry
+#0 string /*\ XPM\ */ X pixmap image data
+
+# this first will upset you if you're a PL/1 shop...
+# in which case rm it; ascmagic will catch real C programs
+#0 string /* C or REXX program text
+0 string // C++ program text
--- /dev/null
+
+#------------------------------------------------------------------------------
+# chi: file(1) magic for ChiWriter files
+#
+0 string \\1cw\ ChiWriter file
+>5 string >\0 version %s
+0 string \\1cw ChiWriter file
--- /dev/null
+#------------------------------------------------------------------------------
+# cisco: file(1) magic for cisco Systems routers
+#
+# Most cisco file-formats are covered by the generic elf code
+#
+# Microcode files are non-ELF, 0x8501 conflicts with NetBSD/alpha.
+0 belong&0xffffff00 0x85011400 cisco IOS microcode
+>7 string >\0 for '%s'
+0 belong&0xffffff00 0x8501cb00 cisco IOS experimental microcode
+>7 string >\0 for '%s'
--- /dev/null
+
+#------------------------------------------------------------------------------
+# clipper: file(1) magic for Intergraph (formerly Fairchild) Clipper.
+#
+# XXX - what byte order does the Clipper use?
+#
+# XXX - what's the "!" stuff:
+#
+# >18 short !074000,000000 C1 R1
+# >18 short !074000,004000 C2 R1
+# >18 short !074000,010000 C3 R1
+# >18 short !074000,074000 TEST
+#
+# I shall assume it's ANDing the field with the first value and
+# comparing it with the second, and rewrite it as:
+#
+# >18 short&074000 000000 C1 R1
+# >18 short&074000 004000 C2 R1
+# >18 short&074000 010000 C3 R1
+# >18 short&074000 074000 TEST
+#
+# as SVR3.1's "file" doesn't support anything of the "!074000,000000"
+# sort, nor does SunOS 4.x, so either it's something Intergraph added
+# in CLIX, or something AT&T added in SVR3.2 or later, or something
+# somebody else thought was a good idea; it's not documented in the
+# man page for this version of "magic", nor does it appear to be
+# implemented (at least not after I blew off the bogus code to turn
+# old-style "&"s into new-style "&"s, which just didn't work at all).
+#
+0 short 0575 CLIPPER COFF executable (VAX #)
+>20 short 0407 (impure)
+>20 short 0410 (5.2 compatible)
+>20 short 0411 (pure)
+>20 short 0413 (demand paged)
+>20 short 0443 (target shared library)
+>12 long >0 not stripped
+>22 short >0 - version %ld
+0 short 0577 CLIPPER COFF executable
+>18 short&074000 000000 C1 R1
+>18 short&074000 004000 C2 R1
+>18 short&074000 010000 C3 R1
+>18 short&074000 074000 TEST
+>20 short 0407 (impure)
+>20 short 0410 (pure)
+>20 short 0411 (separate I&D)
+>20 short 0413 (paged)
+>20 short 0443 (target shared library)
+>12 long >0 not stripped
+>22 short >0 - version %ld
+>48 long&01 01 alignment trap enabled
+>52 byte 1 -Ctnc
+>52 byte 2 -Ctsw
+>52 byte 3 -Ctpw
+>52 byte 4 -Ctcb
+>53 byte 1 -Cdnc
+>53 byte 2 -Cdsw
+>53 byte 3 -Cdpw
+>53 byte 4 -Cdcb
+>54 byte 1 -Csnc
+>54 byte 2 -Cssw
+>54 byte 3 -Cspw
+>54 byte 4 -Cscb
+4 string pipe CLIPPER instruction trace
+4 string prof CLIPPER instruction profile
--- /dev/null
+
+#------------------------------------------------------------------------------
+# commands: file(1) magic for various shells and interpreters
+#
+0 string :\ shell archive or commands for antique kernel text
+0 string #!/bin/sh Bourne shell script text
+0 string #!\ /bin/sh Bourne shell script text
+0 string #!/bin/csh C shell script text
+0 string #!\ /bin/csh C shell script text
+# korn shell magic, sent by George Wu, gwu@clyde.att.com
+0 string #!/bin/ksh Korn shell script text
+0 string #!\ /bin/ksh Korn shell script text
+0 string #!/bin/tcsh Tenex C shell script text
+0 string #!\ /bin/tcsh Tenex C shell script text
+0 string #!/usr/local/tcsh Tenex C shell script text
+0 string #!\ /usr/local/tcsh Tenex C shell script text
+0 string #!/usr/local/bin/tcsh Tenex C shell script text
+0 string #!\ /usr/local/bin/tcsh Tenex C shell script text
+#
+# zsh/ash/ae/nawk/gawk magic from cameron@cs.unsw.oz.au (Cameron Simpson)
+0 string #!/usr/local/bin/zsh Paul Falstad's zsh
+0 string #!\ /usr/local/bin/zsh Paul Falstad's zsh
+0 string #!/usr/local/bin/ash Neil Brown's ash
+0 string #!\ /usr/local/bin/ash Neil Brown's ash
+0 string #!/usr/local/bin/ae Neil Brown's ae
+0 string #!\ /usr/local/bin/ae Neil Brown's ae
+0 string #!/bin/nawk new awk script text
+0 string #!\ /bin/nawk new awk script text
+0 string #!/usr/bin/nawk new awk script text
+0 string #!\ /usr/bin/nawk new awk script text
+0 string #!/usr/local/bin/nawk new awk script text
+0 string #!\ /usr/local/bin/nawk new awk script text
+0 string #!/bin/gawk GNU awk script text
+0 string #!\ /bin/gawk GNU awk script text
+0 string #!/usr/bin/gawk GNU awk script text
+0 string #!\ /usr/bin/gawk GNU awk script text
+0 string #!/usr/local/bin/gawk GNU awk script text
+0 string #!\ /usr/local/bin/gawk GNU awk script text
+#
+0 string #!/bin/awk awk commands text
+0 string #!\ /bin/awk awk commands text
+0 string #!/usr/bin/awk awk commands text
+0 string #!\ /usr/bin/awk awk commands text
+0 string BEGIN awk commands text
+
+# For Larry Wall's perl language. The ``eval'' line recognizes an
+# outrageously clever hack for USG systems.
+# Keith Waclena <keith@cerberus.uchicago.edu>
+0 string #!/bin/perl perl commands text
+0 string #!\ /bin/perl perl commands text
+0 string eval\ "exec\ /bin/perl perl commands text
+0 string #!/usr/bin/perl perl commands text
+0 string #!\ /usr/bin/perl perl commands text
+0 string eval\ "exec\ /usr/bin/perl perl commands text
+0 string #!/usr/local/bin/perl perl commands text
+0 string #!\ /usr/local/bin/perl perl commands text
+0 string eval\ "exec\ /usr/local/bin/perl perl commands text
+
+# AT&T Bell Labs' Plan 9 shell
+0 string #!/bin/rc Plan 9 rc shell script text
+0 string #!\ /bin/rc Plan 9 rc shell script text
+
+# bash shell magic, from Peter Tobias (tobias@server.et-inf.fho-emden.de)
+0 string #!/bin/bash Bourne-Again shell script text
+0 string #!\ /bin/bash Bourne-Again shell script text
+0 string #!/usr/local/bin/bash Bourne-Again shell script text
+0 string #!\ /usr/local/bin/bash Bourne-Again shell script text
+
+# generic shell magic
+0 string #!\ / a
+>3 string >\0 %s script text
+0 string #!/ a
+>2 string >\0 %s script text
+0 string #!\ commands text
+>3 string >\0 for %s
--- /dev/null
+
+#------------------------------------------------------------------------------
+# compress: file(1) magic for pure-compression formats (no archives)
+#
+# compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, etc.
+#
+# Formats for various forms of compressed data
+# Formats for "compress" proper have been moved into "compress.c",
+# because it tries to uncompress it to figure out what's inside.
+
+# standard unix compress
+0 string \037\235 compress'd data
+>2 byte&0x80 >0 block compressed
+>2 byte&0x1f x %d bits
+
+# gzip (GNU zip, not to be confused with Info-ZIP or PKWARE zip archiver)
+0 string \037\213 gzip compressed data
+>2 byte <8 \b, reserved method,
+>2 byte 8 \b, deflated,
+>3 byte &0x01 ASCII,
+>3 byte &0x02 continuation,
+>3 byte &0x04 extra field,
+>3 byte &0x08 original filename,
+>3 byte &0x10 comment,
+>3 byte &0x20 encrypted,
+>4 ledate x last modified: %s,
+>8 byte 2 max compression,
+>8 byte 4 max speed,
+>9 byte =0x00 os: MS-DOS
+>9 byte =0x01 os: Amiga
+>9 byte =0x02 os: VMS
+>9 byte =0x03 os: Unix
+>9 byte =0x05 os: Atari
+>9 byte =0x06 os: OS/2
+>9 byte =0x07 os: MacOS
+>9 byte =0x0A os: Tops/20
+>9 byte =0x0B os: Win/32
+
+# packed data, Huffman (minimum redundancy) codes on a byte-by-byte basis
+0 string \037\036 packed data
+>2 belong >1 \b, %d characters originally
+>2 belong =1 \b, %d character originally
+#
+# This magic number is byte-order-independent. XXX - Does that mean this
+# is big-endian, little-endian, either, or that you can't tell?
+# this short is valid for SunOS
+0 short 017437 old packed data
+
+# XXX - why *two* entries for "compacted data", one of which is
+# byte-order independent, and one of which is byte-order dependent?
+#
+0 short 0x1fff compacted data
+# This string is valid for SunOS (BE) and a matching "short" is listed
+# in the Ultrix (LE) magic file.
+0 string \377\037 compacted data
+0 short 0145405 huf output
+
+# Squeeze and Crunch...
+# These numbers were gleaned from the Unix versions of the programs to
+# handle these formats. Note that I can only uncrunch, not crunch, and
+# I didn't have a crunched file handy, so the crunch number is untested.
+# Keith Waclena <keith@cerberus.uchicago.edu>
+0 leshort 0x76FF squeezed data (CP/M, DOS)
+0 leshort 0x76FE crunched data (CP/M, DOS)
+
+# Freeze
+0 string \037\237 frozen file 2.1
+0 string \037\236 frozen file 1.0 (or gzip 0.5)
+
+# SCO compress -H (LZH)
+0 string \037\240 SCO compress -H (LZH) data
+
+# European GSM 06.10 is a provisional standard for full-rate speech
+# transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse
+# excitation/long term prediction) coding at 13 kbit/s.
+#
+# There's only a magic nibble (4 bits); that nibble repeats every 33
+# bytes. This isn't suited for use, but maybe we can use it someday.
+#
+# This will cause very short GSM files to be declared as data and
+# mismatches to be declared as data too!
+#0 byte&0xF0 0xd0 data
+#>33 byte&0xF0 0xd0
+#>66 byte&0xF0 0xd0
+#>99 byte&0xF0 0xd0
+#>132 byte&0xF0 0xd0 GSM 06.10 compressed audio
+
+# Bzip from ulmo@Q.Net
+0 string BZ bzip compressed data,
+>2 byte x format v. %c,
+>3 byte x block size indicator %c
+
--- /dev/null
+#------------------------------------------------------------------------------
+# convex: file(1) magic for Convex boxes
+#
+# Convexes are big-endian.
+#
+# /*\
+# * Below are the magic numbers and tests added for Convex.
+# * Added at beginning, because they are expected to be used most.
+# \*/
+0 belong 0507 Convex old-style object
+>16 belong >0 not stripped
+0 belong 0513 Convex old-style demand paged executable
+>16 belong >0 not stripped
+0 belong 0515 Convex old-style pre-paged executable
+>16 belong >0 not stripped
+0 belong 0517 Convex old-style pre-paged, non-swapped executable
+>16 belong >0 not stripped
+0 belong 0x011257 Core file
+#
+# The following are a series of dump format magic numbers. Each one
+# corresponds to a drastically different dump format. The first on is
+# the original dump format on a 4.1 BSD or earlier file system. The
+# second marks the change between the 4.1 file system and the 4.2 file
+# system. The Third marks the changing of the block size from 1K
+# to 2K to be compatible with an IDC file system. The fourth indicates
+# a dump that is dependent on Convex Storage Manager, because data in
+# secondary storage is not physically contained within the dump.
+# The restore program uses these number to determine how the data is
+# to be extracted.
+#
+24 belong =60011 dump format, 4.1 BSD or earlier
+24 belong =60012 dump format, 4.2 or 4.3 BSD without IDC
+24 belong =60013 dump format, 4.2 or 4.3 BSD (IDC compatible)
+24 belong =60014 dump format, Convex Storage Manager by-reference dump
+#
+# what follows is a bunch of bit-mask checks on the flags field of the opthdr.
+# If there is no `=' sign, assume just checking for whether the bit is set?
+#
+0 belong 0601 Convex SOFF
+>88 belong&0x000f0000 =0x00000000 c1
+>88 belong &0x00010000 c2
+>88 belong &0x00020000 c2mp
+>88 belong &0x00040000 parallel
+>88 belong &0x00080000 intrinsic
+>88 belong &0x00000001 demand paged
+>88 belong &0x00000002 pre-paged
+>88 belong &0x00000004 non-swapped
+>88 belong &0x00000008 POSIX
+#
+>84 belong &0x80000000 executable
+>84 belong &0x40000000 object
+>84 belong&0x20000000 =0 not stripped
+>84 belong&0x18000000 =0x00000000 native fpmode
+>84 belong&0x18000000 =0x10000000 ieee fpmode
+>84 belong&0x18000000 =0x18000000 undefined fpmode
+#
+0 belong 0605 Convex SOFF core
+#
+0 belong 0607 Convex SOFF checkpoint
+>88 belong&0x000f0000 =0x00000000 c1
+>88 belong &0x00010000 c2
+>88 belong &0x00020000 c2mp
+>88 belong &0x00040000 parallel
+>88 belong &0x00080000 intrinsic
+>88 belong &0x00000008 POSIX
+#
+>84 belong&0x18000000 =0x00000000 native fpmode
+>84 belong&0x18000000 =0x10000000 ieee fpmode
+>84 belong&0x18000000 =0x18000000 undefined fpmode
--- /dev/null
+
+#------------------------------------------------------------------------------
+# database: file(1) magic for various databases
+#
+# extracted from header/code files by Graeme Wilford (eep2gw@ee.surrey.ac.uk)
+#
+#
+# GDBM magic numbers
+# Will be maintained as part of the GDBM distribution in the future.
+# <downsj@teeny.org>
+0 belong 0x13579ace GNU dbm 1.x or ndbm database, big endian
+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 Hash file
+>4 belong >0 (Version %d,
+>8 belong 1234 Little Endian,
+>8 belong 4321 Big Endian,
+>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)
+#
+#
+0 belong 0x053162 Berkeley DB Btree file
+>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)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# diamond: file(1) magic for Diamond system
+#
+# ... diamond is a multi-media mail and electronic conferencing system....
+#
+# XXX - I think it was either renamed Slate, or replaced by Slate....
+#
+# The full deal is too long...
+#0 string <list>\n<protocol\ bbn-multimedia-format> Diamond Multimedia Document
+0 string =<list>\n<protocol\ bbn-m Diamond Multimedia Document
--- /dev/null
+
+#------------------------------------------------------------------------------
+# diff: file(1) magic for diff(1) output
+#
+0 string diff\ 'diff' output text
+0 string ***\ 'diff' output text
+0 string Only\ in\ 'diff' output text
+0 string Common\ subdirectories:\ 'diff' output text
--- /dev/null
+# Digital UNIX - Info
+#
+0 string !<arch>\n________64E Alpha archive
+>22 string X -- out of date
+#
+# Alpha COFF Based Executables
+# The stripped stuff really needs to be an 8 byte (64 bit) compare,
+# but this works
+0 leshort 0x183 COFF format alpha
+>22 leshort&020000 &010000 sharable library,
+>22 leshort&020000 ^010000 dynamically linked,
+>24 leshort 0410 pure
+>24 leshort 0413 demand paged
+>8 lelong >0 executable or object module, not stripped
+>8 lelong 0
+>>12 lelong 0 executable or object module, stripped
+>>12 lelong >0 executable or object module, not stripped
+>27 byte >0 - version %d.
+>26 byte >0 %d-
+>28 leshort >0 %d
+#
+# The next is incomplete, we could tell more about this format,
+# but its not worth it.
+0 leshort 0x188 Alpha compressed COFF
+0 leshort 0x18f Alpha u-code object
+#
+#
+# Some other interesting Digital formats,
+0 string \377\377\177 ddis/ddif
+0 string \377\377\174 ddis/dots archive
+0 string \377\377\176 ddis/dtif table data
+0 string \033c\033 LN03 output
+0 long 04553207 X image
+#
+0 string !<PDF>!\n profiling data file
+#
+# Locale data tables (MIPS and Alpha).
+#
+0 short 0x0501 locale data table
+>6 short 0x24 for MIPS
+>6 short 0x40 for Alpha
--- /dev/null
+
+#------------------------------------------------------------------------------
+# dump: file(1) magic for dump file format--for new and old dump filesystems
+#
+# We specify both byte orders in order to recognize byte-swapped dumps.
+#
+24 belong 60012 new-fs dump file (big endian),
+>4 bedate x Previous dump %s,
+>8 bedate x This dump %s,
+>12 belong >0 Volume %ld,
+>692 belong 0 Level zero, type:
+>692 belong >0 Level %d, type:
+>0 belong 1 tape header,
+>0 belong 2 beginning of file record,
+>0 belong 3 map of inodes on tape,
+>0 belong 4 continuation of file record,
+>0 belong 5 end of volume,
+>0 belong 6 map of inodes deleted,
+>0 belong 7 end of medium (for floppy),
+>676 string >\0 Label %s,
+>696 string >\0 Filesystem %s,
+>760 string >\0 Device %s,
+>824 string >\0 Host %s,
+>888 belong >0 Flags %x
+
+24 belong 60011 old-fs dump file (big endian),
+#>4 bedate x Previous dump %s,
+#>8 bedate x This dump %s,
+>12 belong >0 Volume %ld,
+>692 belong 0 Level zero, type:
+>692 belong >0 Level %d, type:
+>0 belong 1 tape header,
+>0 belong 2 beginning of file record,
+>0 belong 3 map of inodes on tape,
+>0 belong 4 continuation of file record,
+>0 belong 5 end of volume,
+>0 belong 6 map of inodes deleted,
+>0 belong 7 end of medium (for floppy),
+>676 string >\0 Label %s,
+>696 string >\0 Filesystem %s,
+>760 string >\0 Device %s,
+>824 string >\0 Host %s,
+>888 belong >0 Flags %x
+
+24 lelong 60012 new-fs dump file (little endian),
+>4 ledate x This dump %s,
+>8 ledate x Previous dump %s,
+>12 lelong >0 Volume %ld,
+>692 lelong 0 Level zero, type:
+>692 lelong >0 Level %d, type:
+>0 lelong 1 tape header,
+>0 lelong 2 beginning of file record,
+>0 lelong 3 map of inodes on tape,
+>0 lelong 4 continuation of file record,
+>0 lelong 5 end of volume,
+>0 lelong 6 map of inodes deleted,
+>0 lelong 7 end of medium (for floppy),
+>676 string >\0 Label %s,
+>696 string >\0 Filesystem %s,
+>760 string >\0 Device %s,
+>824 string >\0 Host %s,
+>888 lelong >0 Flags %x
+
+24 lelong 60011 old-fs dump file (little endian),
+#>4 ledate x Previous dump %s,
+#>8 ledate x This dump %s,
+>12 lelong >0 Volume %ld,
+>692 lelong 0 Level zero, type:
+>692 lelong >0 Level %d, type:
+>0 lelong 1 tape header,
+>0 lelong 2 beginning of file record,
+>0 lelong 3 map of inodes on tape,
+>0 lelong 4 continuation of file record,
+>0 lelong 5 end of volume,
+>0 lelong 6 map of inodes deleted,
+>0 lelong 7 end of medium (for floppy),
+>676 string >\0 Label %s,
+>696 string >\0 Filesystem %s,
+>760 string >\0 Device %s,
+>824 string >\0 Host %s,
+>888 lelong >0 Flags %x
--- /dev/null
+
+#------------------------------------------------------------------------------
+# elf: file(1) magic for ELF executables
+#
+# We have to check the byte order flag to see what byte order all the
+# other stuff in the header is in.
+#
+# MIPS RS3000 may also be for MIPS RS2000.
+# What're the correct byte orders for the nCUBE and the Fujitsu VPP500?
+#
+# updated by Daniel Quinlan (quinlan@yggdrasil.com)
+0 string \177ELF ELF
+>4 byte 0 invalid class
+>4 byte 1 32-bit
+>4 byte 2 64-bit
+>5 byte 0 invalid byte order
+>5 byte 1 LSB
+>>16 leshort 0 no file type,
+>>16 leshort 1 relocatable,
+>>16 leshort 2 executable,
+>>16 leshort 3 shared object,
+# Core handling from Peter Tobias <tobias@server.et-inf.fho-emden.de>
+>>16 leshort 4 core file
+>>>400 lelong >0 (signal %d),
+>>16 leshort &0xff00 processor-specific,
+>>18 leshort 0 no machine,
+>>18 leshort 1 AT&T WE32100 - invalid byte order,
+>>18 leshort 2 SPARC - invalid byte order,
+>>18 leshort 3 Intel 80386,
+>>18 leshort 4 Motorola 68000 - invalid byte order,
+>>18 leshort 5 Motorola 88000 - invalid byte order,
+>>18 leshort 6 Intel 80486,
+>>18 leshort 7 Intel 80860,
+>>18 leshort 8 MIPS RS3000_BE - invalid byte order,
+>>18 leshort 9 Amdahl - invalid byte order,
+>>18 leshort 10 MIPS RS3000_LE,
+>>18 leshort 11 RS6000 - invalid byte order,
+>>18 leshort 15 PA-RISC - invalid byte order,
+>>18 leshort 16 nCUBE,
+>>18 leshort 17 VPP500,
+>>18 leshort 18 SPARC32PLUS,
+>>18 leshort 20 PowerPC,
+>>18 leshort 0x9026 Alpha,
+>>20 lelong 0 invalid version
+>>20 lelong 1 version 1
+>>36 lelong 1 MathCoPro/FPU/MAU Required
+>5 byte 2 MSB
+>>16 beshort 0 no file type,
+>>16 beshort 1 relocatable,
+>>16 beshort 2 executable,
+>>16 beshort 3 shared object,
+>>16 beshort 4 core file,
+>>>400 lelong >0 (signal %d),
+>>16 beshort &0xff00 processor-specific,
+>>18 beshort 0 no machine,
+>>18 beshort 1 AT&T WE32100,
+>>18 beshort 2 SPARC,
+>>18 beshort 3 Intel 80386 - invalid byte order,
+>>18 beshort 4 Motorola 68000,
+>>18 beshort 5 Motorola 88000,
+>>18 beshort 6 Intel 80486 - invalid byte order,
+>>18 beshort 7 Intel 80860,
+>>18 beshort 8 MIPS RS3000_BE,
+>>18 beshort 9 Amdahl,
+>>18 beshort 10 MIPS RS3000_LE - invalid byte order,
+>>18 beshort 11 RS6000,
+>>18 beshort 15 PA-RISC,
+>>18 beshort 16 nCUBE,
+>>18 beshort 17 VPP500,
+>>18 beshort 18 SPARC32PLUS,
+>>18 beshort 20 PowerPC,
+>>18 beshort 0x9026 Alpha,
+>>20 belong 0 invalid version
+>>20 belong 1 version 1
+>>36 belong 1 MathCoPro/FPU/MAU Required
--- /dev/null
+
+#------------------------------------------------------------------------------
+# encore: file(1) magic for Encore machines
+#
+# XXX - needs to have the byte order specified (NS32K was little-endian,
+# dunno whether they run the 88K in little-endian mode or not).
+#
+0 short 0x154 Encore
+>20 short 0x107 executable
+>20 short 0x108 pure executable
+>20 short 0x10b demand-paged executable
+>20 short 0x10f unsupported executable
+>12 long >0 not stripped
+>22 short >0 - version %ld
+>22 short 0 -
+#>4 date x stamp %s
+0 short 0x155 Encore unsupported executable
+>12 long >0 not stripped
+>22 short >0 - version %ld
+>22 short 0 -
+#>4 date x stamp %s
--- /dev/null
+
+#------------------------------------------------------------------------------
+# 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
--- /dev/null
+
+#------------------------------------------------------------------------------
+# flash: file(1) magic for Macromedia Flash file format
+#
+# See
+#
+# http://www.macromedia.com/software/flash/open/
+#
+0 string FWS Macromedia Flash data,
+>3 byte x version %d
--- /dev/null
+
+#------------------------------------------------------------------------------
+# fonts: file(1) magic for font data
+#
+0 string FONT ASCII vfont text
+0 short 0436 Berkeley vfont data
+0 short 017001 byte-swapped Berkeley vfont data
+
+# PostScript fonts (must precede "printer" entries), quinlan@yggdrasil.com
+0 string %!PS-AdobeFont-1.0 PostScript Type 1 font text
+>20 string >\0 (%s)
+6 string %!PS-AdobeFont-1.0 PostScript Type 1 font program data
+
+# X11 font files in SNF (Server Natural Format) format
+0 belong 00000004 X11 SNF font data, MSB first
+0 lelong 00000004 X11 SNF font data, LSB first
+
+# X11 Bitmap Distribution Format, from Daniel Quinlan (quinlan@yggdrasil.com)
+0 string STARTFONT\040 X11 BDF font text
+
+# X11 fonts, from Daniel Quinlan (quinlan@yggdrasil.com)
+# PCF must come before SGI additions ("MIPSEL MIPS-II COFF" collides)
+0 string \001fcp X11 Portable Compiled Font data
+>12 byte 0x02 \b, LSB first
+>12 byte 0x0a \b, MSB first
+0 string D1.0\015 X11 Speedo font data
--- /dev/null
+
+#------------------------------------------------------------------------------
+# frame: file(1) magic for FrameMaker files
+#
+# This stuff came on a FrameMaker demo tape, most of which is
+# copyright, but this file is "published" as witness the following:
+#
+0 string \<MakerFile FrameMaker document
+>11 string 4.0 (4.0
+>11 string 3.0 (3.0
+>11 string 2.0 (2.0
+>11 string 1.0 (1.0
+>14 byte x %c)
+0 string \<MIFFile FrameMaker MIF (ASCII) file
+>9 string 4.0 (4.0)
+>9 string 3.0 (3.0)
+>9 string 2.0 (2.0)
+>9 string 1.0 (1.x)
+0 string \<MakerDictionary FrameMaker Dictionary text
+>17 string 3.0 (3.0)
+>17 string 2.0 (2.0)
+>17 string 1.0 (1.x)
+0 string \<MakerScreenFont FrameMaker Font file
+>17 string 1.01 (%s)
+0 string \<MML FrameMaker MML file
+0 string \<BookFile FrameMaker Book file
+>10 string 3.0 (3.0
+>10 string 2.0 (2.0
+>10 string 1.0 (1.0
+>13 byte x %c)
+# XXX - this book entry should be verified, if you find one, uncomment this
+#0 string \<Book\ FrameMaker Book (ASCII) file
+#>6 string 3.0 (3.0)
+#>6 string 2.0 (2.0)
+#>6 string 1.0 (1.0)
+0 string \<Maker Intermediate Print File FrameMaker IPL file
--- /dev/null
+
+#------------------------------------------------------------------------------
+# freebsd: file(1) magic for FreeBSD objects
+#
+# All new-style FreeBSD magic numbers are in host byte order (i.e.,
+# little-endian on x86).
+#
+# XXX - this comes from the file "freebsd" in a recent FreeBSD version of
+# "file"; it, and the NetBSD stuff in "netbsd", appear to use different
+# schemes for distinguishing between executable images, shared libraries,
+# and object files.
+#
+# FreeBSD says:
+#
+# Regardless of whether it's pure, demand-paged, or none of the
+# above:
+#
+# if the entry point is < 4096, then it's a shared library if
+# the "has run-time loader information" bit is set, and is
+# position-independent if the "is position-independent" bit
+# is set;
+#
+# if the entry point is >= 4096 (or >4095, same thing), then it's
+# an executable, and is dynamically-linked if the "has run-time
+# loader information" bit is set.
+#
+# On x86, NetBSD says:
+#
+# If it's neither pure nor demand-paged:
+#
+# if it has the "has run-time loader information" bit set, it's
+# a dynamically-linked executable;
+#
+# if it doesn't have that bit set, then:
+#
+# if it has the "is position-independent" bit set, it's
+# position-independent;
+#
+# if the entry point is non-zero, it's an executable, otherwise
+# it's an object file.
+#
+# If it's pure:
+#
+# if it has the "has run-time loader information" bit set, it's
+# a dynamically-linked executable, otherwise it's just an
+# executable.
+#
+# If it's demand-paged:
+#
+# if it has the "has run-time loader information" bit set,
+# then:
+#
+# if the entry point is < 4096, it's a shared library;
+#
+# if the entry point is = 4096 or > 4096 (i.e., >= 4096),
+# it's a dynamically-linked executable);
+#
+# if it doesn't have the "has run-time loader information" bit
+# set, then it's just an executable.
+#
+# (On non-x86, NetBSD does much the same thing, except that it uses
+# 8192 on 68K - except for "68k4k", which is presumably "68K with 4K
+# pages - SPARC, and MIPS, presumably because Sun-3's and Sun-4's
+# had 8K pages; dunno about MIPS.)
+#
+# I suspect the two will differ only in perverse and uninteresting cases
+# ("shared" libraries that aren't demand-paged and whose pages probably
+# won't actually be shared, executables with entry points <4096).
+#
+# I leave it to those more familiar with FreeBSD and NetBSD to figure out
+# what the right answer is (although using ">4095", FreeBSD-style, is
+# probably better than separately checking for "=4096" and ">4096",
+# NetBSD-style). (The old "netbsd" file analyzed FreeBSD demand paged
+# executables using the NetBSD technique.)
+#
+0 lelong&0377777777 041400407 FreeBSD/i386
+>20 lelong <4096
+>>3 byte&0xC0 &0x80 shared library
+>>3 byte&0xC0 0x40 PIC object
+>>3 byte&0xC0 0x00 object
+>20 lelong >4095
+>>3 byte&0x80 0x80 dynamically linked executable
+>>3 byte&0x80 0x00 executable
+>16 lelong >0 not stripped
+
+0 lelong&0377777777 041400410 FreeBSD/i386 pure
+>20 lelong <4096
+>>3 byte&0xC0 &0x80 shared library
+>>3 byte&0xC0 0x40 PIC object
+>>3 byte&0xC0 0x00 object
+>20 lelong >4095
+>>3 byte&0x80 0x80 dynamically linked executable
+>>3 byte&0x80 0x00 executable
+>16 lelong >0 not stripped
+
+0 lelong&0377777777 041400413 FreeBSD/i386 demand paged
+>20 lelong <4096
+>>3 byte&0xC0 &0x80 shared library
+>>3 byte&0xC0 0x40 PIC object
+>>3 byte&0xC0 0x00 object
+>20 lelong >4095
+>>3 byte&0x80 0x80 dynamically linked executable
+>>3 byte&0x80 0x00 executable
+>16 lelong >0 not stripped
+
+0 lelong&0377777777 041400314 FreeBSD/i386 compact demand paged
+>20 lelong <4096
+>>3 byte&0xC0 &0x80 shared library
+>>3 byte&0xC0 0x40 PIC object
+>>3 byte&0xC0 0x00 object
+>20 lelong >4095
+>>3 byte&0x80 0x80 dynamically linked executable
+>>3 byte&0x80 0x00 executable
+>16 lelong >0 not stripped
+
+# XXX gross hack to identify core files
+# cores start with a struct tss; we take advantage of the following:
+# byte 7: highest byte of the kernel stack pointer, always 0xfe
+# 8/9: kernel (ring 0) ss value, always 0x0010
+# 10 - 27: ring 1 and 2 ss/esp, unused, thus always 0
+# 28: low order byte of the current PTD entry, always 0 since the
+# PTD is page-aligned
+#
+7 string \357\020\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 FreeBSD/i386 a.out core file
+>1039 string >\0 from '%s'
+
+# /var/run/ld.so.hints
+# What are you laughing about?
+0 lelong 011421044151 ld.so hints file
+>4 lelong >0 (version %d)
--- /dev/null
+#------------------------------------------------------------------------------
+# GIMP Gradient: file(1) magic for the GIMP's gradient data files
+# by Federico Mena <federico@nuclecu.unam.mx>
+
+0 string GIMP\ Gradient GIMP gradient data
+
+#------------------------------------------------------------------------------
+# XCF: file(1) magic for the XCF image format used in the GIMP developed
+# by Spencer Kimball and Peter Mattis
+# ('Bucky' LaDieu, nega@vt.edu)
+
+0 string gimp\ xcf\ file GIMP XCF image data,
+>14 belong x %ld x
+>18 belong x %ld,
+>22 belong 0 RGB Color
+>22 belong 1 Greyscale
+>22 belong 2 Indexed Color
+
+#------------------------------------------------------------------------------
+# XCF: file(1) magic for the patterns used in the GIMP, developed
+# by Spencer Kimball and Peter Mattis
+# ('Bucky' LaDieu, nega@vt.edu)
+
+20 string GPAT GIMP pattern data,
+>24 string x %s
+
+#------------------------------------------------------------------------------
+# XCF: file(1) magic for the brushes used in the GIMP, developed
+# by Spencer Kimball and Peter Mattis
+# ('Bucky' LaDieu, nega@vt.edu)
+
+20 string GIMP GIMP brush data
--- /dev/null
+#
+# GNU nlsutils message catalog file format
+#
+0 string \336\22\4\225 GNU message catalog (little endian),
+>4 lelong x revision %d,
+>8 lelong x %d messages
+0 string \225\4\22\336 GNU message catalog (big endian),
+>4 belong x revision %d,
+>8 belong x %d messages
--- /dev/null
+
+#------------------------------------------------------------------------------
+# hp: file(1) magic for Hewlett Packard machines (see also "printer")
+#
+# XXX - somebody should figure out whether any byte order needs to be
+# applied to the "TML" stuff; I'm assuming the Apollo stuff is
+# big-endian as it was mostly 68K-based.
+#
+# I think the 500 series was the old stack-based machines, running a
+# UNIX environment atop the "SUN kernel"; dunno whether it was
+# big-endian or little-endian.
+#
+# Daniel Quinlan (quinlan@yggdrasil.com): hp200 machines are 68010 based;
+# hp300 are 68020+68881 based; hp400 are also 68k. The following basic
+# HP magic is useful for reference, but using "long" magic is a better
+# practice in order to avoid collisions.
+#
+# Guy Harris (guy@netapp.com): some additions to this list came from
+# HP-UX 10.0's "/usr/include/sys/unistd.h" (68030, 68040, PA-RISC 1.1,
+# 1.2, and 2.0). The 1.2 and 2.0 stuff isn't in the HP-UX 10.0
+# "/etc/magic", though, except for the "archive file relocatable library"
+# stuff, and the 68030 and 68040 stuff isn't there at all - are they not
+# used in executables, or have they just not yet updated "/etc/magic"
+# completely?
+#
+# 0 beshort 200 hp200 (68010) BSD binary
+# 0 beshort 300 hp300 (68020+68881) BSD binary
+# 0 beshort 0x20c hp200/300 HP-UX binary
+# 0 beshort 0x20d hp400 (68030) HP-UX binary
+# 0 beshort 0x20e hp400 (68040?) HP-UX binary
+# 0 beshort 0x20b PA-RISC1.0 HP-UX binary
+# 0 beshort 0x210 PA-RISC1.1 HP-UX binary
+# 0 beshort 0x211 PA-RISC1.2 HP-UX binary
+# 0 beshort 0x214 PA-RISC2.0 HP-UX binary
+
+#
+# The "misc" stuff needs a byte order; the archives look suspiciously
+# like the old 177545 archives (0xff65 = 0177545).
+#
+#### Old Apollo stuff
+0 beshort 0627 Apollo m68k COFF executable
+>18 beshort ^040000 not stripped
+>22 beshort >0 - version %ld
+0 beshort 0624 apollo a88k COFF executable
+>18 beshort ^040000 not stripped
+>22 beshort >0 - version %ld
+0 long 01203604016 TML 0123 byte-order format
+0 long 01702407010 TML 1032 byte-order format
+0 long 01003405017 TML 2301 byte-order format
+0 long 01602007412 TML 3210 byte-order format
+#### PA-RISC
+0 belong 0x02100106 PA-RISC1.1 relocatable object
+0 belong 0x02100107 PA-RISC1.1 executable
+>168 belong &=0x00000004 dynamically linked
+>(144) belong 0x054ef630 dynamically linked
+>96 belong >0 - not stripped
+
+0 belong 0x02100108 PA-RISC1.1 shared executable
+>168 belong&0x4 0x4 dynamically linked
+>(144) belong 0x054ef630 dynamically linked
+>96 belong >0 - not stripped
+
+0 belong 0x0210010b PA-RISC1.1 demand-load executable
+>168 belong&0x4 0x4 dynamically linked
+>(144) belong 0x054ef630 dynamically linked
+>96 belong >0 - not stripped
+
+0 belong 0x0210010e PA-RISC1.1 shared library
+>96 belong >0 - not stripped
+
+0 belong 0x0210010d PA-RISC1.1 dynamic load library
+>96 belong >0 - not stripped
+
+#### 800
+0 belong 0x020b0106 PA-RISC1.0 relocatable object
+
+0 belong 0x020b0107 PA-RISC1.0 executable
+>168 belong&0x4 0x4 dynamically linked
+>(144) belong 0x054ef630 dynamically linked
+>96 belong >0 - not stripped
+
+0 belong 0x020b0108 PA-RISC1.0 shared executable
+>168 belong&0x4 0x4 dynamically linked
+>(144) belong 0x054ef630 dynamically linked
+>96 belong >0 - not stripped
+
+0 belong 0x020b010b PA-RISC1.0 demand-load executable
+>168 belong&0x4 0x4 dynamically linked
+>(144) belong 0x054ef630 dynamically linked
+>96 belong >0 - not stripped
+
+0 belong 0x020b010e PA-RISC1.0 shared library
+>96 belong >0 - not stripped
+
+0 belong 0x020b010d PA-RISC1.0 dynamic load library
+>96 belong >0 - not stripped
+
+0 belong 0x213c6172 archive file
+>68 belong 0x020b0619 - PA-RISC1.0 relocatable library
+>68 belong 0x02100619 - PA-RISC1.1 relocatable library
+>68 belong 0x02110619 - PA-RISC1.2 relocatable library
+>68 belong 0x02140619 - PA-RISC2.0 relocatable library
+
+#### 500
+0 long 0x02080106 HP s500 relocatable executable
+>16 long >0 - version %ld
+
+0 long 0x02080107 HP s500 executable
+>16 long >0 - version %ld
+
+0 long 0x02080108 HP s500 pure executable
+>16 long >0 - version %ld
+
+#### 200
+0 belong 0x020c0108 HP s200 pure executable
+>4 beshort >0 - version %ld
+>8 belong &0x80000000 save fp regs
+>8 belong &0x40000000 dynamically linked
+>8 belong &0x20000000 debuggable
+>36 belong >0 not stripped
+
+0 belong 0x020c0107 HP s200 executable
+>4 beshort >0 - version %ld
+>8 belong &0x80000000 save fp regs
+>8 belong &0x40000000 dynamically linked
+>8 belong &0x20000000 debuggable
+>36 belong >0 not stripped
+
+0 belong 0x020c010b HP s200 demand-load executable
+>4 beshort >0 - version %ld
+>8 belong &0x80000000 save fp regs
+>8 belong &0x40000000 dynamically linked
+>8 belong &0x20000000 debuggable
+>36 belong >0 not stripped
+
+0 belong 0x020c0106 HP s200 relocatable executable
+>4 beshort >0 - version %ld
+>6 beshort >0 - highwater %d
+>8 belong &0x80000000 save fp regs
+>8 belong &0x20000000 debuggable
+>8 belong &0x10000000 PIC
+
+0 belong 0x020a0108 HP s200 (2.x release) pure executable
+>4 beshort >0 - version %ld
+>36 belong >0 not stripped
+
+0 belong 0x020a0107 HP s200 (2.x release) executable
+>4 beshort >0 - version %ld
+>36 belong >0 not stripped
+
+0 belong 0x020c010e HP s200 shared library
+>4 beshort >0 - version %ld
+>6 beshort >0 - highwater %d
+>36 belong >0 not stripped
+
+0 belong 0x020c010d HP s200 dynamic load library
+>4 beshort >0 - version %ld
+>6 beshort >0 - highwater %d
+>36 belong >0 not stripped
+
+#### MISC
+0 long 0x0000ff65 HP old archive
+0 long 0x020aff65 HP s200 old archive
+0 long 0x020cff65 HP s200 old archive
+0 long 0x0208ff65 HP s500 old archive
+
+0 long 0x015821a6 HP core file
+
+0 long 0x4da7eee8 HP-WINDOWS font
+>8 byte >0 - version %ld
+0 string Bitmapfile HP Bitmapfile
+
+0 string IMGfile CIS compimg HP Bitmapfile
+# XXX - see "lif"
+#0 short 0x8000 lif file
+0 long 0x020c010c compiled Lisp
+
+0 string msgcat01 HP NLS message catalog,
+>8 long >0 %d messages
+
+# addendum to /etc/magic with HP-48sx file-types by phk@data.fls.dk 1jan92
+0 string HPHP48- HP48 binary
+>7 byte >0 - Rev %c
+>8 short 0x1129 (ADR)
+>8 short 0x3329 (REAL)
+>8 short 0x5529 (LREAL)
+>8 short 0x7729 (COMPLX)
+>8 short 0x9d29 (LCOMPLX)
+>8 short 0xbf29 (CHAR)
+>8 short 0xe829 (ARRAY)
+>8 short 0x0a2a (LNKARRAY)
+>8 short 0x2c2a (STRING)
+>8 short 0x4e2a (HXS)
+>8 short 0x742a (LIST)
+>8 short 0x962a (DIR)
+>8 short 0xb82a (ALG)
+>8 short 0xda2a (UNIT)
+>8 short 0xfc2a (TAGGED)
+>8 short 0x1e2b (GROB)
+>8 short 0x402b (LIB)
+>8 short 0x622b (BACKUP)
+>8 short 0x882b (LIBDATA)
+>8 short 0x9d2d (PROG)
+>8 short 0xcc2d (CODE)
+>8 short 0x482e (GNAME)
+>8 short 0x6d2e (LNAME)
+>8 short 0x922e (XLIB)
+0 string %%HP: HP48 text
+>6 string T(0) - T(0)
+>6 string T(1) - T(1)
+>6 string T(2) - T(2)
+>6 string T(3) - T(3)
+>10 string A(D) A(D)
+>10 string A(R) A(R)
+>10 string A(G) A(G)
+>14 string F(.) F(.);
+>14 string F(,) F(,);
+
+# hpBSD magic numbers
+0 beshort 200 hp200 (68010) BSD
+>2 beshort 0407 impure binary
+>2 beshort 0410 read-only binary
+>2 beshort 0413 demand paged binary
+0 beshort 300 hp300 (68020+68881) BSD
+>2 beshort 0407 impure binary
+>2 beshort 0410 read-only binary
+>2 beshort 0413 demand paged binary
+
--- /dev/null
+
+#------------------------------------------------------------------------------
+# ibm370: file(1) magic for IBM 370 and compatibles.
+#
+# "ibm370" said that 0x15d == 0535 was "ibm 370 pure executable".
+# What the heck *is* "USS/370"?
+# AIX 4.1's "/etc/magic" has
+#
+# 0 short 0535 370 sysV executable
+# >12 long >0 not stripped
+# >22 short >0 - version %d
+# >30 long >0 - 5.2 format
+# 0 short 0530 370 sysV pure executable
+# >12 long >0 not stripped
+# >22 short >0 - version %d
+# >30 long >0 - 5.2 format
+#
+# instead of the "USS/370" versions of the same magic numbers.
+#
+0 beshort 0537 370 XA sysV executable
+>12 belong >0 not stripped
+>22 beshort >0 - version %d
+>30 belong >0 - 5.2 format
+0 beshort 0532 370 XA sysV pure executable
+>12 belong >0 not stripped
+>22 beshort >0 - version %d
+>30 belong >0 - 5.2 format
+0 beshort 054001 370 sysV pure executable
+>12 belong >0 not stripped
+0 beshort 055001 370 XA sysV pure executable
+>12 belong >0 not stripped
+0 beshort 056401 370 sysV executable
+>12 belong >0 not stripped
+0 beshort 057401 370 XA sysV executable
+>12 belong >0 not stripped
+0 beshort 0531 SVR2 executable (Amdahl-UTS)
+>12 belong >0 not stripped
+>24 belong >0 - version %ld
+0 beshort 0534 SVR2 pure executable (Amdahl-UTS)
+>12 belong >0 not stripped
+>24 belong >0 - version %ld
+0 beshort 0530 SVR2 pure executable (USS/370)
+>12 belong >0 not stripped
+>24 belong >0 - version %ld
+0 beshort 0535 SVR2 executable (USS/370)
+>12 belong >0 not stripped
+>24 belong >0 - version %ld
--- /dev/null
+
+#------------------------------------------------------------------------------
+# ibm6000: file(1) magic for RS/6000 and the RT PC.
+#
+0 beshort 0x01df executable (RISC System/6000 V3.1) or obj module
+>12 belong >0 not stripped
+# Breaks sun4 statically linked execs.
+#0 beshort 0x0103 executable (RT Version 2) or obj module
+#>2 byte 0x50 pure
+#>28 belong >0 not stripped
+#>6 beshort >0 - version %ld
+0 beshort 0x0104 shared library
+0 beshort 0x0105 ctab data
+0 beshort 0xfe04 structured file
+0 string 0xabcdef AIX message catalog
+0 belong 0x000001f9 AIX compiled message catalog
+0 string \<aiaff> archive
--- /dev/null
+
+#------------------------------------------------------------------------------
+# iff: file(1) magic for Interchange File Format (see also "audio" & "images")
+#
+# Daniel Quinlan (quinlan@yggdrasil.com) -- IFF was designed by Electronic
+# Arts for file interchange. It has also been used by Apple, SGI, and
+# especially Commodore-Amiga.
+#
+# IFF files begin with an 8 byte FORM header, followed by a 4 character
+# FORM type, which is followed by the first chunk in the FORM.
+
+0 string FORM IFF data
+#>4 belong x \b, FORM is %d bytes long
+# audio formats
+>8 string AIFF \b, AIFF audio
+>8 string AIFC \b, AIFF-C compressed audio
+>8 string 8SVX \b, 8SVX 8-bit sampled sound voice
+>8 string SAMP \b, SAMP sampled audio
+# image formats
+>8 string ILBMBMHD \b, ILBM interleaved image
+>>20 beshort x \b, %d x
+>>22 beshort x %d
+>8 string RGBN \b, RGBN 12-bit RGB image
+>8 string RGB8 \b, RGB8 24-bit RGB image
+>8 string DR2D \b, DR2D 2-D object
+>8 string TDDD \b, TDDD 3-D rendering
+# other formats
+>8 string FTXT \b, FTXT formatted text
--- /dev/null
+
+#------------------------------------------------------------------------------
+# images: file(1) magic for image formats (see also "iff")
+#
+# originally from jef@helios.ee.lbl.gov (Jef Poskanzer),
+# additions by janl@ifi.uio.no as well as others. Jan also suggested
+# merging several one- and two-line files into here.
+#
+# little magic: PCX (first byte is 0x0a)
+# no magic: Targa
+
+# PBMPLUS images
+# The next byte following the magic is always whitespace.
+0 string P1 PBM image text
+0 string P2 PGM image text
+0 string P3 PPM image text
+0 string P4 PBM "rawbits" image data
+0 string P5 PGM "rawbits" image data
+0 string P6 PPM "rawbits" image data
+
+# NIFF (Navy Interchange File Format, a modification of TIFF) images
+0 string IIN1 NIFF image data
+
+# Tag Image File Format, from Daniel Quinlan (quinlan@yggdrasil.com)
+# The second word of TIFF files is the TIFF version number, 42, which has
+# never changed. The TIFF specification recommends testing for it.
+0 string MM\x00\x2a TIFF image data, big-endian
+0 string II\x2a\x00 TIFF image data, little-endian
+
+# PNG [Portable Network Graphics, or "PNG's Not GIF"] images
+# (Greg Roelofs, newt@uchicago.edu)
+#
+# 137 P N G \r \n ^Z \n [4-byte length] H E A D [HEAD data] [HEAD crc] ...
+#
+0 string \x89PNG PNG image data,
+>4 belong !0x0d0a1a0a CORRUPTED,
+>16 belong x %ld x
+>20 belong x %ld,
+>24 byte x %d-bit
+>25 byte 0 grayscale,
+>25 byte 2 \b/color RGB,
+>25 byte 3 colormap,
+>25 byte 4 gray+alpha,
+>25 byte 6 \b/color RGBA,
+#>26 byte 0 deflate/32K,
+>28 byte 0 non-interlaced
+>28 byte 1 interlaced
+
+# GIF
+0 string GIF8 GIF image data
+>4 string 7a \b, version 8%s,
+>4 string 9a \b, version 8%s,
+>6 leshort >0 %hd x
+>8 leshort >0 %hd,
+#>10 byte &0x80 color mapped,
+#>10 byte&0x07 =0x00 2 colors
+#>10 byte&0x07 =0x01 4 colors
+#>10 byte&0x07 =0x02 8 colors
+#>10 byte&0x07 =0x03 16 colors
+#>10 byte&0x07 =0x04 32 colors
+#>10 byte&0x07 =0x05 64 colors
+#>10 byte&0x07 =0x06 128 colors
+#>10 byte&0x07 =0x07 256 colors
+
+# ITC (CMU WM) raster files. It is essentially a byte-reversed Sun raster,
+# 1 plane, no encoding.
+0 string \361\0\100\273 CMU window manager raster image data
+>4 lelong >0 %d x
+>8 lelong >0 %d,
+>12 lelong >0 %d-bit
+
+# Magick Image File Format
+0 string id=ImageMagick MIFF image data
+
+# Artisan
+0 long 1123028772 Artisan image data
+>4 long 1 \b, rectangular 24-bit
+>4 long 2 \b, rectangular 8-bit with colormap
+>4 long 3 \b, rectangular 32-bit (24-bit with matte)
+
+# FIG (Facility for Interactive Generation of figures), an object-based format
+0 string #FIG FIG image text
+>5 string x \b, version %.3s
+
+# PHIGS
+0 string ARF_BEGARF PHIGS clear text archive
+0 string @(#)SunPHIGS SunPHIGS
+# version number follows, in the form m.n
+>40 string SunBin binary
+>32 string archive archive
+
+# GKS (Graphics Kernel System)
+0 string GKSM GKS Metafile
+>24 string SunGKS \b, SunGKS
+
+# CGM image files
+0 string BEGMF clear text Computer Graphics Metafile
+# XXX - questionable magic
+0 beshort&0xffe0 0x0020 binary Computer Graphics Metafile
+0 beshort 0x3020 character Computer Graphics Metafile
+
+# MGR bitmaps (Michael Haardt, u31b3hs@pool.informatik.rwth-aachen.de)
+0 string yz MGR bitmap, modern format, 8-bit aligned
+0 string zz MGR bitmap, old format, 1-bit deep, 16-bit aligned
+0 string xz MGR bitmap, old format, 1-bit deep, 32-bit aligned
+0 string yx MGR bitmap, modern format, squeezed
+
+# Fuzzy Bitmap (FBM) images
+0 string %bitmap\0 FBM image data
+>30 long 0x31 \b, mono
+>30 long 0x33 \b, color
+
+# facsimile data
+1 string PC\ Research,\ Inc group 3 fax data
+>29 byte 0 \b, normal resolution (204x98 DPI)
+>29 byte 1 \b, fine resolution (204x196 DPI)
+
+# JPEG images
+# SunOS 5.5.1 had
+#
+# 0 string \377\330\377\340 JPEG file
+# 0 string \377\330\377\356 JPG file
+#
+# both of which turn into "JPEG image data" here.
+#
+0 beshort 0xffd8 JPEG image data
+>6 string JFIF \b, JFIF standard
+# HSI is Handmade Software's proprietary JPEG encoding scheme
+0 string hsi1 JPEG image data, HSI proprietary
+
+# PC bitmaps (OS/2, Windoze BMP files) (Greg Roelofs, newt@uchicago.edu)
+0 string BM PC bitmap data
+>14 leshort 12 \b, OS/2 1.x format
+>>18 leshort x \b, %d x
+>>20 leshort x %d
+>14 leshort 64 \b, OS/2 2.x format
+>>18 leshort x \b, %d x
+>>20 leshort x %d
+>14 leshort 40 \b, Windows 3.x format
+>>18 lelong x \b, %d x
+>>22 lelong x %d x
+>>28 leshort x %d
+0 string IC PC icon data
+0 string PI PC pointer image data
+0 string CI PC color icon data
+0 string CP PC color pointer image data
+# Conflicts with other entries [BABYL]
+#0 string BA PC bitmap array data
+
+# XPM icons (Greg Roelofs, newt@uchicago.edu)
+# note possible collision with C/REXX entry in c-lang; currently commented out
+0 string /*\ XPM\ */ X pixmap image text
+
+# Utah Raster Toolkit RLE images (janl@ifi.uio.no)
+0 leshort 0xcc52 RLE image data,
+>6 leshort x %d x
+>8 leshort x %d
+>2 leshort >0 \b, lower left corner: %d
+>4 leshort >0 \b, lower right corner: %d
+>10 byte&0x1 =0x1 \b, clear first
+>10 byte&0x2 =0x2 \b, no background
+>10 byte&0x4 =0x4 \b, alpha channel
+>10 byte&0x8 =0x8 \b, comment
+>11 byte >0 \b, %d color channels
+>12 byte >0 \b, %d bits per pixel
+>13 byte >0 \b, %d color map channels
+
+# image file format (Robert Potter, potter@cs.rochester.edu)
+0 string Imagefile\ version- iff image data
+# this adds the whole header (inc. version number), informative but longish
+>10 string >\0 %s
+
+# Sun raster images, from Daniel Quinlan (quinlan@yggdrasil.com)
+0 belong 0x59a66a95 Sun raster image data
+>4 belong >0 \b, %d x
+>8 belong >0 %d,
+>12 belong >0 %d-bit,
+#>16 belong >0 %d bytes long,
+>20 belong 0 old format,
+#>20 belong 1 standard,
+>20 belong 2 compressed,
+>20 belong 3 RGB,
+>20 belong 4 TIFF,
+>20 belong 5 IFF,
+>20 belong 0xffff reserved for testing,
+>24 belong 0 no colormap
+>24 belong 1 RGB colormap
+>24 belong 2 raw colormap
+#>28 belong >0 colormap is %d bytes long
+
+# SGI image file format, from Daniel Quinlan (quinlan@yggdrasil.com)
+# file://sgi.com/graphics/SGIIMAGESPEC
+0 beshort 474 SGI image data
+#>2 byte 0 \b, verbatim
+>2 byte 1 \b, RLE
+#>3 byte 1 \b, normal precision
+>3 byte 2 \b, high precision
+>4 beshort x \b, %d-D
+>6 beshort x \b, %d x
+>8 beshort x %d
+>10 beshort x \b, %d channel
+>10 beshort !1 \bs
+>80 string >0 \b, "%s"
+
+0 string IT01 FIT image data
+>4 belong x \b, %d x
+>8 belong x %d x
+>12 belong x %d
+#
+0 string IT02 FIT image data
+>4 belong x \b, %d x
+>8 belong x %d x
+>12 belong x %d
+#
+2048 string PCD_IPI Kodak Photo CD image pack file
+0 string PCD_OPA Kodak Photo CD overview pack file
+
+# FITS format. Jeff Uphoff <juphoff@tarsier.cv.nrao.edu>
+# FITS is the Flexible Image Transport System, the de facto standard for
+# data and image transfer, storage, etc., for the astronomical community.
+# (FITS floating point formats are big-endian.)
+0 string SIMPLE\ \ = FITS image data
+>109 string 8 \b, 8-bit, character or unsigned binary integer
+>108 string 16 \b, 16-bit, two's complement binary integer
+>107 string \ 32 \b, 32-bit, two's complement binary integer
+>107 string -32 \b, 32-bit, floating point, single precision
+>107 string -64 \b, 64-bit, floating point, double precision
+
+# other images
+0 string This\ is\ a\ BitMap\ file Lisp Machine bit-array-file
+0 string !! Bennet Yee's "face" format
+
+# From SunOS 5.5.1 "/etc/magic" - appeared right before Sun raster image
+# stuff.
+#
+0 beshort 0x1010 PEX Binary Archive
--- /dev/null
+
+#------------------------------------------------------------------------------
+# intel: file(1) magic for x86 Unix
+#
+# Various flavors of x86 UNIX executable/object (other than Xenix, which
+# is in "microsoft"). DOS is in "msdos"; the ambitious soul can do
+# Windows as well.
+#
+# Windows NT belongs elsewhere, as you need x86 and MIPS and Alpha and
+# whatever comes next (HP-PA Hummingbird?). OS/2 may also go elsewhere
+# as well, if, as, and when IBM makes it portable.
+#
+# The `versions' should be un-commented if they work for you.
+# (Was the problem just one of endianness?)
+#
+0 leshort 0502 basic-16 executable
+>12 lelong >0 not stripped
+#>22 leshort >0 - version %ld
+0 leshort 0503 basic-16 executable (TV)
+>12 lelong >0 not stripped
+#>22 leshort >0 - version %ld
+0 leshort 0510 x86 executable
+>12 lelong >0 not stripped
+0 leshort 0511 x86 executable (TV)
+>12 lelong >0 not stripped
+0 leshort =0512 iAPX 286 executable small model (COFF)
+>12 lelong >0 not stripped
+#>22 leshort >0 - version %ld
+0 leshort =0522 iAPX 286 executable large model (COFF)
+>12 lelong >0 not stripped
+#>22 leshort >0 - version %ld
+# SGI labeled the next entry as "iAPX 386 executable" --Dan Quinlan
+0 leshort =0514 80386 COFF executable
+>12 lelong >0 not stripped
+>22 leshort >0 - version %ld
--- /dev/null
+
+#------------------------------------------------------------------------------
+# interleaf: file(1) magic for InterLeaf TPS:
+#
+0 string =\210OPS Interleaf saved data
+0 string =<!OPS Interleaf document text
+>5 string ,\ Version\ = \b, version
+>>17 string >\0 %.3s
--- /dev/null
+
+#------------------------------------------------------------------------------
+# island: file(1) magic for IslandWite/IslandDraw, from SunOS 5.5.1
+# "/etc/magic":
+# From: guy@netapp.com (Guy Harris)
+#
+4 string pgscriptver IslandWrite document
+13 string DrawFile IslandDraw document
+
--- /dev/null
+
+#------------------------------------------------------------------------------
+# ispell: file(1) magic for ispell
+#
+# Ispell 3.0 has a magic of 0x9601 and ispell 3.1 has 0x9602. This magic
+# will match 0x9600 through 0x9603 in *both* little endian and big endian.
+# (No other current magic entries collide.)
+#
+# Updated by Daniel Quinlan (quinlan@yggdrasil.com)
+#
+0 leshort&0xFFFC 0x9600 little endian ispell
+>0 byte 0 hash file (?),
+>0 byte 1 3.0 hash file,
+>0 byte 2 3.1 hash file,
+>0 byte 3 hash file (?),
+>2 leshort 0x00 8-bit, no capitalization, 26 flags
+>2 leshort 0x01 7-bit, no capitalization, 26 flags
+>2 leshort 0x02 8-bit, capitalization, 26 flags
+>2 leshort 0x03 7-bit, capitalization, 26 flags
+>2 leshort 0x04 8-bit, no capitalization, 52 flags
+>2 leshort 0x05 7-bit, no capitalization, 52 flags
+>2 leshort 0x06 8-bit, capitalization, 52 flags
+>2 leshort 0x07 7-bit, capitalization, 52 flags
+>2 leshort 0x08 8-bit, no capitalization, 128 flags
+>2 leshort 0x09 7-bit, no capitalization, 128 flags
+>2 leshort 0x0A 8-bit, capitalization, 128 flags
+>2 leshort 0x0B 7-bit, capitalization, 128 flags
+>2 leshort 0x0C 8-bit, no capitalization, 256 flags
+>2 leshort 0x0D 7-bit, no capitalization, 256 flags
+>2 leshort 0x0E 8-bit, capitalization, 256 flags
+>2 leshort 0x0F 7-bit, capitalization, 256 flags
+>4 leshort >0 and %d string characters
+0 beshort&0xFFFC 0x9600 big endian ispell
+>1 byte 0 hash file (?),
+>1 byte 1 3.0 hash file,
+>1 byte 2 3.1 hash file,
+>1 byte 3 hash file (?),
+>2 beshort 0x00 8-bit, no capitalization, 26 flags
+>2 beshort 0x01 7-bit, no capitalization, 26 flags
+>2 beshort 0x02 8-bit, capitalization, 26 flags
+>2 beshort 0x03 7-bit, capitalization, 26 flags
+>2 beshort 0x04 8-bit, no capitalization, 52 flags
+>2 beshort 0x05 7-bit, no capitalization, 52 flags
+>2 beshort 0x06 8-bit, capitalization, 52 flags
+>2 beshort 0x07 7-bit, capitalization, 52 flags
+>2 beshort 0x08 8-bit, no capitalization, 128 flags
+>2 beshort 0x09 7-bit, no capitalization, 128 flags
+>2 beshort 0x0A 8-bit, capitalization, 128 flags
+>2 beshort 0x0B 7-bit, capitalization, 128 flags
+>2 beshort 0x0C 8-bit, no capitalization, 256 flags
+>2 beshort 0x0D 7-bit, no capitalization, 256 flags
+>2 beshort 0x0E 8-bit, capitalization, 256 flags
+>2 beshort 0x0F 7-bit, capitalization, 256 flags
+>4 beshort >0 and %d string characters
--- /dev/null
+#------------------------------------------------------------
+# Java ByteCode
+# From Larry Schwimmer (schwim@cs.stanford.edu)
+#
+# The Java magic number is the same as the Mach-O fat file magic number.
+# Interestingly the the same guy, Mike DeMoney, of NeXT Inc. then of First
+# Person (Sun) picked both numbers only a couple of years apart. To make
+# the file(1) command work with both the Java Bytecode magic was merged with
+# the Mach-O magic in the file mach.
+#
+#0 belong 0xcafebabe
+#>4 belong 0x0003002d Java bytecode
--- /dev/null
+
+#------------------------------------------------------------------------------
+# karma: file(1) magic for Karma data files
+#
+# From <rgooch@atnf.csiro.au>
+
+0 string KarmaRHD Version Karma Data Structure Version
+>16 long x %lu
--- /dev/null
+#------------------------------------------------------------------------------
+# DEC SRC Virtual Paper: Lectern files
+# Karl M. Hegbloom <karlheg@inetarena.com>
+0 string lect DEC SRC Virtual Paper Lectern file
--- /dev/null
+
+#------------------------------------------------------------------------------
+# lex: file(1) magic for lex
+#
+# derived empirically, your offsets may vary!
+53 string yyprevious C program text (from lex)
+>3 string >\0 for %s
+# C program text from GNU flex, from Daniel Quinlan <quinlan@yggdrasil.com>
+21 string generated\ by\ flex C program text (from flex)
+# lex description file, from Daniel Quinlan <quinlan@yggdrasil.com>
+0 string %{ lex description text
--- /dev/null
+
+#------------------------------------------------------------------------------
+# lif: file(1) magic for lif
+#
+# XXX - byte order? (Probably beshort, Daniel Quinlan <quinlan@yggdrasil.com>)
+#
+0 short 0x8000 lif file
--- /dev/null
+
+#------------------------------------------------------------------------------
+# linux: file(1) magic for Linux files
+#
+# Values for Linux/i386 binaries, from Daniel Quinlan <quinlan@yggdrasil.com>
+# The following basic Linux magic is useful for reference, but using
+# "long" magic is a better practice in order to avoid collisions.
+#
+# 2 leshort 100 Linux/i386
+# >0 leshort 0407 impure executable (OMAGIC)
+# >0 leshort 0410 pure executable (NMAGIC)
+# >0 leshort 0413 demand-paged executable (ZMAGIC)
+# >0 leshort 0314 demand-paged executable (QMAGIC)
+#
+0 lelong 0x00640107 Linux/i386 impure executable (OMAGIC)
+>16 lelong 0 \b, stripped
+0 lelong 0x00640108 Linux/i386 pure executable (NMAGIC)
+>16 lelong 0 \b, stripped
+0 lelong 0x0064010b Linux/i386 demand-paged executable (ZMAGIC)
+>16 lelong 0 \b, stripped
+0 lelong 0x006400cc Linux/i386 demand-paged executable (QMAGIC)
+>16 lelong 0 \b, stripped
+#
+0 string \007\001\000 Linux/i386 object file
+>20 lelong >0x1020 \b, DLL library
+# message catalogs, from Mitchum DSouza <m.dsouza@mrc-apu.cam.ac.uk>
+0 string *nazgul* Linux compiled message catalog
+>8 lelong >0 \b, version %ld
+# core dump file, from Bill Reynolds <bill@goshawk.lanl.gov>
+216 lelong 0421 Linux/i386 core file
+>220 string >\0 of '%s'
+>200 lelong >0 (signal %d)
+#
+# LILO boot/chain loaders, from Daniel Quinlan <quinlan@yggdrasil.com>
+# this can be overridden by the DOS executable (COM) entry
+2 string LILO Linux/i386 LILO boot/chain loader
+#
+# Debian Packages, from Peter Tobias <tobias@server.et-inf.fho-emden.de>
+0 string 0.9
+>8 byte 0x0a Debian Binary Package
+>>3 byte >0 \b, created by dpkg 0.9%c
+>>4 byte >0 pl%c
+# PSF fonts, from H. Peter Anvin <hpa@yggdrasil.com>
+0 leshort 0x0436 Linux/i386 PC Screen Font data,
+>2 byte 0 256 characters, no directory,
+>2 byte 1 512 characters, no directory,
+>2 byte 2 256 characters, Unicode directory,
+>2 byte 3 512 characters, Unicode directory,
+>3 byte >0 8x%d
+# Linux swap file, from Daniel Quinlan <quinlan@yggdrasil.com>
+4086 string SWAP-SPACE Linux/i386 swap file
+# ECOFF magic for OSF/1 and Linux (only tested under Linux though)
+#
+# from Erik Troan (ewt@redhat.com) examining od dumps, so this
+# could be wrong
+# updated by David Mosberger (davidm@azstarnet.com) based on
+# GNU BFD and MIPS info found below.
+#
+0 leshort 0x0183 ECOFF alpha
+>24 leshort 0407 executable
+>24 leshort 0410 pure
+>24 leshort 0413 demand paged
+>8 long >0 not stripped
+>8 long 0 stripped
+>23 leshort >0 - version %ld.
+# linux Kernel images version 1.3.80 - ?
+# from Axel Kohlmeyer <akohlmey@rincewind.chemie.uni-ulm.de>
+0 belong 0xb8c0078e Linux/x86 kernel image,
+>0x048c byte 0x31
+>>0x048c string x version %s
+>0x0493 byte 0x31
+>>0x0493 string x version %s
+#
--- /dev/null
+
+#------------------------------------------------------------------------------
+# lisp: file(1) magic for lisp programs
+#
+# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com)
+0 string ;; Lisp/Scheme program text
+# Emacs 18 - this is always correct, but not very magical.
+0 string \012( byte-compiled Emacs-Lisp program data
+# Emacs 19
+0 string ;ELC\023\000\000\000 byte-compiled Emacs-Lisp program data
--- /dev/null
+#------------------------------------------------------------------------------
+# mach file description
+#
+# Since Java bytecode and Mach-O fat-files have the same magic number the test
+# must be preformed in the same "magic" sequence to get both right. The long
+# at offset 4 in a fat file tells the number of architectures. The short at
+# offset 4 in a Java bytecode file is the compiler minor version and the
+# short at offset 6 is the compiler major version. Since the minor version is
+# never to be non-zero then the hack of testing for the number of architectures
+# to be less that the maximum short is done here.
+#
+0 belong 0xcafebabe
+>4 belong 0x0003002d Java bytecode
+>4 belong 1 Mach-O fat file with 1 architecture
+>4 belong >1
+>>4 belong <0xffff Mach-O fat file with %ld architectures
+#
+0 lelong 0xfeedface Mach-O
+>12 lelong 1 object
+>12 lelong 2 executable
+>12 lelong 3 fixed virtual memory shared library
+>12 lelong 4 core
+>12 lelong 5 preload executable
+>12 lelong 6 dynamically linked shared library
+>12 lelong 7 dynamic linker
+>12 lelong 8 bundle
+>12 lelong >8
+>>12 lelong x filetype=%ld
+>4 lelong <0
+>>4 lelong x architecture=%ld
+>4 lelong 1 vax
+>4 lelong 2 romp
+>4 lelong 3 architecture=3
+>4 lelong 4 ns32032
+>4 lelong 5 ns32332
+>4 lelong 6 m68k
+>4 lelong 7 i386
+>4 lelong 8 mips
+>4 lelong 9 ns32532
+>4 lelong 10 architecture=10
+>4 lelong 11 hppa
+>4 lelong 12 acorn
+>4 lelong 13 m88k
+>4 lelong 14 sparc
+>4 lelong 15 i860-big
+>4 lelong 16 i860
+>4 lelong 17 rs6000
+>4 lelong 18 ppc
+>4 lelong >18
+>>4 lelong x architecture=%ld
+#
+0 belong 0xfeedface Mach-O
+>12 belong 1 object
+>12 belong 2 executable
+>12 belong 3 fixed virtual memory shared library
+>12 belong 4 core
+>12 belong 5 preload executable
+>12 belong 6 dynamically linked shared library
+>12 belong 7 dynamic linker
+>12 belong 8 bundle
+>12 belong >8
+>>12 belong x filetype=%ld
+>4 belong <0
+>>4 belong x architecture=%ld
+>4 belong 1 vax
+>4 belong 2 romp
+>4 belong 3 architecture=3
+>4 belong 4 ns32032
+>4 belong 5 ns32332
+>4 belong 6 m68k
+>4 belong 7 i386
+>4 belong 8 mips
+>4 belong 9 ns32532
+>4 belong 10 architecture=10
+>4 belong 11 hppa
+>4 belong 12 acorn
+>4 belong 13 m88k
+>4 belong 14 sparc
+>4 belong 15 i860-big
+>4 belong 16 i860
+>4 belong 17 rs6000
+>4 belong 18 ppc
+>4 belong >18
+>>4 belong x architecture=%ld
--- /dev/null
+
+#------------------------------------------------------------------------------
+# macintosh: file(1) magic for Apple Macintosh file formats
+
+# Stuffit archives are the de facto standard of compression for Macintosh
+# files obtained from most archives. (franklsm@tuns.ca)
+0 string SIT! StuffIt Archive (data)
+>2 string x : %s
+65 string SIT! StuffIt Archive (rsrc + data)
+>2 string x : %s
+0 string SITD StuffIt Deluxe (data)
+>2 string x : %s
+65 string SITD StuffIt Deluxe (rsrc + data)
+>2 string x : %s
+0 string Seg StuffIt Deluxe Segment (data)
+>2 string x : %s
+65 string Seg StuffIt Deluxe Segment (rsrc + data)
+>2 string x : %s
+
+# Macintosh Applications and Installation binaries (franklsm@tuns.ca)
+0 string APPL Macintosh Application (data)
+>2 string x : %s
+65 string APPL Macintosh Application (rsrc + data)
+>2 string x : %s
+
+# Macintosh System files (franklsm@tuns.ca)
+0 string zsys Macintosh System File (data)
+65 string zsys Macintosh System File(rsrc + data)
+0 string FNDR Macintosh Finder (data)
+65 string FNDR Macintosh Finder(rsrc + data)
+0 string libr Macintosh Library (data)
+>2 string x : %s
+65 string libr Macintosh Library(rsrc + data)
+>2 string x : %s
+0 string shlb Macintosh Shared Library (data)
+>2 string x : %s
+65 string shlb Macintosh Shared Library(rsrc + data)
+>2 string x : %s
+0 string cdev Macintosh Control Panel (data)
+>2 string x : %s
+65 string cdev Macintosh Control Panel(rsrc + data)
+>2 string x : %s
+0 string INIT Macintosh Extension (data)
+>2 string x : %s
+65 string INIT Macintosh Extension(rsrc + data)
+>2 string x : %s
+0 string FFIL Macintosh Truetype Font (data)
+>2 string x : %s
+65 string FFIL Macintosh Truetype Font(rsrc + data)
+>2 string x : %s
+0 string LWFN Macintosh Postscript Font (data)
+>2 string x : %s
+65 string LWFN Macintosh Postscript Font(rsrc + data)
+>2 string x : %s
+
+# Additional Macintosh Files (franklsm@tuns.ca)
+0 string PACT Macintosh Compact Pro Archive (data)
+>2 string x : %s
+65 string PACT Macintosh Compact Pro Archive(rsrc + data)
+>2 string x : %s
+0 string ttro Macintosh TeachText File (data)
+>2 string x : %s
+65 string ttro Macintosh TeachText File(rsrc + data)
+>2 string x : %s
+0 string TEXT Macintosh TeachText File (data)
+>2 string x : %s
+65 string TEXT Macintosh TeachText File(rsrc + data)
+>2 string x : %s
+0 string PDF Macintosh PDF File (data)
+>2 string x : %s
+65 string PDF Macintosh PDF File(rsrc + data)
+>2 string x : %s
--- /dev/null
+
+#------------------------------------------------------------------------------
+# magic: file(1) magic for magic files
+#
+0 string #\ Magic magic text file for file(1) cmd
--- /dev/null
+
+#------------------------------------------------------------------------------
+# mail.news: file(1) magic for mail and news
+#
+# Unfortunately, saved netnews also has From line added in some news software.
+#0 string From mail text
+# There are tests to ascmagic.c to cope with mail and news.
+0 string Relay-Version: old news text
+0 string #!\ rnews batched news text
+0 string N#!\ rnews mailed, batched news text
+0 string Forward\ to mail forwarding text
+0 string Pipe\ to mail piping text
+0 string Return-Path: smtp mail text
+0 string Path: news text
+0 string Xref: news text
+0 string From: news or mail text
+0 string Article saved news text
+0 string BABYL Emacs RMAIL text
+0 string Received: RFC 822 mail text
+0 string MIME-Version: MIME entity text
+0 string Content- MIME entity text
--- /dev/null
+#------------------------------------------------------------------------------
+# mime: file(1) magic for MIME encoded files
+#
+0 string Content-Type:\
+>14 string >\0 %s
+0 string Content-Type:
+>13 string >\0 %s
--- /dev/null
+
+#------------------------------------------------------------------------------
+# mirage: file(1) magic for Mirage executables
+#
+# XXX - byte order?
+#
+0 long 31415 Mirage Assembler m.out executable
--- /dev/null
+
+#------------------------------------------------------------------------------
+# mkid: file(1) magic for mkid(1) databases
+#
+# ID is the binary tags database produced by mkid(1).
+#
+# XXX - byte order?
+#
+0 string \311\304 ID tags data
+>2 short >0 version %d
--- /dev/null
+
+#------------------------------------------------------------------------------
+# mmdf: file(1) magic for MMDF mail files
+#
+0 string \001\001\001\001 MMDF mailbox
--- /dev/null
+#------------------------------------------------------------------------------
+# modem: file(1) magic for modem programs
+#
+# From: Florian La Roche <florian@knorke.saar.de>
+4 string Research, Digifax-G3-File
+>29 byte 1 , fine resolution
+>29 byte 0 , normal resolution
+
+0 short 0x0100 raw G3 data, byte-padded
+0 short 0x1400 raw G3 data
+#
+# Magic data for vgetty voice formats
+# (Martin Seine & Marc Eberhard)
+
+#
+# raw modem data version 1
+#
+0 string RMD1 raw modem data
+>4 string >\0 (%s /
+>20 short >0 compression type 0x%04x)
+
+#
+# portable voice format 1
+#
+0 string PVF1\n portable voice format
+>5 string >\0 (binary %s)
+
+#
+# portable voice format 2
+#
+0 string PVF2\n portable voice format
+>5 string >\0 (ascii %s)
+
--- /dev/null
+
+#------------------------------------------------------------------------------
+# motorola: file(1) magic for Motorola 68K and 88K binaries
+#
+# 68K
+#
+0 beshort 0520 mc68k COFF
+>18 beshort ^00000020 object
+>18 beshort &00000020 executable
+>12 belong >0 not stripped
+>168 string .lowmem Apple toolbox
+>20 beshort 0407 (impure)
+>20 beshort 0410 (pure)
+>20 beshort 0413 (demand paged)
+>20 beshort 0421 (standalone)
+0 beshort 0521 mc68k executable (shared)
+>12 belong >0 not stripped
+0 beshort 0522 mc68k executable (shared demand paged)
+>12 belong >0 not stripped
+#
+# Motorola/UniSoft 68K Binary Compatibility Standard (BCS)
+#
+0 beshort 0554 68K BCS executable
+#
+# 88K
+#
+# Motorola/88Open BCS
+#
+0 beshort 0555 88K BCS executable
+#
+# Motorola S-Records, from Gerd Truschinski <gt@freebsd.first.gmd.de>
+0 string S0 Motorola S-Record; binary data in text format
--- /dev/null
+
+#------------------------------------------------------------------------------
+# msdos: file(1) magic for MS-DOS files
+#
+
+# .BAT files (Daniel Quinlan, quinlan@yggdrasil.com)
+0 string @echo\ off MS-DOS batch file text
+
+# .EXE formats (Greg Roelofs, newt@uchicago.edu)
+#
+0 string MZ MS-DOS executable (EXE)
+>24 string @ \b, OS/2 or Windows
+>1638 string -lh5- \b, LHa SFX archive v2.13S
+>7195 string Rar! \b, RAR self-extracting archive
+#
+# [GRR 950118: file 3.15 has a buffer-size limitation; offsets bigger than
+# 8161 bytes are ignored. To make the following entries work, increase
+# HOWMANY in file.h to 32K at least, and maybe to 70K or more for OS/2,
+# NT/Win32 and VMS.]
+# [GRR: some company sells a self-extractor/displayer for image data(!)]
+#
+>11696 string PK\003\004 \b, PKZIP SFX archive v1.1
+>13297 string PK\003\004 \b, PKZIP SFX archive v1.93a
+>15588 string PK\003\004 \b, PKZIP2 SFX archive v1.09
+>15770 string PK\003\004 \b, PKZIP SFX archive v2.04g
+>28374 string PK\003\004 \b, PKZIP2 SFX archive v1.02
+#
+# Info-ZIP self-extractors
+# these are the DOS versions:
+>25115 string PK\003\004 \b, Info-ZIP SFX archive v5.12
+>26331 string PK\003\004 \b, Info-ZIP SFX archive v5.12 w/decryption
+# these are the OS/2 versions (OS/2 is flagged above):
+>47031 string PK\003\004 \b, Info-ZIP SFX archive v5.12
+>49845 string PK\003\004 \b, Info-ZIP SFX archive v5.12 w/decryption
+# this is the NT/Win32 version:
+>69120 string PK\003\004 \b, Info-ZIP NT SFX archive v5.12 w/decryption
+#
+# TELVOX Teleinformatica CODEC self-extractor for OS/2:
+>49801 string \x79\xff\x80\xff\x76\xff \b, CODEC archive v3.21
+>>49824 leshort =1 \b, 1 file
+>>49824 leshort >1 \b, %u files
+
+# .COM formats (Daniel Quinlan, quinlan@yggdrasil.com)
+# Uncommenting only the first two lines will cover about 2/3 of COM files,
+# but it isn't feasible to match all COM files since there must be at least
+# two dozen different one-byte "magics".
+#0 byte 0xe9 MS-DOS executable (COM)
+#0 byte 0x8c MS-DOS executable (COM)
+# 0xeb conflicts with "sequent" magic
+#0 byte 0xeb MS-DOS executable (COM)
+#0 byte 0xb8 MS-DOS executable (COM)
+
+# miscellaneous formats
+0 string LZ MS-DOS executable (built-in)
+#0 byte 0xf0 MS-DOS program library data
+#
+
+# Popular applications
+2080 string Microsoft\ Word\ 6.0\ Document %s
+#
+0 belong 0x31be0000 Microsoft Word Document
+#
+2080 string Microsoft\ Excel\ 5.0\ Worksheet %s
+#
+0 belong 0x00001a00 Lotus 1-2-3
+>4 belong 0x00100400 wk3 document
+>4 belong 0x02100400 wk4 document
+>4 belong 0x07800100 fm3 or fmb document
+>4 belong 0x07800000 fm3 or fmb document
+#
+0 belong 0x00000200 Lotus 1-2-3
+>4 belong 0x06040600 wk1 document
+>4 belong 0x06800200 fmt document
--- /dev/null
+
+#------------------------------------------------------------------------------
+# ncr: file(1) magic for NCR Tower objects
+#
+# contributed by
+# Michael R. Wayne *** TMC & Associates *** INTERNET: wayne@ford-vax.arpa
+# uucp: {philabs | pyramid} !fmsrl7!wayne OR wayne@fmsrl7.UUCP
+#
+0 beshort 000610 Tower/XP rel 2 object
+>12 belong >0 not stripped
+>20 beshort 0407 executable
+>20 beshort 0410 pure executable
+>22 beshort >0 - version %ld
+0 beshort 000615 Tower/XP rel 2 object
+>12 belong >0 not stripped
+>20 beshort 0407 executable
+>20 beshort 0410 pure executable
+>22 beshort >0 - version %ld
+0 beshort 000620 Tower/XP rel 3 object
+>12 belong >0 not stripped
+>20 beshort 0407 executable
+>20 beshort 0410 pure executable
+>22 beshort >0 - version %ld
+0 beshort 000625 Tower/XP rel 3 object
+>12 belong >0 not stripped
+>20 beshort 0407 executable
+>20 beshort 0410 pure executable
+>22 beshort >0 - version %ld
+0 beshort 000630 Tower32/600/400 68020 object
+>12 belong >0 not stripped
+>20 beshort 0407 executable
+>20 beshort 0410 pure executable
+>22 beshort >0 - version %ld
+0 beshort 000640 Tower32/800 68020
+>18 beshort &020000 w/68881 object
+>18 beshort &040000 compatible object
+>18 beshort &~060000 object
+>20 beshort 0407 executable
+>20 beshort 0413 pure executable
+>12 belong >0 not stripped
+>22 beshort >0 - version %ld
+0 beshort 000645 Tower32/800 68010
+>18 beshort &040000 compatible object
+>18 beshort &~060000 object
+>20 beshort 0407 executable
+>20 beshort 0413 pure executable
+>12 belong >0 not stripped
+>22 beshort >0 - version %ld
--- /dev/null
+
+#------------------------------------------------------------------------------
+# netbsd: file(1) magic for NetBSD objects
+#
+# All new-style magic numbers are in network byte order.
+#
+
+0 lelong 000000407 NetBSD little-endian object file
+>16 lelong >0 not stripped
+0 belong 000000407 NetBSD big-endian object file
+>16 belong >0 not stripped
+
+0 belong&0377777777 041400413 NetBSD/i386 demand paged
+>0 byte &0x80
+>>20 lelong <4096 shared library
+>>20 lelong =4096 dynamically linked executable
+>>20 lelong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 041400410 NetBSD/i386 pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 041400407 NetBSD/i386
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 041400507 NetBSD/i386 core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 041600413 NetBSD/m68k demand paged
+>0 byte &0x80
+>>20 belong <8192 shared library
+>>20 belong =8192 dynamically linked executable
+>>20 belong >8192 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 041600410 NetBSD/m68k pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 041600407 NetBSD/m68k
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 belong !0 executable
+>>20 belong =0 object file
+>16 belong >0 not stripped
+0 belong&0377777777 041600507 NetBSD/m68k core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 042000413 NetBSD/m68k4k demand paged
+>0 byte &0x80
+>>20 belong <4096 shared library
+>>20 belong =4096 dynamically linked executable
+>>20 belong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 042000410 NetBSD/m68k4k pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 042000407 NetBSD/m68k4k
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 belong !0 executable
+>>20 belong =0 object file
+>16 belong >0 not stripped
+0 belong&0377777777 042000507 NetBSD/m68k4k core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 042200413 NetBSD/ns32532 demand paged
+>0 byte &0x80
+>>20 lelong <4096 shared library
+>>20 lelong =4096 dynamically linked executable
+>>20 lelong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 042200410 NetBSD/ns32532 pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 042200407 NetBSD/ns32532
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 042200507 NetBSD/ns32532 core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 042400413 NetBSD/sparc demand paged
+>0 byte &0x80
+>>20 belong <8192 shared library
+>>20 belong =8192 dynamically linked executable
+>>20 belong >8192 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 042400410 NetBSD/sparc pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 042400407 NetBSD/sparc
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 belong !0 executable
+>>20 belong =0 object file
+>16 belong >0 not stripped
+0 belong&0377777777 042400507 NetBSD/sparc core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 042600413 NetBSD/pmax demand paged
+>0 byte &0x80
+>>20 lelong <4096 shared library
+>>20 lelong =4096 dynamically linked executable
+>>20 lelong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 042600410 NetBSD/pmax pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 042600407 NetBSD/pmax
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 042600507 NetBSD/pmax core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 043000413 NetBSD/vax demand paged
+>0 byte &0x80
+>>20 lelong <4096 shared library
+>>20 lelong =4096 dynamically linked executable
+>>20 lelong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 043000410 NetBSD/vax pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 043000407 NetBSD/vax
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 043000507 NetBSD/vax core
+>12 string >\0 from '%s'
+
+# NetBSD/alpha does not support (and has never supported) a.out objects,
+# so no rules are provided for them. NetBSD/alpha ELF objects are
+# dealt with in "elf".
+0 lelong 0x00070185 ECOFF NetBSD/alpha binary
+>10 leshort 0x0001 not stripped
+>10 leshort 0x0000 stripped
+0 belong&0377777777 043200507 NetBSD/alpha core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 043400413 NetBSD/mips demand paged
+>0 byte &0x80
+>>20 belong <8192 shared library
+>>20 belong =8192 dynamically linked executable
+>>20 belong >8192 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 043400410 NetBSD/mips pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&0377777777 043400407 NetBSD/mips
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 belong !0 executable
+>>20 belong =0 object file
+>16 belong >0 not stripped
+0 belong&0377777777 043400507 NetBSD/mips core
+>12 string >\0 from '%s'
+
+0 belong&0377777777 043600413 NetBSD/arm32 demand paged
+>0 byte &0x80
+>>20 lelong <8192 shared library
+>>20 lelong =8192 dynamically linked executable
+>>20 lelong >8192 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 043600410 NetBSD/arm32 pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 lelong >0 not stripped
+0 belong&0377777777 043600407 NetBSD/arm32
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80
+>>0 byte &0x40 position independent
+>>20 lelong !0 executable
+>>20 lelong =0 object file
+>16 lelong >0 not stripped
+0 belong&0377777777 043600507 NetBSD/arm32 core
+>12 string >\0 from '%s'
--- /dev/null
+
+#------------------------------------------------------------------------------
+# news: file(1) magic for SunOS NeWS fonts (not "news" as in "netnews")
+#
+0 string StartFontMetrics ASCII font metrics
+0 string StartFont ASCII font bits
+0 belong 0x137A2944 NeWS bitmap font
+0 belong 0x137A2947 NeWS font family
+0 belong 0x137A2950 scalable OpenFont binary
+0 belong 0x137A2951 encrypted scalable OpenFont binary
+8 belong 0x137A2B45 X11/NeWS bitmap font
+8 belong 0x137A2B48 X11/NeWS font family
--- /dev/null
+#------------------------------------------------------------------------------
+# octave binary data file(1) magic, from Dirk Eddelbuettel <edd@debian.org>
+0 string Octave-1-L Octave binary data (little endian)
+0 string Octave-1-B Octave binary data (big endian)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# olf: file(1) magic for OLF executables
+#
+# We have to check the byte order flag to see what byte order all the
+# other stuff in the header is in.
+#
+# Byte order is probably big-endian for MIPS R3000 and Amdahl.
+# MIPS R3000 may also be for MIPS R2000.
+#
+# Created by Erik Theisen <etheisen@openbsd.org>
+# Based on elf from Daniel Quinlan <quinlan@yggdrasil.com>
+0 string \177OLF OLF
+>4 byte 0 invalid class
+>4 byte 1 32-bit
+>4 byte 2 64-bit
+>7 byte 0 invalid os
+>7 byte 1 OpenBSD
+>7 byte 2 NetBSD
+>7 byte 3 FreeBSD
+>7 byte 4 4.4BSD
+>7 byte 5 Linux
+>7 byte 6 Mach
+>7 byte 7 SVR4
+>7 byte 8 esix
+>7 byte 9 Solaris
+>7 byte 10 Irix
+>7 byte 11 SCO
+>7 byte 12 Dell
+>8 byte 1 dynamically linked
+>9 byte 1 unstripped
+>5 byte 0 invalid byte order
+>5 byte 1 LSB
+>>16 leshort 0 no file type,
+>>16 leshort 1 relocatable,
+>>16 leshort 2 executable,
+>>16 leshort 3 shared object,
+>>16 leshort 4 core file,
+>>16 leshort &0xff00 processor-specific,
+>>18 leshort 0 no machine,
+>>18 leshort 1 AT&T WE32100 - invalid byte order,
+>>18 leshort 2 SPARC - invalid byte order,
+>>18 leshort 3 Intel 80386,
+>>18 leshort 4 Motorola 68000 - invalid byte order,
+>>18 leshort 5 Motorola 88000 - invalid byte order,
+>>18 leshort 6 Intel 80486,
+>>18 leshort 7 Intel 80860,
+>>18 leshort 8 MIPS R3000,
+>>18 leshort 9 Amdahl,
+>>20 lelong 0 invalid version
+>>20 lelong 1 version 1
+>>36 lelong 1 MathCoPro/FPU/MAU Required
+>5 byte 2 MSB
+>>16 beshort 0 no file type,
+>>16 beshort 1 relocatable,
+>>16 beshort 2 executable,
+>>16 beshort 3 shared object,
+>>16 beshort 4 core file,
+>>16 beshort &0xff00 processor-specific,
+>>18 beshort 0 no machine,
+>>18 beshort 1 AT&T WE32100,
+>>18 beshort 2 SPARC,
+>>18 beshort 3 Intel 80386 - invalid byte order,
+>>18 beshort 4 Motorola 68000,
+>>18 beshort 5 Motorola 88000,
+>>18 beshort 6 Intel 80486 - invalid byte order,
+>>18 beshort 7 Intel 80860,
+>>18 beshort 8 MIPS R3000,
+>>18 leshort 9 Amdahl,
+>>20 belong 0 invalid version
+>>20 belong 1 version 1
+>>36 belong 1 MathCoPro/FPU/MAU Required
--- /dev/null
+
+#------------------------------------------------------------------------------
+# os2: file(1) magic for OS/2 files
+#
+
+# Provided 1998/08/22 by
+# David Mediavilla <davidme.news@REMOVEIFNOTSPAMusa.net>
+1 string InternetShortcut MS Windows 95 Internet shortcut text
+>24 string >\ (URL=<%s>)
+
+# OS/2 URL objects
+# Provided 1998/08/22 by
+# David Mediavilla <davidme.news@REMOVEIFNOTSPAMusa.net>
+0 string http: OS/2 URL object text
+>5 string >\ (WWW) <http:%s>
+0 string mailto: OS/2 URL object text
+>7 string >\ (email) <%s>
+0 string news: OS/2 URL object text
+>5 string >\ (Usenet) <%s>
+0 string ftp: OS/2 URL object text
+>4 string >\ (FTP) <ftp:%s>
+0 string file: OS/2 URL object text
+>5 string >\ (Local file) <%s>
--- /dev/null
+#
+# $OpenBSD: os9,v 1.2 1996/06/26 05:33:04 deraadt Exp $
+# $NetBSD: os9,v 1.1 1996/05/06 18:24:01 is Exp $
+#
+# Copyright (c) 1996 Ignatios Souvatzis. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by Ignatios Souvatzis for
+# the NetBSD project.
+# 4. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#
+#
+# OS9/6809 module descriptions:
+#
+0 beshort 0x87CD OS9/6809 module:
+#
+>6 byte&0x0f 0x00 non-executable
+>6 byte&0x0f 0x01 machine language
+>6 byte&0x0f 0x02 BASIC I-code
+>6 byte&0x0f 0x03 P-code
+>6 byte&0x0f 0x04 C I-code
+>6 byte&0x0f 0x05 COBOL I-code
+>6 byte&0x0f 0x06 FORTRAN I-code
+#
+>6 byte&0xf0 0x10 program executable
+>6 byte&0xf0 0x20 subroutine
+>6 byte&0xf0 0x30 multi-module
+>6 byte&0xf0 0x40 data module
+#
+>6 byte&0xf0 0xC0 system module
+>6 byte&0xf0 0xD0 file manager
+>6 byte&0xf0 0xE0 device driver
+>6 byte&0xf0 0xF0 device descriptor
+#
+# OS9/m68k stuff (to be continued)
+#
+0 beshort 0x4AFC OS9/68K module:
+#
+# attr
+>14 byte&0x80 0x80 re-entrant
+>14 byte&0x40 0x40 ghost
+>14 byte&0x20 0x20 system-state
+#
+# lang:
+#
+>13 byte 1 machine language
+>13 byte 2 BASIC I-code
+>13 byte 3 P-code
+>13 byte 4 C I-code
+>13 byte 5 COBOL I-code
+>13 byte 6 Fortran I-code
+#
+#
+# type:
+#
+>12 byte 1 program executable
+>12 byte 2 subroutine
+>12 byte 3 multi-module
+>12 byte 4 data module
+>12 byte 11 trap library
+>12 byte 12 system module
+>12 byte 13 file manager
+>12 byte 14 device driver
+>12 byte 15 device descriptor
--- /dev/null
+#
+# Mach magic number info
+#
+0 long 0xefbe OSF/Rose object
+# I386 magic number info
+#
+0 short 0565 i386 COFF object
--- /dev/null
+
+#------------------------------------------------------------------------------
+# pbm: file(1) magic for Portable Bitmap files
+#
+# XXX - byte order?
+#
+0 short 0x2a17 "compact bitmap" format (Poskanzer)
--- /dev/null
+#------------------------------------------------------------------------------
+# pdf: file(1) magic for Portable Document Format
+#
+
+0 string %PDF- PDF document
+>5 byte x \b, version %c
+>7 byte x \b.%c
--- /dev/null
+
+#------------------------------------------------------------------------------
+# pdp: file(1) magic for PDP-11 executable/object and APL workspace
+#
+0 lelong 0101555 PDP-11 single precision APL workspace
+0 lelong 0101554 PDP-11 double precision APL workspace
+#
+# PDP-11 a.out
+#
+0 leshort 0407 PDP-11 executable
+>8 leshort >0 not stripped
+>15 byte >0 - version %ld
+
+0 leshort 0401 PDP-11 UNIX/RT ldp
+0 leshort 0405 PDP-11 old overlay
+
+0 leshort 0410 PDP-11 pure executable
+>8 leshort >0 not stripped
+>15 byte >0 - version %ld
+
+0 leshort 0411 PDP-11 separate I&D executable
+>8 leshort >0 not stripped
+>15 byte >0 - version %ld
+
+0 leshort 0437 PDP-11 kernel overlay
--- /dev/null
+
+#------------------------------------------------------------------------------
+# pgp: file(1) magic for Pretty Good Privacy
+#
+0 beshort 0x9900 PGP key public ring
+0 beshort 0x9501 PGP key security ring
+0 beshort 0x9500 PGP key security ring
+0 beshort 0xa600 PGP encrypted data
+0 string -----BEGIN\040PGP PGP armored data
+>15 string PUBLIC\040KEY\040BLOCK- public key block
+>15 string MESSAGE- message
+>15 string SIGNED\040MESSAGE- signed message
+>15 string PGP\040SIGNATURE- signature
--- /dev/null
+
+#------------------------------------------------------------------------------
+# pkgadd: file(1) magic for SysV R4 PKG Datastreams
+#
+0 string #\ PaCkAgE\ DaTaStReAm pkg Datastream (SVR4)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# plus5: file(1) magic for Plus Five's UNIX MUMPS
+#
+# XXX - byte order? Paging Hokey....
+#
+0 short 0x259 mumps avl global
+>2 byte >0 (V%d)
+>6 byte >0 with %d byte name
+>7 byte >0 and %d byte data cells
+0 short 0x25a mumps blt global
+>2 byte >0 (V%d)
+>8 short >0 - %d byte blocks
+>15 byte 0x00 - P/D format
+>15 byte 0x01 - P/K/D format
+>15 byte 0x02 - K/D format
+>15 byte >0x02 - Bad Flags
--- /dev/null
+
+#------------------------------------------------------------------------------
+# printer: file(1) magic for printer-formatted files
+#
+
+# PostScript, updated by Daniel Quinlan (quinlan@yggdrasil.com)
+0 string %! PostScript document text
+>2 string PS-Adobe- conforming
+>>11 string >\0 at level %.3s
+>>>15 string EPS - type %s
+>>>15 string Query - type %s
+>>>15 string ExitServer - type %s
+# Some PCs have the annoying habit of adding a ^D as a document separator
+0 string \004%! PostScript document text
+>3 string PS-Adobe- conforming
+>>12 string >\0 at level %.3s
+>>>16 string EPS - type %s
+>>>16 string Query - type %s
+>>>16 string ExitServer - type %s
+
+# HP Printer Job Language
+0 string \033%-12345X@PJL HP Printer Job Language data
+>15 string \ ENTER\ LANGUAGE\ =
+>31 string PostScript PostScript
+
+# HP Printer Control Language, Daniel Quinlan (quinlan@yggdrasil.com)
+0 string \033E\033 HP PCL printer data
+>3 string \&l0A - default page size
+>3 string \&l1A - US executive page size
+>3 string \&l2A - US letter page size
+>3 string \&l3A - US legal page size
+>3 string \&l26A - A4 page size
+>3 string \&l80A - Monarch envelope size
+>3 string \&l81A - No. 10 envelope size
+>3 string \&l90A - Intl. DL envelope size
+>3 string \&l91A - Intl. C5 envelope size
+>3 string \&l100A - Intl. B5 envelope size
+>3 string \&l-81A - No. 10 envelope size (landscape)
+>3 string \&l-90A - Intl. DL envelope size (landscape)
+
+# IMAGEN printer-ready files:
+0 string @document( Imagen printer
+# this only works if "language xxx" is first item in Imagen header.
+>10 string language\ impress (imPRESS data)
+>10 string language\ daisy (daisywheel text)
+>10 string language\ diablo (daisywheel text)
+>10 string language\ printer (line printer emulation)
+>10 string language\ tektronix (Tektronix 4014 emulation)
+# Add any other languages that your Imagen uses - remember
+# to keep the word `text' if the file is human-readable.
+# [GRR 950115: missing "postscript" or "ultrascript" (whatever it was called)]
+#
+# Now magic for IMAGEN font files...
+0 string Rast RST-format raster font data
+>45 string >0 face %
--- /dev/null
+
+#------------------------------------------------------------------------------
+# psdbms: file(1) magic for psdatabase
+#
+0 belong&0xff00ffff 0x56000000 ps database
+>1 string >\0 version %s
+>4 string >\0 from kernel %s
--- /dev/null
+
+#------------------------------------------------------------------------------
+# pyramid: file(1) magic for Pyramids
+#
+# XXX - byte order?
+#
+0 long 0x50900107 Pyramid 90x family executable
+0 long 0x50900108 Pyramid 90x family pure executable
+>16 long >0 not stripped
+0 long 0x5090010b Pyramid 90x family demand paged pure executable
+>16 long >0 not stripped
--- /dev/null
+
+#------------------------------------------------------------------------------
+# riff: file(1) magic for RIFF format
+# See
+#
+# http://www.seanet.com/users/matts/riffmci/riffmci.htm
+#
+# and
+#
+# http://www.ora.com/centers/gff/formats/micriff/index.htm
+#
+# and
+#
+# http://www.jtauber.com/music/encoding/niff/spec/
+#
+0 string RIFF RIFF (little-endian) data
+# RIFF Palette format
+>8 string PAL \b, palette
+>>16 leshort x \b, version %d
+>>18 leshort x \b, %d entries
+# RIFF Device Independent Bitmap format
+>8 string RDIB \b, device-independent bitmap
+>>16 string BM
+>>>30 leshort 12 \b, OS/2 1.x format
+>>>>34 leshort x \b, %d x
+>>>>36 leshort x %d
+>>>30 leshort 64 \b, OS/2 2.x format
+>>>>34 leshort x \b, %d x
+>>>>36 leshort x %d
+>>>30 leshort 40 \b, Windows 3.x format
+>>>>34 lelong x \b, %d x
+>>>>38 lelong x %d x
+>>>>44 leshort x %d
+# RIFF MIDI format
+>8 string RMID \b, MIDI
+# RIFF Multimedia Movie File format
+>8 string RMMP \b, multimedia movie
+# Microsoft WAVE format (*.wav)
+>8 string WAVE \b, WAVE audio
+>>20 leshort 1 \b, Microsoft PCM
+>>>34 leshort >0 \b, %d bit
+>>22 leshort =1 \b, mono
+>>22 leshort =2 \b, stereo
+>>22 leshort >2 \b, %d channels
+>>24 lelong >0 %d Hz
+# AVI == Audio Video Interleave
+>8 string AVI\ \b, AVI
+# Animated Cursor format
+>8 string ACON \b, animated cursor
+
+#
+# XXX - some of the below may only appear in little-endian form.
+#
+# Also "MV93" appears to be for one form of Macromedia Director
+# files, and "GDMF" appears to be another multimedia format.
+#
+0 string RIFX RIFF (big-endian) data
+# RIFF Palette format
+>8 string PAL \b, palette
+>>16 beshort x \b, version %d
+>>18 beshort x \b, %d entries
+# RIFF Device Independent Bitmap format
+>8 string RDIB \b, device-independent bitmap
+>>16 string BM
+>>>30 beshort 12 \b, OS/2 1.x format
+>>>>34 beshort x \b, %d x
+>>>>36 beshort x %d
+>>>30 beshort 64 \b, OS/2 2.x format
+>>>>34 beshort x \b, %d x
+>>>>36 beshort x %d
+>>>30 beshort 40 \b, Windows 3.x format
+>>>>34 belong x \b, %d x
+>>>>38 belong x %d x
+>>>>44 beshort x %d
+# RIFF MIDI format
+>8 string RMID \b, MIDI
+# RIFF Multimedia Movie File format
+>8 string RMMP \b, multimedia movie
+# Microsoft WAVE format (*.wav)
+>8 string WAVE \b, WAVE audio
+>>20 leshort 1 \b, Microsoft PCM
+>>>34 leshort >0 \b, %d bit
+>>22 beshort =1 \b, mono
+>>22 beshort =2 \b, stereo
+>>22 beshort >2 \b, %d channels
+>>24 belong >0 %d Hz
+# AVI == Audio Video Interleave
+>8 string AVI\ \b, AVI
+# Animated Cursor format
+>8 string ACON \b, animated cursor
+# Notation Interchange File Format (big-endian only)
+>8 string NIFF \b, Notation Interchange File Format
+
--- /dev/null
+#------------------------------------------------------------------------------
+#
+# RPM: file(1) magic for Red Hat Packages Erik Troan (ewt@redhat.com)
+#
+0 beshort 0xedab
+>2 beshort 0xeedb RPM
+>>4 byte x v%d
+>>6 beshort 0 bin
+>>6 beshort 1 src
+>>8 beshort 1 i386
+>>8 beshort 2 Alpha
+>>8 beshort 3 Sparc
+>>8 beshort 4 MIPS
+>>8 beshort 5 PowerPC
+>>8 beshort 6 68000
+>>8 beshort 7 SGI
+>>10 string x %s
--- /dev/null
+
+#------------------------------------------------------------------------------
+# rtf: file(1) magic for Rich Text Format (RTF)
+#
+# Duncan P. Simpson, D.P.Simpson@dcs.warwick.ac.uk
+#
+0 string {\\rtf Rich Text Format data,
+>5 byte x version %c,
+>6 string \\ansi ANSI
+>6 string \\mac Apple Macintosh
+>6 string \\pc IBM PC, code page 437
+>6 string \\pca IBM PS/2, code page 850
--- /dev/null
+
+#------------------------------------------------------------------------------
+# sc: file(1) magic for "sc" spreadsheet
+#
+38 string Spreadsheet sc spreadsheet file
--- /dev/null
+
+#------------------------------------------------------------------------------
+# sccs: file(1) magic for SCCS archives
+#
+# SCCS archive structure:
+# \001h01207
+# \001s 00276/00000/00000
+# \001d D 1.1 87/09/23 08:09:20 ian 1 0
+# \001c date and time created 87/09/23 08:09:20 by ian
+# \001e
+# \001u
+# \001U
+# ... etc.
+# Now '\001h' happens to be the same as the 3B20's a.out magic number (0550).
+# *Sigh*. And these both came from various parts of the USG.
+# Maybe we should just switch everybody from SCCS to RCS!
+# Further, you can't just say '\001h0', because the five-digit number
+# is a checksum that could (presumably) have any leading digit,
+# and we don't have regular expression matching yet.
+# Hence the following official kludge:
+8 string \001s\ SCCS archive data
--- /dev/null
+
+#------------------------------------------------------------------------------
+# sendmail: file(1) magic for sendmail config files
+#
+# XXX - byte order?
+#
+0 byte 046 Sendmail frozen configuration
+>16 string >\0 - version %s
+0 short 0x271c Sendmail frozen configuration
+>16 string >\0 - version %s
--- /dev/null
+
+#------------------------------------------------------------------------------
+# sequent: file(1) magic for Sequent machines
+#
+# Sequent information updated by Don Dwiggins <atsun!dwiggins>.
+# For Sequent's multiprocessor systems (incomplete).
+0 lelong 0x00ea BALANCE NS32000 .o
+>16 lelong >0 not stripped
+>124 lelong >0 version %ld
+0 lelong 0x10ea BALANCE NS32000 executable (0 @ 0)
+>16 lelong >0 not stripped
+>124 lelong >0 version %ld
+0 lelong 0x20ea BALANCE NS32000 executable (invalid @ 0)
+>16 lelong >0 not stripped
+>124 lelong >0 version %ld
+0 lelong 0x30ea BALANCE NS32000 standalone executable
+>16 lelong >0 not stripped
+>124 lelong >0 version %ld
+#
+# Symmetry information added by Jason Merrill <jason@jarthur.claremont.edu>.
+# Symmetry magic nums will not be reached if DOS COM comes before them;
+# byte 0xeb is matched before these get a chance.
+0 leshort 0x12eb SYMMETRY i386 .o
+>16 lelong >0 not stripped
+>124 lelong >0 version %ld
+0 leshort 0x22eb SYMMETRY i386 executable (0 @ 0)
+>16 lelong >0 not stripped
+>124 lelong >0 version %ld
+0 leshort 0x32eb SYMMETRY i386 executable (invalid @ 0)
+>16 lelong >0 not stripped
+>124 lelong >0 version %ld
+0 leshort 0x42eb SYMMETRY i386 standalone executable
+>16 lelong >0 not stripped
+>124 lelong >0 version %ld
--- /dev/null
+
+#------------------------------------------------------------------------------
+# sgi: file(1) magic for Silicon Graphics (MIPS, IRIS, IRIX, etc.)
+# Dec Ultrix (MIPS)
+# all of SGI's *current* machines and OSes run in big-endian mode on the
+# MIPS machines, as far as I know.
+#
+# XXX - what is the blank "-" line?
+#
+# kbd file definitions
+0 string kbd!map kbd map file
+>8 byte >0 Ver %d:
+>10 short >0 with %d table(s)
+0 belong 0407 old SGI 68020 executable
+0 belong 0410 old SGI 68020 pure executable
+0 beshort 0x8765 disk quotas file
+0 beshort 0x0506 IRIS Showcase file
+>2 byte 0x49 -
+>3 byte x - version %ld
+0 beshort 0x0226 IRIS Showcase template
+>2 byte 0x63 -
+>3 byte x - version %ld
+0 belong 0x5343464d IRIS Showcase file
+>4 byte x - version %ld
+0 belong 0x5443464d IRIS Showcase template
+>4 byte x - version %ld
+0 belong 0xdeadbabe IRIX Parallel Arena
+>8 belong >0 - version %ld
+#
+0 beshort 0x0160 MIPSEB COFF executable
+>20 beshort 0407 (impure)
+>20 beshort 0410 (swapped)
+>20 beshort 0413 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>22 byte x - version %ld
+>23 byte x \b.%ld
+#
+0 beshort 0x0162 MIPSEL COFF executable
+>20 beshort 0407 (impure)
+>20 beshort 0410 (swapped)
+>20 beshort 0413 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>23 byte x - version %d
+>22 byte x \b.%ld
+#
+0 beshort 0x6001 MIPSEB-LE COFF executable
+>20 beshort 03401 (impure)
+>20 beshort 04001 (swapped)
+>20 beshort 05401 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>23 byte x - version %d
+>22 byte x \b.%ld
+#
+0 beshort 0x6201 MIPSEL-LE COFF executable
+>20 beshort 03401 (impure)
+>20 beshort 04001 (swapped)
+>20 beshort 05401 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>23 byte x - version %ld
+>22 byte x \b.%ld
+#
+# MIPS 2 additions
+#
+0 beshort 0x0163 MIPSEB MIPS-II COFF executable
+>20 beshort 0407 (impure)
+>20 beshort 0410 (swapped)
+>20 beshort 0413 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>22 byte x - version %ld
+>23 byte x \b.%ld
+#
+0 beshort 0x0166 MIPSEL MIPS-II COFF executable
+>20 beshort 0407 (impure)
+>20 beshort 0410 (swapped)
+>20 beshort 0413 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>22 byte x - version %ld
+>23 byte x \b.%ld
+#
+0 beshort 0x6301 MIPSEB-LE MIPS-II COFF executable
+>20 beshort 03401 (impure)
+>20 beshort 04001 (swapped)
+>20 beshort 05401 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>23 byte x - version %ld
+>22 byte x \b.%ld
+#
+0 beshort 0x6601 MIPSEL-LE MIPS-II COFF executable
+>20 beshort 03401 (impure)
+>20 beshort 04001 (swapped)
+>20 beshort 05401 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>23 byte x - version %ld
+>22 byte x \b.%ld
+#
+# MIPS 3 additions
+#
+0 beshort 0x0140 MIPSEB MIPS-III COFF executable
+>20 beshort 0407 (impure)
+>20 beshort 0410 (swapped)
+>20 beshort 0413 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>22 byte x - version %ld
+>23 byte x \b.%ld
+#
+0 beshort 0x0142 MIPSEL MIPS-III COFF executable
+>20 beshort 0407 (impure)
+>20 beshort 0410 (swapped)
+>20 beshort 0413 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>22 byte x - version %ld
+>23 byte x \b.%ld
+#
+0 beshort 0x4001 MIPSEB-LE MIPS-III COFF executable
+>20 beshort 03401 (impure)
+>20 beshort 04001 (swapped)
+>20 beshort 05401 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>23 byte x - version %ld
+>22 byte x \b.%ld
+#
+0 beshort 0x4201 MIPSEL-LE MIPS-III COFF executable
+>20 beshort 03401 (impure)
+>20 beshort 04001 (swapped)
+>20 beshort 05401 (paged)
+>8 belong >0 not stripped
+>8 belong 0 stripped
+>23 byte x - version %ld
+>22 byte x \b.%ld
+#
+0 beshort 0x180 MIPSEB Ucode
+0 beshort 0x182 MIPSEL Ucode
+# 32bit core file
+0 belong 0xdeadadb0 IRIX core dump
+>4 belong 1 of
+>16 string >\0 '%s'
+# 64bit core file
+0 belong 0xdeadad40 IRIX 64-bit core dump
+>4 belong 1 of
+>16 string >\0 '%s'
+# New style crash dump file
+0 string \x43\x72\x73\x68\x44\x75\x6d\x70 IRIX vmcore dump of
+>36 string >\0 '%s'
+# Trusted IRIX info
+0 string SGIAUDIT SGI Audit file
+>8 byte x - version %d
+>9 byte x \b.%ld
+# Are these three SGI-based file types or general ones?
+0 string WNGZWZSC Wingz compiled script
+0 string WNGZWZSS Wingz spreadsheet
+0 string WNGZWZHP Wingz help file
+#
+0 string \#Inventor V IRIS Inventor 1.0 file
+0 string \#Inventor V2 Open Inventor 2.0 file
+# XXX - I don't know what next thing is! It is likely to be an image
+# (or movie) format
+0 string glfHeadMagic(); GLF_TEXT
+4 belong 0x41010000 GLF_BINARY_LSB_FIRST
+4 belong 0x00000141 GLF_BINARY_MSB_FIRST
--- /dev/null
+
+#------------------------------------------------------------------------------
+# sgml: file(1) magic for Standard Generalized Markup Language
+
+# HyperText Markup Language (HTML) is an SGML document type,
+# from Daniel Quinlan (quinlan@yggdrasil.com)
+0 string \<!DOCTYPE\ HTML HTML document text
+0 string \<!doctype\ html HTML document text
+0 string \<HEAD HTML document text
+0 string \<head HTML document text
+0 string \<TITLE HTML document text
+0 string \<title HTML document text
+0 string \<html HTML document text
+0 string \<HTML HTML document text
+
+# SGML, mostly from rph@sq
+0 string \<!DOCTYPE exported SGML document text
+0 string \<!doctype exported SGML document text
+0 string \<!SUBDOC exported SGML subdocument text
+0 string \<!subdoc exported SGML subdocument text
+0 string \<!-- exported SGML document text
--- /dev/null
+
+#------------------------------------------------------------------------------
+# sniffer: file(1) magic for packet captured files
+#
+# From: guy@netapp.com (Guy Harris)
+#
+# Microsoft NetMon (packet capture/display program) capture files.
+#
+0 string RTSS NetMon capture file
+>4 byte x - version %d
+>5 byte x \b.%d
+#
+# Network General Sniffer capture files.
+#
+0 string TRSNIFF\ data\ \ \ \ \032 Sniffer capture file
+>23 leshort x - version %d
+>25 leshort x \b.%d
+>33 byte x (Format %d,
+>32 byte 0 Token ring)
+>32 byte 1 Ethernet)
+>32 byte 2 ARCnet)
+>32 byte 3 StarLAN)
+>32 byte 4 PC Network broadband)
+>32 byte 5 LocalTalk)
+>32 byte 6 Znet)
+#
+# "libpcap" capture files.
+# (We call them "tcpdump capture file(s)" for now, as "tcpdump" is
+# the main program that uses that format, but there's also "tcpview",
+# and there may be others in the future.)
+#
+0 ubelong 0xa1b2c3d4 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
+>16 belong x \b, capture length %d)
+0 ulelong 0xa1b2c3d4 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
+>16 lelong x \b, capture length %d)
--- /dev/null
+# $OpenBSD: softquad,v 1.3 1996/06/26 05:33:05 deraadt Exp $
+
+#------------------------------------------------------------------------------
+# softquad: file(1) magic for SoftQuad Publishing Software
+#
+# Author/Editor and RulesBuilder
+#
+# XXX - byte order?
+#
+0 string \<!SQ\ DTD> Compiled SGML rules file
+>9 string >\0 Type %s
+0 string \<!SQ\ A/E> A/E SGML Document binary
+>9 string >\0 Type %s
+0 string \<!SQ\ STS> A/E SGML binary styles file
+>9 string >\0 Type %s
+0 short 0xc0de Compiled PSI (v1) data
+0 short 0xc0da Compiled PSI (v2) data
+>3 string >\0 (%s)
+# Binary sqtroff font/desc files...
+0 short 0125252 SoftQuad DESC or font file binary
+>2 short >0 - version %d
+# Bitmaps...
+0 string SQ\ BITMAP1 SoftQuad Raster Format text
+#0 string SQ\ BITMAP2 SoftQuad Raster Format data
+# sqtroff intermediate language (replacement for ditroff int. lang.)
+0 string X\ SoftQuad troff Context intermediate
+>2 string 495 for AT&T 495 laser printer
+>2 string hp for Hewlett-Packard LaserJet
+>2 string impr for IMAGEN imPRESS
+>2 string ps for PostScript
--- /dev/null
+
+#------------------------------------------------------------------------------
+# sun: file(1) magic for Sun machines
+#
+# Values for big-endian Sun (MC680x0, SPARC) binaries on pre-5.x
+# releases. (5.x uses ELF.)
+#
+0 belong&077777777 0600413 sparc demand paged
+>0 byte &0x80
+>>20 belong <4096 shared library
+>>20 belong =4096 dynamically linked executable
+>>20 belong >4096 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&077777777 0600410 sparc pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&077777777 0600407 sparc
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+
+0 belong&077777777 0400413 mc68020 demand paged
+>0 byte &0x80
+>>20 belong <4096 shared library
+>>20 belong =4096 dynamically linked executable
+>>20 belong >4096 dynamically linked executable
+>16 belong >0 not stripped
+0 belong&077777777 0400410 mc68020 pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&077777777 0400407 mc68020
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+
+0 belong&077777777 0200413 mc68010 demand paged
+>0 byte &0x80
+>>20 belong <4096 shared library
+>>20 belong =4096 dynamically linked executable
+>>20 belong >4096 dynamically linked executable
+>16 belong >0 not stripped
+0 belong&077777777 0200410 mc68010 pure
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+0 belong&077777777 0200407 mc68010
+>0 byte &0x80 dynamically linked executable
+>0 byte ^0x80 executable
+>16 belong >0 not stripped
+
+# reworked these to avoid anything beginning with zero becoming "old sun-2"
+0 belong 0407 old sun-2 executable
+>16 belong >0 not stripped
+0 belong 0410 old sun-2 pure executable
+>16 belong >0 not stripped
+0 belong 0413 old sun-2 demand paged executable
+>16 belong >0 not stripped
+
+#
+# Core files. "SPARC 4.x BCP" means "core file from a SunOS 4.x SPARC
+# binary executed in compatibility mode under SunOS 5.x".
+#
+0 belong 0x080456 SunOS core file
+>4 belong 432 (SPARC)
+>>132 string >\0 from '%s'
+>>116 belong =3 (quit)
+>>116 belong =4 (illegal instruction)
+>>116 belong =5 (trace trap)
+>>116 belong =6 (abort)
+>>116 belong =7 (emulator trap)
+>>116 belong =8 (arithmetic exception)
+>>116 belong =9 (kill)
+>>116 belong =10 (bus error)
+>>116 belong =11 (segmentation violation)
+>>116 belong =12 (bad argument to system call)
+>>116 belong =29 (resource lost)
+>>120 belong x (T=%dK,
+>>124 belong x D=%dK,
+>>128 belong x S=%dK)
+>4 belong 826 (68K)
+>>128 string >\0 from '%s'
+>4 belong 456 (SPARC 4.x BCP)
+>>152 string >\0 from '%s'
+# Sun SunPC
+0 long 0xfa33c08e SunPC 4.0 Hard Disk
+0 string #SUNPC_CONFIG SunPC 4.0 Properties Values
+# Sun snoop
+#
+# XXX - are numbers stored in big-endian format, or in host byte order?
+# They're the same on SPARC, but not the same on x86.
+#
+0 string snoop Snoop capture file
+>8 long >0 - version %ld
+>12 long 0 (IEEE 802.3)
+>12 long 1 (IEEE 802.4)
+>12 long 2 (IEEE 802.5)
+>12 long 3 (IEEE 802.6)
+>12 long 4 (Ethernet)
+>12 long 5 (HDLC)
+>12 long 6 (Character synchronous)
+>12 long 7 (IBM channel-to-channel adapter)
+>12 long 8 (FDDI)
+>12 long 9 (Unknown)
+# Sun KCMS
+36 string acsp Kodak Color Management System, ICC Profile
+
+
--- /dev/null
+#------------------------------------------------------------------------------
+# teapot: file(1) magic for "teapot" spreadsheet
+#
+0 string #!teapot\012xdr teapot work sheet (XDR format)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# terminfo: file(1) magic for terminfo
+#
+# XXX - byte order for screen images?
+#
+0 string \032\001 Compiled terminfo entry
+0 short 0433 Curses screen image
+0 short 0434 Curses screen image
--- /dev/null
+
+#------------------------------------------------------------------------------
+# tex: file(1) magic for TeX files
+#
+# From <conklin@talisman.kaleida.com>
+
+# Although we may know the offset of certain text fields in TeX DVI
+# and font files, we can't use them reliably because they are not
+# zero terminated. [but we do anyway, christos]
+0 string \367\002 TeX DVI file
+>16 string >\0 (%s)
+0 string \367\203 TeX generic font data
+0 string \367\131 TeX packed font data
+>3 string >\0 (%s)
+0 string \367\312 TeX virtual font data
+0 string This\ is\ TeX, TeX transcript text
+0 string This\ is\ METAFONT, METAFONT transcript text
+
+# There is no way to detect TeX Font Metric (*.tfm) files without
+# breaking them apart and reading the data. The following patterns
+# match most *.tfm files generated by METAFONT or afm2tfm.
+2 string \000\021 TeX font metric data
+>33 string >\0 (%s)
+2 string \000\022 TeX font metric data
+>33 string >\0 (%s)
+
+# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com)
+0 string \\input\ texinfo Texinfo source text
+0 string This\ is\ Info\ file GNU Info text
+
+# TeX documents, from Daniel Quinlan (quinlan@yggdrasil.com)
+0 string \\input TeX document text
+0 string \\section LaTeX document text
+0 string \\setlength LaTeX document text
+0 string \\documentstyle LaTeX document text
+0 string \\chapter LaTeX document text
--- /dev/null
+# ------------------------------------------------------------------------
+# ti-8x: file(1) magic for the TI-8x and TI-92 Graphing Calculators.
+#
+# From: Ryan McGuire (rmcguire@freenet.columbus.oh.us).
+#
+# NOTE: This list is not complete.
+#
+# Magic Numbers for the TI-82
+#
+0 string **TI82** TI-82 Graphing Calculator
+>0x000037 byte 0x0B TI-BASIC Group/Program File.
+#
+# Magic Numbers for the TI-83
+#
+0 string **TI83** TI-83 Graphing Calculator
+>0x000037 byte 0x0B TI-BASIC Group/Program File.
+#
+# Magic Numbers for the TI-85
+#
+0 string **TI85** TI-85 Graphing Calculator
+>11 string Backup Backup File.
+>0x000032 string ZS4 - ZShell Version 4 File.
+>0x000032 string ZS3 - ZShell Version 3 File.
+>0x00000B string GDatabase Graphics Database.
+>0x00003B byte 0x12 TI-BASIC Group/Program File.
+#
+# Magic Numbers for the TI-92
+#
+0 string **TI92** TI-92 Graphing Calculator
+>0x000058 byte 0x12 TI-BASIC Group File.
+>0x000012 string Function Function.
+>0x000048 byte 0x12 TI-BASIC Program.
+# Files for the TI-80 and TI-81 are pretty rare. I'm not going to put the
+# program/group magic numbers in here because I cannot find any.
+0 string **TI80** TI-80 Graphing Calculator File.
+0 string **TI81** TI-81 Graphing Calculator File.
--- /dev/null
+
+#------------------------------------------------------------------------------
+# timezone: file(1) magic for timezone data
+#
+# from Daniel Quinlan (quinlan@yggdrasil.com)
+# this should work on Linux, SunOS, and maybe others
+0 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0 timezone data
+0 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\0 timezone data
+0 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0 timezone data
+0 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0 timezone data
+0 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0 timezone data
+0 string \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\6\0 timezone data
--- /dev/null
+
+#------------------------------------------------------------------------------
+# troff: file(1) magic for *roff
+#
+# updated by Daniel Quinlan (quinlan@yggdrasil.com)
+
+# troff input
+0 string .\\" troff or preprocessor input text
+0 string '\\" troff or preprocessor input text
+0 string '.\\" troff or preprocessor input text
+0 string \\" troff or preprocessor input text
+
+# ditroff intermediate output text
+0 string x\ T ditroff text
+>4 string cat for the C/A/T phototypesetter
+>4 string ps for PostScript
+>4 string dvi for DVI
+>4 string ascii for ASCII
+>4 string lj4 for LaserJet 4
+>4 string latin1 for ISO 8859-1 (Latin 1)
+>4 string X75 for xditview at 75dpi
+>>7 string -12 (12pt)
+>4 string X100 for xditview at 100dpi
+>>8 string -12 (12pt)
+
+# output data formats
+0 string \100\357 very old (C/A/T) troff output data
--- /dev/null
+
+#------------------------------------------------------------------------------
+# typeset: file(1) magic for other typesetting
+#
+0 string Interpress/Xerox Xerox InterPress data
+>16 string / (version
+>>17 string >\0 %s)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# unknown: file(1) magic for unknown machines
+#
+# XXX - this probably should be pruned, as it'll match PDP-11 and
+# VAX image formats.
+#
+# 0x107 is 0407; 0x108 is 0410; both are PDP-11 (executable and pure,
+# respectively).
+#
+# 0x109 is 0411; that's PDP-11 split I&D, but the PDP-11 version doesn't
+# have the "version %ld", which may be a bogus COFFism (I don't think
+# there ever was COFF for the PDP-11).
+#
+# 0x10B is 0413; that's VAX demand-paged, but this is a short, not a
+# long, as it would be on a VAX.
+#
+# 0x10C is 0414, 0x10D is 0415, and 0x10E is 416; those *are* unknown.
+#
+0 short 0x107 unknown machine executable
+>8 short >0 not stripped
+>15 byte >0 - version %ld
+0 short 0x108 unknown pure executable
+>8 short >0 not stripped
+>15 byte >0 - version %ld
+0 short 0x109 PDP-11 separate I&D
+>8 short >0 not stripped
+>15 byte >0 - version %ld
+0 short 0x10b unknown pure executable
+>8 short >0 not stripped
+>15 byte >0 - version %ld
+0 long 0x10c unknown demand paged pure executable
+>16 long >0 not stripped
+0 long 0x10d unknown demand paged pure executable
+>16 long >0 not stripped
+0 long 0x10e unknown readable demand paged pure executable
--- /dev/null
+
+#------------------------------------------------------------------------------
+# uuencode: file(1) magic for ASCII-encoded files
+#
+
+# GRR: the first line of xxencoded files is identical to that in uuencoded
+# files, but the first character in most subsequent lines is 'h' instead of
+# 'M'. (xxencoding uses lowercase letters in place of most of uuencode's
+# punctuation and survives BITNET gateways better.) If regular expressions
+# were supported, this entry could possibly be split into two with
+# "begin\040\.\*\012M" or "begin\040\.\*\012h" (where \. and \* are REs).
+0 string begin\040 uuencoded or xxencoded text
+
+# btoa(1) is an alternative to uuencode that requires less space.
+0 string xbtoa\ Begin btoa'd text
+
+# ship(1) is another, much cooler alternative to uuencode.
+# Greg Roelofs, newt@uchicago.edu
+0 string $\012ship ship'd binary text
+
+# bencode(8) is used to encode compressed news batches (Bnews/Cnews only?)
+# Greg Roelofs, newt@uchicago.edu
+0 string Decode\ the\ following\ with\ bdeco bencoded News text
+
+# BinHex is the Macintosh ASCII-encoded file format (see also "apple")
+# Daniel Quinlan, quinlan@yggdrasil.com
+11 string must\ be\ converted\ with\ BinHex BinHex binary text
+>41 string x \b, version %.3s
+
+# GRR: is MIME BASE64 encoding handled somewhere?
--- /dev/null
+
+#------------------------------------------------------------------------------
+# varied.out: file(1) magic for various USG systems
+#
+# Herewith many of the object file formats used by USG systems.
+# Most have been moved to files for a particular processor,
+# and deleted if they duplicate other entries.
+#
+0 short 0610 Perkin-Elmer executable
+# AMD 29K
+0 beshort 0572 amd 29k coff noprebar executable
+0 beshort 01572 amd 29k coff prebar executable
+0 beshort 0160007 amd 29k coff archive
+# Cray
+6 beshort 0407 unicos (cray) executable
+# Ultrix 4.3
+596 string \130\337\377\377 Ultrix core file
+>600 string >\0 '%s'
--- /dev/null
+
+#------------------------------------------------------------------------------
+# vax: file(1) magic for VAX executable/object and APL workspace
+#
+0 lelong 0101557 VAX single precision APL workspace
+0 lelong 0101556 VAX double precision APL workspace
+
+#
+# VAX a.out (32V, BSD)
+#
+0 lelong 0407 VAX executable
+>16 lelong >0 not stripped
+
+0 lelong 0410 VAX pure executable
+>16 lelong >0 not stripped
+
+0 lelong 0413 VAX demand paged pure executable
+>16 lelong >0 not stripped
+
+0 lelong 0420 VAX demand paged (first page unmapped) pure executable
+>16 lelong >0 not stripped
+
+#
+# VAX COFF
+#
+# The `versions' should be un-commented if they work for you.
+# (Was the problem just one of endianness?)
+#
+0 leshort 0570 VAX COFF executable
+>12 lelong >0 not stripped
+>22 leshort >0 - version %ld
+0 leshort 0575 VAX COFF pure executable
+>12 lelong >0 not stripped
+>22 leshort >0 - version %ld
--- /dev/null
+
+#------------------------------------------------------------------------------
+# vicar: file(1) magic for VICAR files.
+#
+# From: Ossama Othman <othman@astrosun.tn.cornell.edu
+# VICAR is JPL's in-house spacecraft image processing program
+# VICAR image
+0 string LBLSIZE= VICAR image data
+>32 string BYTE \b, 8 bits = VAX byte
+>32 string HALF \b, 16 bits = VAX word = Fortran INTEGER*2
+>32 string FULL \b, 32 bits = VAX longword = Fortran INTEGER*4
+>32 string REAL \b, 32 bits = VAX longword = Fortran REAL*4
+>32 string DOUB \b, 64 bits = VAX quadword = Fortran REAL*8
+>32 string COMPLEX \b, 64 bits = VAX quadword = Fortran COMPLEX*8
+# VICAR label file
+43 string SFDU_LABEL VICAR label file
--- /dev/null
+
+#------------------------------------------------------------------------------
+# visx: file(1) magic for Visx format files
+#
+0 short 0x5555 VISX image file
+>2 byte 0 (zero)
+>2 byte 1 (unsigned char)
+>2 byte 2 (short integer)
+>2 byte 3 (float 32)
+>2 byte 4 (float 64)
+>2 byte 5 (signed char)
+>2 byte 6 (bit-plane)
+>2 byte 7 (classes)
+>2 byte 8 (statistics)
+>2 byte 10 (ascii text)
+>2 byte 15 (image segments)
+>2 byte 100 (image set)
+>2 byte 101 (unsigned char vector)
+>2 byte 102 (short integer vector)
+>2 byte 103 (float 32 vector)
+>2 byte 104 (float 64 vector)
+>2 byte 105 (signed char vector)
+>2 byte 106 (bit plane vector)
+>2 byte 121 (feature vector)
+>2 byte 122 (feature vector library)
+>2 byte 124 (chain code)
+>2 byte 126 (bit vector)
+>2 byte 130 (graph)
+>2 byte 131 (adjacency graph)
+>2 byte 132 (adjacency graph library)
+>2 string .VISIX (ascii text)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# vms: file(1) magic for VMS executables (experimental)
+#
+# VMS .exe formats, both VAX and AXP (Greg Roelofs, newt@uchicago.edu)
+
+# GRR 950122: I'm just guessing on these, based on inspection of the headers
+# of three executables each for Alpha and VAX architectures. The VAX files
+# all had headers similar to this:
+#
+# 00000 b0 00 30 00 44 00 60 00 00 00 00 00 30 32 30 35 ..0.D.`.....0205
+# 00010 01 01 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 ................
+#
+0 string \xb0\0\x30\0 VMS VAX executable
+>44032 string PK\003\004 \b, Info-ZIP SFX archive v5.12 w/decryption
+#
+# The AXP files all looked like this, except that the byte at offset 0x22
+# was 06 in some of them and 07 in others:
+#
+# 00000 03 00 00 00 00 00 00 00 ec 02 00 00 10 01 00 00 ................
+# 00010 68 00 00 00 98 00 00 00 b8 00 00 00 00 00 00 00 h...............
+# 00020 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+# 00030 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
+# 00040 00 00 00 00 ff ff ff ff ff ff ff ff 02 00 00 00 ................
+#
+0 belong 0x03000000 VMS Alpha executable
+>75264 string PK\003\004 \b, Info-ZIP SFX archive v5.12 w/decryption
--- /dev/null
+#WordPerfect type files Version 1.6 - PLEASE DO NOT REMOVE THIS LINE
+0 string \377WPC\020\000\000\000\022\012\001\001\000\000\000\000 (WP) loadable text
+>15 byte 0 Optimized for Intel
+>15 byte 1 Optimized for Non-Intel
+1 string WPC (Corel/WP)
+>8 short 257 WordPerfect macro
+>8 short 258 WordPerfect help file
+>8 short 259 WordPerfect keyboard file
+>8 short 266 WordPerfect document
+>8 short 267 WordPerfect dictionary
+>8 short 268 WordPerfect thesaurus
+>8 short 269 WordPerfect block
+>8 short 270 WordPerfect rectangular block
+>8 short 271 WordPerfect column block
+>8 short 272 WordPerfect printer data
+>8 short 275 WordPerfect printer data
+>8 short 276 WordPerfect driver resource data
+>8 short 279 WordPerfect hyphenation code
+>8 short 280 WordPerfect hyphenation data
+>8 short 281 WordPerfect macro resource data
+>8 short 283 WordPerfect hyphenation lex
+>8 short 285 WordPerfect wordlist
+>8 short 286 WordPerfect equation resource data
+>8 short 289 WordPerfect spell rules
+>8 short 290 WordPerfect dictionary rules
+>8 short 295 WordPerfect spell rules (Microlytics)
+>8 short 299 WordPerfect settings file
+>8 short 301 WordPerfect 4.2 document
+>8 short 325 WordPerfect dialog file
+>8 short 332 WordPerfect button bar
+>8 short 513 Shell macro
+>8 short 522 Shell definition
+>8 short 769 Notebook macro
+>8 short 770 Notebook help file
+>8 short 771 Notebook keyboard file
+>8 short 778 Notebook definition
+>8 short 1026 Calculator help file
+>8 short 1538 Calendar help file
+>8 short 1546 Calendar data file
+>8 short 1793 Editor macro
+>8 short 1794 Editor help file
+>8 short 1795 Editor keyboard file
+>8 short 1817 Editor macro resource file
+>8 short 2049 Macro editor macro
+>8 short 2050 Macro editor help file
+>8 short 2051 Macro editor keyboard file
+>8 short 2305 PlanPerfect macro
+>8 short 2306 PlanPerfect help file
+>8 short 2307 PlanPerfect keyboard file
+>8 short 2314 PlanPerfect worksheet
+>8 short 2319 PlanPerfect printer definition
+>8 short 2322 PlanPerfect graphic definition
+>8 short 2323 PlanPerfect data
+>8 short 2324 PlanPerfect temporary printer
+>8 short 2329 PlanPerfect macro resource data
+>8 byte 11 Mail
+>8 short 2818 help file
+>8 short 2821 distribution list
+>8 short 2826 out box
+>8 short 2827 in box
+>8 short 2836 users archived mailbox
+>8 short 2837 archived message database
+>8 short 2838 archived attachments
+>8 short 3083 Printer temporary file
+>8 short 3330 Scheduler help file
+>8 short 3338 Scheduler in file
+>8 short 3339 Scheduler out file
+>8 short 3594 GroupWise settings file
+>8 short 3601 GroupWise directory services
+>8 short 3627 GroupWise settings file
+>8 short 4362 Terminal resource data
+>8 short 4363 Terminal resource data
+>8 short 4395 Terminal resource data
+>8 short 4619 GUI loadable text
+>8 short 4620 graphics resource data
+>8 short 4621 printer settings file
+>8 short 4622 port definition file
+>8 short 4623 print queue parameters
+>8 short 4624 compressed file
+>8 short 5130 Network service msg file
+>8 short 5131 Network service msg file
+>8 short 5132 Async gateway login msg
+>8 short 5134 GroupWise message file
+>8 short 7956 GroupWise admin domain database
+>8 short 7957 GroupWise admin host database
+>8 short 7959 GroupWise admin remote host database
+>8 short 7960 GroupWise admin ADS deferment data file
+>8 short 8458 IntelliTAG (SGML) compiled DTD
+>8 long 18219264 WordPerfect graphic image (1.0)
+>8 long 18219520 WordPerfect graphic image (2.0)
+#end of WordPerfect type files Version 1.6 - PLEASE DO NOT REMOVE THIS LINE
--- /dev/null
+
+#------------------------------------------------------------------------------
+# xenix: file(1) magic for Microsoft Xenix
+#
+# "Middle model" stuff, and "Xenix 8086 relocatable or 80286 small
+# model" lifted from "magic.xenix", with comment "derived empirically;
+# treat as folklore until proven"
+#
+# "small model", "large model", "huge model" stuff lifted from XXX
+#
+# XXX - "x.out" collides with PDP-11 archives
+#
+0 string core core file (Xenix)
+0 byte 0x80 8086 relocatable (Microsoft)
+0 leshort 0xff65 x.out
+>2 string __.SYMDEF randomized
+>0 byte x archive
+0 leshort 0x206 Microsoft a.out
+>8 leshort 1 Middle model
+>0x1e leshort &0x10 overlay
+>0x1e leshort &0x2 separate
+>0x1e leshort &0x4 pure
+>0x1e leshort &0x800 segmented
+>0x1e leshort &0x400 standalone
+>0x1e leshort &0x8 fixed-stack
+>0x1c byte &0x80 byte-swapped
+>0x1c byte &0x40 word-swapped
+>0x10 lelong >0 not-stripped
+>0x1e leshort ^0xc000 pre-SysV
+>0x1e leshort &0x4000 V2.3
+>0x1e leshort &0x8000 V3.0
+>0x1c byte &0x4 86
+>0x1c byte &0xb 186
+>0x1c byte &0x9 286
+>0x1c byte &0xa 386
+>0x1f byte <0x040 small model
+>0x1f byte =0x048 large model
+>0x1f byte =0x049 huge model
+>0x1e leshort &0x1 executable
+>0x1e leshort ^0x1 object file
+>0x1e leshort &0x40 Large Text
+>0x1e leshort &0x20 Large Data
+>0x1e leshort &0x120 Huge Objects Enabled
+>0x10 lelong >0 not stripped
+
+0 leshort 0x140 old Microsoft 8086 x.out
+>0x3 byte &0x4 separate
+>0x3 byte &0x2 pure
+>0 byte &0x1 executable
+>0 byte ^0x1 relocatable
+>0x14 lelong >0 not stripped
+
+0 lelong 0x206 b.out
+>0x1e leshort &0x10 overlay
+>0x1e leshort &0x2 separate
+>0x1e leshort &0x4 pure
+>0x1e leshort &0x800 segmented
+>0x1e leshort &0x400 standalone
+>0x1e leshort &0x1 executable
+>0x1e leshort ^0x1 object file
+>0x1e leshort &0x4000 V2.3
+>0x1e leshort &0x8000 V3.0
+>0x1c byte &0x4 86
+>0x1c byte &0xb 186
+>0x1c byte &0x9 286
+>0x1c byte &0x29 286
+>0x1c byte &0xa 386
+>0x1e leshort &0x4 Large Text
+>0x1e leshort &0x2 Large Data
+>0x1e leshort &0x102 Huge Objects Enabled
+
+0 leshort 0x580 XENIX 8086 relocatable or 80286 small model
--- /dev/null
+
+#------------------------------------------------------------------------------
+# zilog: file(1) magic for Zilog Z8000.
+#
+# Was it big-endian or little-endian? My Product Specification doesn't
+# say.
+#
+0 long 0xe807 object file (z8000 a.out)
+0 long 0xe808 pure object file (z8000 a.out)
+0 long 0xe809 separate object file (z8000 a.out)
+0 long 0xe805 overlay object file (z8000 a.out)
--- /dev/null
+
+#------------------------------------------------------------------------------
+# zyxel: file(1) magic for ZyXEL modems
+#
+# From <rob@pe1chl.ampr.org>
+# These are the /etc/magic entries to decode datafiles as used for the
+# ZyXEL U-1496E DATA/FAX/VOICE modems. (This header conforms to a
+# ZyXEL-defined standard)
+
+0 string ZyXEL\002 ZyXEL voice data
+>10 byte 0 - CELP encoding
+>10 byte&0x0B 1 - ADPCM2 encoding
+>10 byte&0x0B 2 - ADPCM3 encoding
+>10 byte&0x0B 3 - ADPCM4 encoding
+>10 byte&0x0B 8 - New ADPCM3 encoding
+>10 byte&0x04 4 with resync
--- /dev/null
+.\" $OpenBSD: magic.5,v 1.3 1997/02/09 23:58:28 millert Exp $
+.\" install as magic.4 on USG, magic.5 on V7 or Berkeley systems.
+.TH MAGIC 5 "Public Domain"
+.SH NAME
+magic \- file command's magic number file
+.SH DESCRIPTION
+This manual page documents the format of the magic file as
+used by the
+.BR file (1)
+command, version 3.22. The
+.B file
+command identifies the type of a file using,
+among other tests,
+a test for whether the file begins with a certain
+.IR "magic number" .
+The file
+.I /etc/magic
+specifies what magic numbers are to be tested for,
+what message to print if a particular magic number is found,
+and additional information to extract from the file.
+.PP
+Each line of the file specifies a test to be performed.
+A test compares the data starting at a particular offset
+in the file with a 1-byte, 2-byte, or 4-byte numeric value or
+a string. If the test succeeds, a message is printed.
+The line consists of the following fields:
+.IP offset \w'message'u+2n
+A number specifying the offset, in bytes, into the file of the data
+which is to be tested.
+.IP type
+The type of the data to be tested. The possible values are:
+.RS
+.IP byte \w'message'u+2n
+A one-byte value.
+.IP short
+A two-byte value (on most systems) in this machine's native byte order.
+.IP long
+A four-byte value (on most systems) in this machine's native byte order.
+.IP string
+A string of bytes.
+.IP date
+A four-byte value interpreted as a unix date.
+.IP beshort
+A two-byte value (on most systems) in big-endian byte order.
+.IP belong
+A four-byte value (on most systems) in big-endian byte order.
+.IP bedate
+A four-byte value (on most systems) in big-endian byte order,
+interpreted as a unix date.
+.IP leshort
+A two-byte value (on most systems) in little-endian byte order.
+.IP lelong
+A four-byte value (on most systems) in little-endian byte order.
+.IP ledate
+A four-byte value (on most systems) in little-endian byte order,
+interpreted as a unix date.
+.RE
+.PP
+The numeric types may optionally be followed by
+.B &
+and a numeric value,
+to specify that the value is to be AND'ed with the
+numeric value before any comparisons are done. Prepending a
+.B u
+to the type indicates that ordered comparisons should be unsigned.
+.IP test
+The value to be compared with the value from the file. If the type is
+numeric, this value
+is specified in C form; if it is a string, it is specified as a C string
+with the usual escapes permitted (e.g. \en for new-line).
+.IP
+Numeric values
+may be preceded by a character indicating the operation to be performed.
+It may be
+.BR = ,
+to specify that the value from the file must equal the specified value,
+.BR < ,
+to specify that the value from the file must be less than the specified
+value,
+.BR > ,
+to specify that the value from the file must be greater than the specified
+value,
+.BR & ,
+to specify that the value from the file must have set all of the bits
+that are set in the specified value,
+.BR ^ ,
+to specify that the value from the file must have clear any of the bits
+that are set in the specified value, or
+.BR x ,
+to specify that any value will match. If the character is omitted,
+it is assumed to be
+.BR = .
+.IP
+Numeric values are specified in C form; e.g.
+.B 13
+is decimal,
+.B 013
+is octal, and
+.B 0x13
+is hexadecimal.
+.IP
+For string values, the byte string from the
+file must match the specified byte string.
+The operators
+.BR = ,
+.B <
+and
+.B >
+(but not
+.BR & )
+can be applied to strings.
+The length used for matching is that of the string argument
+in the magic file. This means that a line can match any string, and
+then presumably print that string, by doing
+.B >\e0
+(because all strings are greater than the null string).
+.IP message
+The message to be printed if the comparison succeeds. If the string
+contains a
+.BR printf (3S)
+format specification, the value from the file (with any specified masking
+performed) is printed using the message as the format string.
+.PP
+Some file formats contain additional information which is to be printed
+along with the file type. A line which begins with the character
+.B >
+indicates additional tests and messages to be printed. The number of
+.B >
+on the line indicates the level of the test; a line with no
+.B >
+at the beginning is considered to be at level 0.
+Each line at level
+.IB n \(pl1
+is under the control of the line at level
+.IB n
+most closely preceding it in the magic file.
+If the test on a line at level
+.I n
+succeeds, the tests specified in all the subsequent lines at level
+.IB n \(pl1
+are performed, and the messages printed if the tests succeed. The next
+line at level
+.I n
+terminates this.
+If the first character following the last
+.B >
+is a
+.B (
+then the string after the parenthesis is interpreted as an indirect offset.
+That means that the number after the parenthesis is used as an offset in
+the file. The value at that offset is read, and is used again as an offset
+in the file. Indirect offsets are of the form:
+.BI (( x [.[bsl]][+-][ y ]).
+The value of
+.I x
+is used as an offset in the file. A byte, short or long is read at that offset
+depending on the
+.B [bsl]
+type specifier. To that number the value of
+.I y
+is added and the result is used as an offset in the file. The default type
+if one is not specified is long.
+.PP
+Sometimes you do not know the exact offset as this depends on the length of
+preceding fields. You can specify an offset relative to the end of the
+last uplevel field (of course this may only be done for sublevel tests, i.e.
+test beginning with
+.B >
+). Such a relative offset is specified using
+.B &
+as a prefix to the offset.
+.SH BUGS
+The formats
+.IR long ,
+.IR belong ,
+.IR lelong ,
+.IR short ,
+.IR beshort ,
+.IR leshort ,
+.IR date ,
+.IR bedate ,
+and
+.I ledate
+are system-dependent; perhaps they should be specified as a number
+of bytes (2B, 4B, etc),
+since the files being recognized typically come from
+a system on which the lengths are invariant.
+.PP
+There is (currently) no support for specified-endian data to be used in
+indirect offsets.
+.SH SEE ALSO
+.BR file (1)
+\- the command that reads this file.
+.\"
+.\" From: guy@sun.uucp (Guy Harris)
+.\" Newsgroups: net.bugs.usg
+.\" Subject: /etc/magic's format isn't well documented
+.\" Message-ID: <2752@sun.uucp>
+.\" Date: 3 Sep 85 08:19:07 GMT
+.\" Organization: Sun Microsystems, Inc.
+.\" Lines: 136
+.\"
+.\" Here's a manual page for the format accepted by the "file" made by adding
+.\" the changes I posted to the S5R2 version.
+.\"
+.\" Modified for Ian Darwin's version of the file command.
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: names.h,v 1.3 1997/02/09 23:58:29 millert Exp $ */
+
+/*
+ * Names.h - names and types used by ascmagic in file(1).
+ * These tokens are here because they can appear anywhere in
+ * the first HOWMANY bytes, while tokens in /etc/magic must
+ * appear at fixed offsets into the file. Don't make HOWMANY
+ * too high unless you have a very fast CPU.
+ *
+ * Copyright (c) Ian F. Darwin, 1987.
+ * Written by Ian F. Darwin.
+ *
+ * See LEGAL.NOTICE
+ */
+
+/* these types are used to index the table 'types': keep em in sync! */
+#define L_C 0 /* first and foremost on UNIX */
+#define L_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",
+ "assembler program text",
+ "English text",
+ "Pascal program text",
+ "mail text",
+ "news text",
+ "can't happen error on names.h/types",
+ 0};
+
+static struct names {
+ char *name;
+ short type;
+} 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},
+ {"The", L_ENG},
+ {"the", L_ENG},
+ {"double", L_C},
+ {"extern", L_C},
+ {"float", L_C},
+ {"real", L_C},
+ {"struct", L_C},
+ {"union", L_C},
+ {"CFLAGS", L_MAKE},
+ {"LDFLAGS", L_MAKE},
+ {"all:", L_MAKE},
+ {".PRECIOUS", L_MAKE},
+/* Too many files of text have these words in them. Find another way
+ * to recognize Fortrash.
+ */
+#ifdef NOTDEF
+ {"subroutine", L_FORT},
+ {"function", L_FORT},
+ {"block", L_FORT},
+ {"common", L_FORT},
+ {"dimension", L_FORT},
+ {"integer", L_FORT},
+ {"data", L_FORT},
+#endif /*NOTDEF*/
+ {".ascii", L_MACH},
+ {".asciiz", L_MACH},
+ {".byte", L_MACH},
+ {".even", L_MACH},
+ {".globl", L_MACH},
+ {".text", L_MACH},
+ {"clr", L_MACH},
+ {"(input,", L_PAS},
+ {"dcl", L_PLI},
+ {"Received:", L_MAIL},
+ {">From", L_MAIL},
+ {"Return-Path:",L_MAIL},
+ {"Cc:", L_MAIL},
+ {"Newsgroups:", L_NEWS},
+ {"Path:", L_NEWS},
+ {"Organization:",L_NEWS},
+ {NULL, 0}
+};
+#define NNAMES ((sizeof(names)/sizeof(struct names)) - 1)
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: patchlevel.h,v 1.4 1997/02/09 23:58:31 millert Exp $ */
+
+#define FILE_VERSION_MAJOR 3
+#define patchlevel 22
+
+/*
+ * Patchlevel file for Ian Darwin's MAGIC command.
+ *
+ * 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
+ *
+ * Revision 1.20 1996/06/22 22:15:52 christos
+ * - support relative offsets of the form >&
+ * - fix bug with truncating magic strings that contain \n
+ * - file -f - did not read from stdin as documented
+ * - support elf file parsing using our own elf support.
+ * - as always magdir fixes and additions.
+ *
+ * Revision 1.19 1995/10/27 23:14:46 christos
+ * Ability to parse colon separated list of magic files
+ * New LEGAL.NOTICE
+ * Various magic file changes
+ *
+ * Revision 1.18 1995/05/20 22:09:21 christos
+ * Passed incorrect argument to eatsize().
+ * Use %ld and %lx where appropriate.
+ * Remove unused variables
+ * ELF support for both big and little endian
+ * Fixes for small files again.
+ *
+ * Revision 1.17 1995/04/28 17:29:13 christos
+ * - Incorrect nroff detection fix from der Mouse
+ * - Lost and incorrect magic entries.
+ * - Added ELF stripped binary detection [in C; ugh]
+ * - Look for $MAGIC to find the magic file.
+ * - Eat trailing size specifications from numbers i.e. ignore 10L
+ * - More fixes for very short files
+ *
+ * Revision 1.16 1995/03/25 22:06:45 christos
+ * - use strtoul() where it exists.
+ * - fix sign-extend bug
+ * - try to detect tar archives before nroff files, otherwise
+ * tar files where the first file starts with a . will not work
+ *
+ * Revision 1.15 1995/01/21 21:03:35 christos
+ * Added CSECTION for the file man page
+ * Added version flag -v
+ * Fixed bug with -f input flag (from iorio@violet.berkeley.edu)
+ * Lots of magic fixes and reorganization...
+ *
+ * Revision 1.14 1994/05/03 17:58:23 christos
+ * changes from mycroft@gnu.ai.mit.edu (Charles Hannum) for unsigned
+ *
+ * Revision 1.13 1994/01/21 01:27:01 christos
+ * Fixed null termination bug from Don Seeley at BSDI in ascmagic.c
+ *
+ * Revision 1.12 1993/10/27 20:59:05 christos
+ * Changed -z flag to understand gzip format too.
+ * Moved builtin compression detection to a table, and move
+ * the compress magic entry out of the source.
+ * Made printing of numbers unsigned, and added the mask to it.
+ * Changed the buffer size to 8k, because gzip will refuse to
+ * unzip just a few bytes.
+ *
+ * Revision 1.11 1993/09/24 18:49:06 christos
+ * Fixed small bug in softmagic.c introduced by
+ * copying the data to be examined out of the input
+ * buffer. Changed the Makefile to use sed to create
+ * the correct man pages.
+ *
+ * Revision 1.10 1993/09/23 21:56:23 christos
+ * Passed purify. Fixed indirections. Fixed byte order printing.
+ * Fixed segmentation faults caused by referencing past the end
+ * of the magic buffer. Fixed bus errors caused by referencing
+ * unaligned shorts or longs.
+ *
+ * Revision 1.9 1993/03/24 14:23:40 ian
+ * Batch of minor changes from several contributors.
+ *
+ * Revision 1.8 93/02/19 15:01:26 ian
+ * Numerous changes from Guy Harris too numerous to mention but including
+ * byte-order independance, fixing "old-style masking", etc. etc. A bugfix
+ * for broken symlinks from martin@@d255s004.zfe.siemens.de.
+ *
+ * Revision 1.7 93/01/05 14:57:27 ian
+ * Couple of nits picked by Christos (again, thanks).
+ *
+ * Revision 1.6 93/01/05 13:51:09 ian
+ * Lotsa work on the Magic directory.
+ *
+ * Revision 1.5 92/09/14 14:54:51 ian
+ * Fix a tiny null-pointer bug in previous fix for tar archive + uncompress.
+ *
+ */
+
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: print.c,v 1.3 1997/02/09 23:58:32 millert Exp $ */
+
+/*
+ * print.c - debugging printout routines
+ *
+ * Copyright (c) Ian F. Darwin, 1987.
+ * Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#if __STDC__
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include "file.h"
+
+#ifndef lint
+#if 0
+static char *moduleid = "$OpenBSD: print.c,v 1.3 1997/02/09 23:58:32 millert Exp $";
+#endif
+#endif /* lint */
+
+#define SZOF(a) (sizeof(a) / sizeof(a[0]))
+
+void
+mdump(m)
+struct magic *m;
+{
+ static char *typ[] = { "invalid", "byte", "short", "invalid",
+ "long", "string", "date", "beshort",
+ "belong", "bedate", "leshort", "lelong",
+ "ledate" };
+ (void) fputc('[', stderr);
+ (void) fprintf(stderr, ">>>>>>>> %d" + 8 - (m->cont_level & 7),
+ m->offset);
+
+ if (m->flag & INDIR)
+ (void) fprintf(stderr, "(%s,%d),",
+ (m->in.type >= 0 && m->in.type < SZOF(typ)) ?
+ typ[(unsigned char) m->in.type] :
+ "*bad*",
+ m->in.offset);
+
+ (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
+ (m->type >= 0 && m->type < SZOF(typ)) ?
+ typ[(unsigned char) m->type] :
+ "*bad*");
+ if (m->mask != ~0L)
+ (void) fprintf(stderr, " & %.8x", m->mask);
+
+ (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:
+ {
+ char *rt, *pp = ctime((time_t*) &m->value.l);
+ 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);
+}
+
+/*
+ * ckfputs - futs, but with error checking
+ * ckfprintf - fprintf, but with error checking
+ */
+void
+ckfputs(str, fil)
+ const char *str;
+ FILE *fil;
+{
+ if (fputs(str,fil) == EOF)
+ error("write failed.\n");
+}
+
+/*VARARGS*/
+void
+#if __STDC__
+ckfprintf(FILE *f, const char *fmt, ...)
+#else
+ckfprintf(va_alist)
+ va_dcl
+#endif
+{
+ va_list va;
+#if __STDC__
+ va_start(va, fmt);
+#else
+ FILE *f;
+ const char *fmt;
+ va_start(va);
+ f = va_arg(va, FILE *);
+ fmt = va_arg(va, const char *);
+#endif
+ (void) vfprintf(f, fmt, va);
+ if (ferror(f))
+ error("write failed.\n");
+ va_end(va);
+}
+
+/*
+ * error - print best error message possible and exit
+ */
+/*VARARGS*/
+void
+#if __STDC__
+error(const char *f, ...)
+#else
+error(va_alist)
+ va_dcl
+#endif
+{
+ va_list va;
+#if __STDC__
+ va_start(va, f);
+#else
+ const char *f;
+ va_start(va);
+ f = va_arg(va, const char *);
+#endif
+ /* cuz we use stdout for most, stderr here */
+ (void) fflush(stdout);
+
+ if (progname != NULL)
+ (void) fprintf(stderr, "%s: ", progname);
+ (void) vfprintf(stderr, f, va);
+ va_end(va);
+ exit(1);
+}
+
+/*VARARGS*/
+void
+#if __STDC__
+magwarn(const char *f, ...)
+#else
+magwarn(va_alist)
+ va_dcl
+#endif
+{
+ va_list va;
+#if __STDC__
+ va_start(va, f);
+#else
+ const char *f;
+ va_start(va);
+ f = va_arg(va, const char *);
+#endif
+ /* cuz we use stdout for most, stderr here */
+ (void) fflush(stdout);
+
+ if (progname != NULL)
+ (void) fprintf(stderr, "%s: %s, %d: ",
+ progname, magicfile, lineno);
+ (void) vfprintf(stderr, f, va);
+ va_end(va);
+ fputc('\n', stderr);
+}
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: readelf.c,v 1.1 1997/02/09 23:58:33 millert Exp $ */
+
+#ifdef BUILTIN_ELF
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "readelf.h"
+#include "file.h"
+
+static void
+doshn(fd, off, num, size, buf)
+ int fd;
+ off_t off;
+ int num;
+ size_t size;
+ char *buf;
+{
+ /*
+ * This works for both 32-bit and 64-bit ELF formats,
+ * because it looks only at the "sh_type" field, which is
+ * always 32 bits, and is preceded only by the "sh_name"
+ * field which is also always 32 bits, and because it uses
+ * the shdr size from the ELF header rather than using
+ * the size of an "Elf32_Shdr".
+ */
+ Elf32_Shdr *sh = (Elf32_Shdr *) buf;
+
+ if (lseek(fd, off, SEEK_SET) == -1)
+ error("lseek failed (%s).\n", strerror(errno));
+
+ for ( ; num; num--) {
+ if (read(fd, buf, size) == -1)
+ error("read failed (%s).\n", strerror(errno));
+ if (sh->sh_type == SHT_SYMTAB) {
+ (void) printf (", not stripped");
+ return;
+ }
+ }
+ (void) printf (", stripped");
+}
+
+/*
+ * Look through the program headers of an executable image, searching
+ * for a PT_INTERP section; if one is found, it's dynamically linked,
+ * otherwise it's statically linked.
+ */
+static void
+dophn_exec(fd, off, num, size, buf)
+ int fd;
+ off_t off;
+ int num;
+ size_t size;
+ char *buf;
+{
+ /* I am not sure if this works for 64 bit elf formats */
+ Elf32_Phdr *ph = (Elf32_Phdr *) buf;
+
+ if (lseek(fd, off, SEEK_SET) == -1)
+ error("lseek failed (%s).\n", strerror(errno));
+
+ for ( ; num; num--) {
+ if (read(fd, buf, size) == -1)
+ error("read failed (%s).\n", strerror(errno));
+ if (ph->p_type == PT_INTERP) {
+ /*
+ * Has an interpreter - must be a dynamically-linked
+ * executable.
+ */
+ printf(", dynamically linked");
+ return;
+ }
+ }
+ printf(", statically linked");
+}
+
+size_t prpsoffsets[] = {
+ 100, /* SunOS 5.x */
+ 32, /* Linux */
+};
+
+#define NOFFSETS (sizeof prpsoffsets / sizeof prpsoffsets[0])
+
+/*
+ * Look through the program headers of an executable image, searching
+ * for a PT_NOTE section of type NT_PRPSINFO, with a name "CORE"; if one
+ * is found, try looking in various places in its contents for a 16-character
+ * string containing only printable characters - if found, that string
+ * should be the name of the program that dropped core.
+ * Note: right after that 16-character string is, at least in SunOS 5.x
+ * (and possibly other SVR4-flavored systems) and Linux, a longer string
+ * (80 characters, in 5.x, probably other SVR4-flavored systems, and Linux)
+ * containing the start of the command line for that program.
+ */
+static void
+dophn_core(fd, off, num, size, buf)
+ int fd;
+ off_t off;
+ int num;
+ size_t size;
+ char *buf;
+{
+ /*
+ * This doesn't work for 64-bit ELF, as the "p_offset" field is
+ * 64 bits in 64-bit ELF.
+ */
+ /*
+ * This doesn't work for 64-bit ELF, as the "p_offset" field is
+ * 64 bits in 64-bit ELF.
+ */
+ Elf32_Phdr *ph = (Elf32_Phdr *) buf;
+ Elf32_Nhdr *nh;
+ size_t offset, noffset, reloffset;
+ unsigned char c;
+ int i, j;
+ char nbuf[BUFSIZ];
+ int bufsize;
+
+ for ( ; num; num--) {
+ if (lseek(fd, off, SEEK_SET) == -1)
+ error("lseek failed (%s).\n", strerror(errno));
+ if (read(fd, buf, size) == -1)
+ error("read failed (%s).\n", strerror(errno));
+ off += size;
+ if (ph->p_type != PT_NOTE)
+ continue;
+ if (lseek(fd, ph->p_offset, SEEK_SET) == -1)
+ error("lseek failed (%s).\n", strerror(errno));
+ bufsize = read(fd, nbuf, BUFSIZ);
+ if (bufsize == -1)
+ error("read failed (%s).\n", strerror(errno));
+ offset = 0;
+ for (;;) {
+ if (offset >= bufsize)
+ break;
+ nh = (Elf32_Nhdr *)&nbuf[offset];
+ offset += sizeof *nh;
+
+ /*
+ * If this note isn't an NT_PRPSINFO note, it's
+ * not what we're looking for.
+ */
+ if (nh->n_type != NT_PRPSINFO) {
+ offset += nh->n_namesz;
+ offset = ((offset + 3)/4)*4;
+ offset += nh->n_descsz;
+ offset = ((offset + 3)/4)*4;
+ continue;
+ }
+
+ /*
+ * Make sure this note has the name "CORE".
+ */
+ if (offset + nh->n_namesz >= bufsize) {
+ /*
+ * We're past the end of the buffer.
+ */
+ break;
+ }
+ if (nh->n_namesz != 5
+ || strcmp(&nbuf[offset], "CORE") != 0)
+ continue;
+ offset += nh->n_namesz;
+ offset = ((offset + 3)/4)*4;
+
+ /*
+ * Extract the program name. We assume it to be
+ * 16 characters (that's what it is in SunOS 5.x
+ * and Linux).
+ *
+ * Unfortunately, it's at a different offset in
+ * SunOS 5.x and Linux, so try multiple offsets.
+ * If the characters aren't all printable, reject
+ * it.
+ */
+ for (i = 0; i < NOFFSETS; i++) {
+ reloffset = prpsoffsets[i];
+ noffset = offset + reloffset;
+ for (j = 0; j < 16;
+ j++, noffset++, reloffset++) {
+ /*
+ * Make sure we're not past the end
+ * of the buffer; if we are, just
+ * give up.
+ */
+ if (noffset >= bufsize)
+ return;
+
+ /*
+ * Make sure we're not past the
+ * end of the contents; if we
+ * are, this obviously isn't
+ * the right offset.
+ */
+ if (reloffset >= nh->n_descsz)
+ goto tryanother;
+
+ c = nbuf[noffset];
+ if (c != '\0' && !isprint(c))
+ goto tryanother;
+ }
+
+ /*
+ * Well, that worked.
+ */
+ printf(", from '%.16s'",
+ &nbuf[offset + prpsoffsets[i]]);
+ return;
+
+ tryanother:
+ ;
+ }
+ offset += nh->n_descsz;
+ offset = ((offset + 3)/4)*4;
+ }
+ }
+}
+
+void
+tryelf(fd, buf, nbytes)
+ int fd;
+ char *buf;
+ int nbytes;
+{
+ union {
+ int32 l;
+ char c[sizeof (int32)];
+ } u;
+
+ /*
+ * ELF executables have multiple section headers in arbitrary
+ * file locations and thus file(1) cannot determine it from easily.
+ * Instead we traverse thru all section headers until a symbol table
+ * one is found or else the binary is stripped.
+ */
+ if (buf[EI_MAG0] != ELFMAG0 || buf[EI_MAG1] != ELFMAG1
+ || buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)
+ return;
+
+
+ if (buf[4] == ELFCLASS32) {
+ Elf32_Ehdr elfhdr;
+ if (nbytes <= sizeof (Elf32_Ehdr))
+ return;
+
+
+ u.l = 1;
+ (void) memcpy(&elfhdr, buf, sizeof elfhdr);
+ /*
+ * If the system byteorder does not equal the
+ * object byteorder then don't test.
+ * XXX - we could conceivably fix up the "dophn_XXX()" and
+ * "doshn()" routines to extract stuff in the right
+ * byte order....
+ */
+ if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5]) {
+ if (elfhdr.e_type == ET_CORE)
+ dophn_core(fd, elfhdr.e_phoff, elfhdr.e_phnum,
+ elfhdr.e_phentsize, buf);
+ else {
+ if (elfhdr.e_type == ET_EXEC) {
+ dophn_exec(fd, elfhdr.e_phoff,
+ elfhdr.e_phnum,
+ elfhdr.e_phentsize, buf);
+ }
+ doshn(fd, elfhdr.e_shoff, elfhdr.e_shnum,
+ elfhdr.e_shentsize, buf);
+ }
+ }
+ return;
+ }
+
+ if (buf[4] == ELFCLASS64) {
+ Elf64_Ehdr elfhdr;
+ if (nbytes <= sizeof (Elf64_Ehdr))
+ return;
+
+
+ u.l = 1;
+ (void) memcpy(&elfhdr, buf, sizeof elfhdr);
+
+ /*
+ * If the system byteorder does not equal the
+ * object byteorder then don't test.
+ * XXX - we could conceivably fix up the "dophn_XXX()" and
+ * "doshn()" routines to extract stuff in the right
+ * byte order....
+ */
+ if ((u.c[sizeof(long) - 1] + 1) == elfhdr.e_ident[5]) {
+#ifdef notyet
+ if (elfhdr.e_type == ET_CORE)
+ dophn_core(fd, elfhdr.e_phoff, elfhdr.e_phnum,
+ elfhdr.e_phentsize, buf);
+ else
+#endif
+ {
+#ifdef notyet
+ if (elfhdr.e_type == ET_EXEC) {
+ dophn_exec(fd, elfhdr.e_phoff,
+ elfhdr.e_phnum,
+ elfhdr.e_phentsize, buf);
+ }
+#endif
+ doshn(fd, elfhdr.e_shoff, elfhdr.e_shnum,
+ elfhdr.e_shentsize, buf);
+ }
+ }
+ return;
+ }
+}
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: readelf.h,v 1.1 1997/02/09 23:58:34 millert Exp $ */
+
+/*
+ * readelf.h
+ *
+ * Provide elf data structures for non-elf machines, allowing file
+ * non-elf hosts to determine if an elf binary is stripped.
+ * Note: cobbled from the linux header file, with modifications
+ */
+#ifndef __fake_elf_h__
+#define __fake_elf_h__
+
+typedef unsigned int Elf32_Addr;
+typedef unsigned short Elf32_Half;
+typedef unsigned int Elf32_Off;
+typedef unsigned int Elf32_Word;
+typedef unsigned char Elf32_Char;
+
+/* XXX: We need 64 bit numbers here */
+typedef unsigned int Elf64_Addr[2];
+typedef unsigned short Elf64_Half;
+typedef unsigned int Elf64_Off[2];
+typedef unsigned int Elf64_Word;
+typedef unsigned char Elf64_Char;
+
+#define EI_NIDENT 16
+
+typedef struct {
+ Elf32_Char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry; /* Entry point */
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct {
+ Elf64_Char e_ident[EI_NIDENT];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry; /* Entry point */
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+/* e_type */
+#define ET_EXEC 2
+#define ET_CORE 4
+
+/* sh_type */
+#define SHT_SYMTAB 2
+#define SHT_NOTE 7
+
+/* elf type */
+#define ELFDATANONE 0 /* e_ident[EI_DATA] */
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+/* elf class */
+#define ELFCLASSNONE 0
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+
+/* magic number */
+#define EI_MAG0 0 /* e_ident[] indexes */
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_PAD 7
+
+#define ELFMAG0 0x7f /* EI_MAG */
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+
+typedef struct {
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+#define PT_NULL 0 /* p_type */
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_NUM 7
+
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct {
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Off sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Off sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Off sh_addralign;
+ Elf64_Off sh_entsize;
+} Elf64_Shdr;
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_TASKSTRUCT 4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf_note {
+ Elf32_Word n_namesz; /* Name size */
+ Elf32_Word n_descsz; /* Content size */
+ Elf32_Word n_type; /* Content type */
+} Elf32_Nhdr;
+
+typedef struct {
+ Elf64_Word n_namesz;
+ Elf64_Word n_descsz;
+ Elf64_Word n_type;
+} Elf64_Nhdr;
+
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_PRXREG 4
+#define NT_PLATFORM 5
+#define NT_AUXV 6
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#ifdef BUILTIN_FAT
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/param.h> /* for MAXPATHLEN */
+#include <sys/file.h>
+#include <unistd.h> /* for read() */
+
+#include <mach-o/fat.h>
+#include <mach-o/arch.h>
+#include <mach-o/swap.h>
+
+#include "file.h"
+
+static void print_arch_name_for_file(
+ cpu_type_t cputype,
+ cpu_subtype_t cpusubtype);
+
+void
+tryfat(
+const char *inname,
+int fd,
+char *buf,
+int nbytes)
+{
+ struct fat_header fat_header;
+ struct fat_arch *fat_archs;
+ unsigned long i, arch_size, tbytes;
+ char *arch_buf;
+ unsigned char tmpbuf[HOWMANY+1]; /* one extra for terminating '\0' */
+
+
+ if(nbytes < sizeof(struct fat_header)){
+ return;
+ }
+ memcpy(&fat_header, buf, sizeof(struct fat_header));
+#ifdef __LITTLE_ENDIAN__
+ swap_fat_header(&fat_header, NX_LittleEndian);
+#endif /* __LITTLE_ENDIAN__ */
+ arch_size = fat_header.nfat_arch * sizeof(struct fat_arch);
+ if(arch_size + sizeof(struct fat_header) > nbytes){
+ return;
+ }
+ arch_buf = malloc(nbytes);
+ if(arch_buf == NULL)
+ return;
+ memcpy(arch_buf, buf + sizeof(struct fat_header), arch_size);
+ fat_archs = (struct fat_arch *)(arch_buf);
+#ifdef __LITTLE_ENDIAN__
+ swap_fat_arch(fat_archs, fat_header.nfat_arch, NX_LittleEndian);
+#endif /* __LITTLE_ENDIAN__ */
+ for(i = 0; i < fat_header.nfat_arch; i++){
+ printf("\n%s", inname);
+ print_arch_name_for_file(fat_archs[i].cputype,
+ fat_archs[i].cpusubtype);
+ printf(":\t");
+ lseek(fd, fat_archs[i].offset, L_SET);
+ /*
+ * try looking at the first HOWMANY bytes
+ */
+ if ((tbytes = read(fd, (char *)tmpbuf, HOWMANY)) == -1) {
+ error("read failed (%s).\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+ tryit(tmpbuf, tbytes, 0);
+ }
+}
+
+static
+void
+print_arch_name_for_file(
+cpu_type_t cputype,
+cpu_subtype_t cpusubtype)
+{
+ const NXArchInfo *ArchInfoTable, *ai;
+
+ ArchInfoTable = NXGetAllArchInfos();
+ for(ai = ArchInfoTable; ai->name != NULL; ai++){
+ if(ai->cputype == cputype &&
+ ai->cpusubtype == cpusubtype){
+ printf(" (for architecture %s)", ai->name);
+ return;
+ }
+ }
+ printf(" (for architecture cputype (%d) cpusubtype (%d))",
+ cputype, cpusubtype);
+}
+#endif /* BUILTIN_FAT */
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: softmagic.c,v 1.3 1997/02/09 23:58:36 millert Exp $ */
+
+/*
+ * softmagic - interpret variable magic from /etc/magic
+ *
+ * Copyright (c) Ian F. Darwin, 1987.
+ * Written by Ian F. Darwin.
+ *
+ * This software is not subject to any license of the American Telephone
+ * and Telegraph Company or of the Regents of the University of California.
+ *
+ * Permission is granted to anyone to use this software for any purpose on
+ * any computer system, and to alter it and redistribute it freely, subject
+ * to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits must appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits must appear in the documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h>
+
+#include "file.h"
+
+#ifndef lint
+#if 0
+static char *moduleid = "$OpenBSD: softmagic.c,v 1.3 1997/02/09 23:58:36 millert Exp $";
+#endif
+#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 int32 mprint __P((union VALUETYPE *, struct magic *));
+static void mdebug __P((int32, char *, int));
+static int mconvert __P((union VALUETYPE *, struct magic *));
+
+/*
+ * softmagic - lookup one file in database
+ * (already read from /etc/magic by apprentice.c).
+ * Passed the name and FILE * of one file to be typed.
+ */
+/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
+int
+softmagic(buf, nbytes)
+unsigned char *buf;
+int nbytes;
+{
+ if (match(buf, nbytes))
+ return 1;
+
+ return 0;
+}
+
+/*
+ * Go through the whole list, stopping if you find a match. Process all
+ * the continuations of that match before returning.
+ *
+ * We support multi-level continuations:
+ *
+ * At any time when processing a successful top-level match, there is a
+ * current continuation level; it represents the level of the last
+ * successfully matched continuation.
+ *
+ * Continuations above that level are skipped as, if we see one, it
+ * means that the continuation that controls them - i.e, the
+ * lower-level continuation preceding them - failed to match.
+ *
+ * Continuations below that level are processed as, if we see one,
+ * it means we've finished processing or skipping higher-level
+ * continuations under the control of a successful or unsuccessful
+ * lower-level continuation, and are now seeing the next lower-level
+ * continuation and should process it. The current continuation
+ * level reverts to the level of the one we're seeing.
+ *
+ * Continuations at the current level are processed as, if we see
+ * one, there's no lower-level continuation that may have failed.
+ *
+ * If a continuation matches, we bump the current continuation level
+ * so that higher-level continuations are processed.
+ */
+static int
+match(s, nbytes)
+unsigned char *s;
+int nbytes;
+{
+ int magindex = 0;
+ int cont_level = 0;
+ int need_separator = 0;
+ union VALUETYPE p;
+ static int32 *tmpoff = NULL;
+ static size_t tmplen = 0;
+ int32 oldoff = 0;
+
+ if (tmpoff == NULL)
+ if ((tmpoff = (int32 *) malloc(tmplen = 20)) == NULL)
+ error("out of memory\n");
+
+ for (magindex = 0; magindex < nmagic; magindex++) {
+ /* if main entry matches, print it... */
+ if (!mget(&p, s, &magic[magindex], nbytes) ||
+ !mcheck(&p, &magic[magindex])) {
+ /*
+ * main entry didn't match,
+ * flush its continuations
+ */
+ while (magindex < nmagic &&
+ magic[magindex + 1].cont_level != 0)
+ magindex++;
+ continue;
+ }
+
+ tmpoff[cont_level] = mprint(&p, &magic[magindex]);
+ /*
+ * If we printed something, we'll need to print
+ * a blank before we print something else.
+ */
+ if (magic[magindex].desc[0])
+ need_separator = 1;
+ /* and any continuations that match */
+ if (++cont_level >= tmplen)
+ if ((tmpoff = (int32 *) realloc(tmpoff,
+ tmplen += 20)) == NULL)
+ error("out of memory\n");
+ while (magic[magindex+1].cont_level != 0 &&
+ ++magindex < nmagic) {
+ if (cont_level >= magic[magindex].cont_level) {
+ if (cont_level > magic[magindex].cont_level) {
+ /*
+ * We're at the end of the level
+ * "cont_level" continuations.
+ */
+ cont_level = magic[magindex].cont_level;
+ }
+ if (magic[magindex].flag & ADD) {
+ oldoff=magic[magindex].offset;
+ magic[magindex].offset += tmpoff[cont_level-1];
+ }
+ if (mget(&p, s, &magic[magindex], nbytes) &&
+ mcheck(&p, &magic[magindex])) {
+ /*
+ * This continuation matched.
+ * Print its message, with
+ * a blank before it if
+ * the previous item printed
+ * and this item isn't empty.
+ */
+ /* space if previous printed */
+ if (need_separator
+ && (magic[magindex].nospflag == 0)
+ && (magic[magindex].desc[0] != '\0')
+ ) {
+ (void) putchar(' ');
+ need_separator = 0;
+ }
+ tmpoff[cont_level] = mprint(&p, &magic[magindex]);
+ if (magic[magindex].desc[0])
+ need_separator = 1;
+
+ /*
+ * If we see any continuations
+ * at a higher level,
+ * process them.
+ */
+ if (++cont_level >= tmplen)
+ if ((tmpoff =
+ (int32 *) realloc(tmpoff,
+ tmplen += 20)) == NULL)
+ error("out of memory\n");
+ }
+ if (magic[magindex].flag & ADD) {
+ magic[magindex].offset = oldoff;
+ }
+ }
+ }
+ return 1; /* all through */
+ }
+ return 0; /* no match at all */
+}
+
+static int32
+mprint(p, m)
+union VALUETYPE *p;
+struct magic *m;
+{
+ char *pp, *rt;
+ uint32 v;
+ int32 t=0 ;
+
+
+ switch (m->type) {
+ case BYTE:
+ v = p->b;
+ v = signextend(m, v) & m->mask;
+ (void) printf(m->desc, (unsigned char) v);
+ t = m->offset + sizeof(char);
+ break;
+
+ case SHORT:
+ case BESHORT:
+ case LESHORT:
+ v = p->h;
+ v = signextend(m, v) & m->mask;
+ (void) printf(m->desc, (unsigned short) v);
+ t = m->offset + sizeof(short);
+ break;
+
+ case LONG:
+ case BELONG:
+ case LELONG:
+ v = p->l;
+ v = signextend(m, v) & m->mask;
+ (void) printf(m->desc, (uint32) v);
+ t = m->offset + sizeof(int32);
+ break;
+
+ case STRING:
+ if (m->reln == '=') {
+ (void) printf(m->desc, m->value.s);
+ t = m->offset + strlen(m->value.s);
+ }
+ else {
+ if (*m->value.s == '\0') {
+ char *cp = strchr(p->s,'\n');
+ if (cp)
+ *cp = '\0';
+ }
+ (void) printf(m->desc, p->s);
+ t = m->offset + strlen(p->s);
+ }
+ break;
+
+ case DATE:
+ case BEDATE:
+ case LEDATE:
+ pp = ctime((time_t*) &p->l);
+ if ((rt = strchr(pp, '\n')) != NULL)
+ *rt = '\0';
+ (void) printf(m->desc, pp);
+ t = m->offset + sizeof(time_t);
+ break;
+
+ default:
+ error("invalid m->type (%d) in mprint().\n", m->type);
+ /*NOTREACHED*/
+ }
+ return(t);
+}
+
+/*
+ * Convert the byte order of the data we are looking at
+ */
+static int
+mconvert(p, m)
+union VALUETYPE *p;
+struct magic *m;
+{
+ switch (m->type) {
+ case BYTE:
+ case SHORT:
+ case LONG:
+ case DATE:
+ return 1;
+ case STRING:
+ {
+ char *ptr;
+
+ /* Null terminate and eat the return */
+ p->s[sizeof(p->s) - 1] = '\0';
+ if ((ptr = strchr(p->s, '\n')) != NULL)
+ *ptr = '\0';
+ return 1;
+ }
+ case BESHORT:
+ p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
+ return 1;
+ case BELONG:
+ case BEDATE:
+ p->l = (int32)
+ ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
+ return 1;
+ case LESHORT:
+ p->h = (short)((p->hs[1]<<8)|(p->hs[0]));
+ return 1;
+ case LELONG:
+ case LEDATE:
+ p->l = (int32)
+ ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
+ return 1;
+ default:
+ error("invalid type %d in mconvert().\n", m->type);
+ return 0;
+ }
+}
+
+
+static void
+mdebug(offset, str, len)
+int32 offset;
+char *str;
+int len;
+{
+ (void) fprintf(stderr, "mget @%d: ", offset);
+ showstr(stderr, (char *) str, len);
+ (void) fputc('\n', stderr);
+ (void) fputc('\n', stderr);
+}
+
+static int
+mget(p, s, m, nbytes)
+union VALUETYPE* p;
+unsigned char *s;
+struct magic *m;
+int nbytes;
+{
+ int32 offset = m->offset;
+
+ if (offset + sizeof(union VALUETYPE) <= nbytes)
+ memcpy(p, s + offset, sizeof(union VALUETYPE));
+ else {
+ /*
+ * the usefulness of padding with zeroes eludes me, it
+ * might even cause problems
+ */
+ int32 have = nbytes - offset;
+ memset(p, 0, sizeof(union VALUETYPE));
+ if (have > 0)
+ memcpy(p, s + offset, have);
+ }
+
+
+ if (debug) {
+ mdebug(offset, (char *) p, sizeof(union VALUETYPE));
+ mdump(m);
+ }
+
+ if (!mconvert(p, m))
+ return 0;
+
+ if (m->flag & INDIR) {
+
+ switch (m->in.type) {
+ case BYTE:
+ offset = p->b + m->in.offset;
+ break;
+ case SHORT:
+ offset = p->h + m->in.offset;
+ break;
+ case LONG:
+ offset = p->l + m->in.offset;
+ break;
+ }
+
+ if (offset + sizeof(union VALUETYPE) > nbytes)
+ return 0;
+
+ memcpy(p, s + offset, sizeof(union VALUETYPE));
+
+ if (debug) {
+ mdebug(offset, (char *) p, sizeof(union VALUETYPE));
+ mdump(m);
+ }
+
+ if (!mconvert(p, m))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+mcheck(p, m)
+union VALUETYPE* p;
+struct magic *m;
+{
+ register uint32 l = m->value.l;
+ register uint32 v;
+ int matched;
+
+ if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
+ fprintf(stderr, "BOINK");
+ return 1;
+ }
+
+
+ switch (m->type) {
+ case BYTE:
+ v = p->b;
+ break;
+
+ case SHORT:
+ case BESHORT:
+ case LESHORT:
+ v = p->h;
+ break;
+
+ case LONG:
+ case BELONG:
+ case LELONG:
+ case DATE:
+ case BEDATE:
+ case LEDATE:
+ v = p->l;
+ break;
+
+ case STRING:
+ l = 0;
+ /* What we want here is:
+ * v = strncmp(m->value.s, p->s, m->vallen);
+ * but ignoring any nulls. bcmp doesn't give -/+/0
+ * and isn't universally available anyway.
+ */
+ v = 0;
+ {
+ register unsigned char *a = (unsigned char*)m->value.s;
+ register unsigned char *b = (unsigned char*)p->s;
+ register int len = m->vallen;
+
+ while (--len >= 0)
+ if ((v = *b++ - *a++) != '\0')
+ break;
+ }
+ break;
+ default:
+ error("invalid type %d in mcheck().\n", m->type);
+ return 0;/*NOTREACHED*/
+ }
+
+ v = signextend(m, v) & m->mask;
+
+ switch (m->reln) {
+ case 'x':
+ if (debug)
+ (void) fprintf(stderr, "%u == *any* = 1\n", v);
+ matched = 1;
+ break;
+
+ case '!':
+ matched = v != l;
+ if (debug)
+ (void) fprintf(stderr, "%u != %u = %d\n",
+ v, l, matched);
+ break;
+
+ case '=':
+ matched = v == l;
+ if (debug)
+ (void) fprintf(stderr, "%u == %u = %d\n",
+ v, l, matched);
+ break;
+
+ case '>':
+ if (m->flag & UNSIGNED) {
+ matched = v > l;
+ if (debug)
+ (void) fprintf(stderr, "%u > %u = %d\n",
+ v, l, matched);
+ }
+ else {
+ matched = (int32) v > (int32) l;
+ if (debug)
+ (void) fprintf(stderr, "%d > %d = %d\n",
+ v, l, matched);
+ }
+ break;
+
+ case '<':
+ if (m->flag & UNSIGNED) {
+ matched = v < l;
+ if (debug)
+ (void) fprintf(stderr, "%u < %u = %d\n",
+ v, l, matched);
+ }
+ else {
+ matched = (int32) v < (int32) l;
+ if (debug)
+ (void) fprintf(stderr, "%d < %d = %d\n",
+ v, l, matched);
+ }
+ break;
+
+ case '&':
+ matched = (v & l) == l;
+ if (debug)
+ (void) fprintf(stderr, "((%x & %x) == %x) = %d\n",
+ v, l, l, matched);
+ break;
+
+ case '^':
+ matched = (v & l) != l;
+ if (debug)
+ (void) fprintf(stderr, "((%x & %x) != %x) = %d\n",
+ v, l, l, matched);
+ break;
+
+ default:
+ matched = 0;
+ error("mcheck: can't happen: invalid relation %d.\n", m->reln);
+ break;/*NOTREACHED*/
+ }
+
+ return matched;
+}
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* $OpenBSD: tar.h,v 1.3 1997/02/09 23:58:37 millert Exp $ */
+
+/*
+ * Header file for public domain tar (tape archive) program.
+ *
+ * @(#)tar.h 1.20 86/10/29 Public Domain.
+ *
+ * Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu.
+ *
+ */
+
+/*
+ * Kludge for handling systems that can't cope with multiple
+ * external definitions of a variable. In ONE routine (tar.c),
+ * we #define TAR_EXTERN to null; here, we set it to "extern" if
+ * it is not already set.
+ */
+#ifndef TAR_EXTERN
+#define TAR_EXTERN extern
+#endif
+
+/*
+ * Header block on tape.
+ *
+ * I'm going to use traditional DP naming conventions here.
+ * A "block" is a big chunk of stuff that we do I/O on.
+ * A "record" is a piece of info that we care about.
+ * Typically many "record"s fit into a "block".
+ */
+#define RECORDSIZE 512
+#define NAMSIZ 100
+#define TUNMLEN 32
+#define TGNMLEN 32
+
+union record {
+ char charptr[RECORDSIZE];
+ struct header {
+ char name[NAMSIZ];
+ char mode[8];
+ char uid[8];
+ char gid[8];
+ char size[12];
+ char mtime[12];
+ char chksum[8];
+ char linkflag;
+ char linkname[NAMSIZ];
+ char magic[8];
+ char uname[TUNMLEN];
+ char gname[TGNMLEN];
+ char devmajor[8];
+ char devminor[8];
+ } header;
+};
+
+/* The checksum field is filled with this while the checksum is computed. */
+#define CHKBLANKS " " /* 8 blanks, no null */
+
+/* The magic field is filled with this if uname and gname are valid. */
+#define TMAGIC "ustar " /* 7 chars and a null */
+
+/* The linkflag defines the type of file */
+#define LF_OLDNORMAL '\0' /* Normal disk file, Unix compat */
+#define LF_NORMAL '0' /* Normal disk file */
+#define LF_LINK '1' /* Link to previously dumped file */
+#define LF_SYMLINK '2' /* Symbolic link */
+#define LF_CHR '3' /* Character special file */
+#define LF_BLK '4' /* Block special file */
+#define LF_DIR '5' /* Directory */
+#define LF_FIFO '6' /* FIFO special file */
+#define LF_CONTIG '7' /* Contiguous file */
+/* Further link types may be defined later. */
+
+/*
+ * Exit codes from the "tar" program
+ */
+#define EX_SUCCESS 0 /* success! */
+#define EX_ARGSBAD 1 /* invalid args */
+#define EX_BADFILE 2 /* invalid filename */
+#define EX_BADARCH 3 /* bad archive */
+#define EX_SYSTEM 4 /* system gave unexpected error */
+
+
+/*
+ * Global variables
+ */
+TAR_EXTERN union record *ar_block; /* Start of block of archive */
+TAR_EXTERN union record *ar_record; /* Current record of archive */
+TAR_EXTERN union record *ar_last; /* Last+1 record of archive block */
+TAR_EXTERN char ar_reading; /* 0 writing, !0 reading archive */
+TAR_EXTERN int blocking; /* Size of each block, in records */
+TAR_EXTERN int blocksize; /* Size of each block, in bytes */
+TAR_EXTERN char *ar_file; /* File containing archive */
+TAR_EXTERN char *name_file; /* File containing names to work on */
+TAR_EXTERN char *tar; /* Name of this program */
+
+/*
+ * Flags from the command line
+ */
+TAR_EXTERN char f_reblock; /* -B */
+TAR_EXTERN char f_create; /* -c */
+TAR_EXTERN char f_debug; /* -d */
+TAR_EXTERN char f_sayblock; /* -D */
+TAR_EXTERN char f_follow_links; /* -h */
+TAR_EXTERN char f_ignorez; /* -i */
+TAR_EXTERN char f_keep; /* -k */
+TAR_EXTERN char f_modified; /* -m */
+TAR_EXTERN char f_oldarch; /* -o */
+TAR_EXTERN char f_use_protection; /* -p */
+TAR_EXTERN char f_sorted_names; /* -s */
+TAR_EXTERN char f_list; /* -t */
+TAR_EXTERN char f_namefile; /* -T */
+TAR_EXTERN char f_verbose; /* -v */
+TAR_EXTERN char f_extract; /* -x */
+TAR_EXTERN char f_compress; /* -z */
+
+/*
+ * We now default to Unix Standard format rather than 4.2BSD tar format.
+ * The code can actually produce all three:
+ * f_standard ANSI standard
+ * f_oldarch V7
+ * neither 4.2BSD
+ * but we don't bother, since 4.2BSD can read ANSI standard format anyway.
+ * The only advantage to the "neither" option is that we can cmp(1) our
+ * output to the output of 4.2BSD tar, for debugging.
+ */
+#define f_standard (!f_oldarch)
+
+/*
+ * Structure for keeping track of filenames and lists thereof.
+ */
+struct name {
+ struct name *next;
+ short length;
+ char found;
+ char name[NAMSIZ+1];
+};
+
+TAR_EXTERN struct name *namelist; /* Points to first name in list */
+TAR_EXTERN struct name *namelast; /* Points to last name in list */
+
+TAR_EXTERN int archive; /* File descriptor for archive file */
+TAR_EXTERN int errors; /* # of files in error */
+
+/*
+ *
+ * Due to the next struct declaration, each routine that includes
+ * "tar.h" must also include <sys/types.h>. I tried to make it automatic,
+ * but System V has no defines in <sys/types.h>, so there is no way of
+ * knowing when it has been included. In addition, it cannot be included
+ * twice, but must be included exactly once. Argghh!
+ *
+ * Thanks, typedef. Thanks, USG.
+ */
+struct link {
+ struct link *next;
+ dev_t dev;
+ ino_t ino;
+ short linkcount;
+ char name[NAMSIZ+1];
+};
+
+TAR_EXTERN struct link *linklist; /* Points to first link in list */
+
+
+/*
+ * Error recovery stuff
+ */
+TAR_EXTERN char read_error_flag;
+
+
+/*
+ * Declarations of functions available to the world.
+ */
+/*LINTLIBRARY*/
+union record *findrec();
+void userec();
+union record *endofrecs();
+void anno();
+#define annorec(stream, msg) anno(stream, msg, 0) /* Cur rec */
+#define annofile(stream, msg) anno(stream, msg, 1) /* Saved rec */
-.\" $NetBSD: install.1,v 1.11 1998/09/28 08:16:15 christos Exp $
-.\"
.\" Copyright (c) 1987, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)install.1 8.1 (Berkeley) 6/6/93
+.\" From: @(#)install.1 8.1 (Berkeley) 6/6/93
+.\" $FreeBSD: src/usr.bin/xinstall/install.1,v 1.21 2001/05/30 09:45:47 ru Exp $
.\"
-.Dd June 6, 1993
+.Dd May 7, 2001
.Dt INSTALL 1
-.Os BSD 4.2
+.Os
.Sh NAME
.Nm install
.Nd install binaries
.Sh SYNOPSIS
.Nm
-.Op Fl cps
+.Op Fl bCcMpSsv
+.Op Fl B Ar suffix
.Op Fl f Ar flags
+.Op Fl g Ar group
.Op Fl m Ar mode
.Op Fl o Ar owner
-.Op Fl g Ar group
-.Op Fl l Ar linkflags
-.Op Fl S Ar stripflag
.Ar file1 file2
-.Nm ""
-.Op Fl cps
+.Nm
+.Op Fl bCcMpSsv
+.Op Fl B Ar suffix
.Op Fl f Ar flags
+.Op Fl g Ar group
.Op Fl m Ar mode
.Op Fl o Ar owner
+.Ar file1 ... fileN directory
+.Nm
+.Fl d
+.Op Fl v
.Op Fl g Ar group
-.Op Fl l Ar linkflags
-.Op Fl S Ar stripflag
-.Ar file1
-\&...
-.Ar fileN directory
-.Nm ""
-.Fl pd
.Op Fl m Ar mode
.Op Fl o Ar owner
-.Op Fl g Ar group
-.Ar directory
-\&...
+.Ar directory ...
.Sh DESCRIPTION
-The file(s) are moved (copied if the
-.Fl c
-option is specified, or linked if the
-.Fl l
-option is specified) to the target file or directory.
+The file(s) are copied
+to the target file or directory.
If the destination is a directory, then the
.Ar file
-is moved into
+is copied into
.Ar directory
with its original filename.
-If the target file already exists, it is overwritten if permissions
-allow.
+If the target file already exists, it is
+either renamed to
+.Ar file Ns Pa .old
+if the
+.Fl b
+option is given
+or overwritten
+if permissions allow.
+An alternate backup suffix may be specified via the
+.Fl B
+option's argument.
.Pp
-.Bl -tag -width Ds
+The options are as follows:
+.Bl -tag -width indent
+.It Fl b
+Back up any existing files before overwriting them by renaming
+them to
+.Ar file Ns Pa .old .
+See
+.Fl B
+for specifying a different backup suffix.
+.It Fl B Ar suffix
+Use
+.Ar suffix
+as the backup suffix if
+.Fl b
+is given.
+.It Fl C
+Copy the file.
+If the target file already exists and the files are the same,
+then don't change the modification time of the target.
.It Fl c
Copy the file.
-This flag turns off the default behavior of
-.Nm
-where it deletes the original file after creating the target.
+This is actually the default.
+The
+.Fl c
+option is only included for backwards compatibility.
+.It Fl d
+Create directories.
+Missing parent directories are created as required.
.It Fl f
-Specify the target's file flags.
-(See
+Specify the target's file flags; see
.Xr chflags 1
-for a list of possible flags and their meanings.)
+for a list of possible flags and their meanings.
.It Fl g
Specify a group.
+A numeric GID is allowed.
+.It Fl M
+Disable all use of
+.Xr mmap 2 .
.It Fl m
-Specify an alternative mode.
+Specify an alternate mode.
The default mode is set to rwxr-xr-x (0755).
The specified mode may be either an octal or symbolic value; see
-.Xr chmod 1
+.Xr chmod 1
for a description of possible mode values.
-.It Fl l Ar linkflags
-Instead of copying the file make a link to the source. The type of the
-link is determined by the
-.Ar linkflags
-argument. Valid
-.Ar linkflags
-are:
-.Ar a
-(absolute),
-.Ar r
-(relative),
-.Ar h
-(hard),
-.Ar s
-(symbolic),
-.Ar m
-(mixed). Absolute and relative have effect only for symbolic links. Mixed links
-are hard links for files on the same filesystem, symbolic otherwise.
.It Fl o
Specify an owner.
+A numeric UID is allowed.
.It Fl p
-Preserve the source files access and modification times.
+Preserve the modification time.
+Copy the file, as if the
+.Fl C
+(compare and copy) option is specified,
+except if the target file doesn't already exist or is different,
+then preserve the modification time of the file.
+.It Fl S
+Safe copy.
+Normally,
+.Nm
+unlinks an existing target before installing the new file.
+With the
+.Fl S
+flag a temporary file is used and then renamed to be
+the target.
+The reason this is safer is that if the copy or
+rename fails, the existing target is left untouched.
.It Fl s
.Nm
exec's the command
-.Xr strip 1
-to strip binaries so that install can be portable over a large
-number of systems and binary types. If the environment variable
-.Ev STRIP
-is set, it is used as the
.Xr strip 1
-program.
-.It Fl S Ar stripflags
-.Nm
-passes
-.Ar stripflags
-as option arguments to
-.Xr strip 1 .
-When -S is used,
-.Xr strip 1
-is invoked via the
-.Xr sh 1
-shell, allowing a single -S argument be to specified to
+to strip binaries so that
.Nm
-which the shell can then tokenize. Normally,
+can be portable over a large
+number of systems and binary types.
+.It Fl v
+Causes
.Nm
-invokes
-.Xr strip 1
-directly. This flag implies -s.
-.It Fl d
-Create directories.
-Missing parent directories are created as required.
+to show when
+.Fl C
+actually installs something.
.El
.Pp
By default,
.Nm
-preserves all file flags, with the exception of the ``nodump'' flag.
+preserves all file flags, with the exception of the
+.Dq nodump
+flag.
.Pp
The
.Nm
Installing
.Pa /dev/null
creates an empty file.
-.Pp
-Upon successful completion a value of 0 is returned.
-Otherwise, a value of 1 is returned.
+.Sh DIAGNOSTICS
+The
+.Nm
+utility exits 0 on success, and 1 otherwise.
+.Sh FILES
+.Bl -tag -width INS@XXXX -compact
+.It Pa INS@XXXX
+If either
+.Fl S
+option is specified, or the
+.Fl C
+or
+.Fl p
+option is used in conjuction with the
+.Fl s
+option, temporary files named
+.Pa INS@XXXX ,
+where
+.Pa XXXX
+is decided by
+.Xr mkstemp 3 ,
+are created in the target directory.
+.El
+.Sh COMPATIBILITY
+Historically
+.Nm
+moved files by default.
+The default was changed to copy in
+.Fx 4.4 .
.Sh SEE ALSO
.Xr chflags 1 ,
.Xr chgrp 1 ,
.Xr cp 1 ,
.Xr mv 1 ,
.Xr strip 1 ,
+.Xr mmap 2 ,
.Xr chown 8
.Sh HISTORY
The
.Nm
utility appeared in
.Bx 4.2 .
+.Sh BUGS
+Temporary files may be left in the target directory if
+.Nm
+exits abnormally.
+.Pp
+File flags cannot be set by
+.Xr fchflags 2
+over a NFS file system. Other file systems do not have a concept of flags.
+.Nm
+will only warn when flags could not be set on a file system
+that does not support them.
+.Pp
+.Nm
+with
+.Fl v
+falsely says a file is copied when
+.Fl C
+snaps hard links.
-/* $NetBSD: pathnames.h,v 1.4 1997/12/30 22:31:17 thorpej Exp $ */
-
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
-/* $NetBSD: xinstall.c,v 1.27 1998/10/01 18:23:52 erh Exp $ */
-
/*
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1987, 1993\n\
- The Regents of the University of California. All rights reserved.\n");
+static const char copyright[] =
+"@(#) Copyright (c) 1987, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
-static char sccsid[] = "@(#)xinstall.c 8.1 (Berkeley) 7/21/93";
-#else
-__RCSID("$NetBSD: xinstall.c,v 1.27 1998/10/01 18:23:52 erh Exp $");
+static char sccsid[] = "From: @(#)xinstall.c 8.1 (Berkeley) 7/21/93";
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/usr.bin/xinstall/xinstall.c,v 1.43 2001/05/30 07:08:49 ru Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <sys/mount.h>
#include <ctype.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <err.h>
+#include <sysexits.h>
+#include <utime.h>
#include "pathnames.h"
-#define STRIP_ARGS_MAX 32
+/* Bootstrap aid - this doesn't exist in most older releases */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1) /* from <sys/mman.h> */
+#endif
+
+#define DIRECTORY 0x01 /* Tell install it's a directory. */
+#define SETFLAGS 0x02 /* Tell install to set flags. */
+#define NOCHANGEBITS (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
+#define BACKUP_SUFFIX ".old"
struct passwd *pp;
struct group *gp;
-int docopy=0, dodir=0, dostrip=0, dolink=0, dopreserve=0;
-int mode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
-char pathbuf[MAXPATHLEN];
-uid_t uid;
gid_t gid;
-char *stripArgs=NULL;
-
-#define LN_ABSOLUTE 0x01
-#define LN_RELATIVE 0x02
-#define LN_HARD 0x04
-#define LN_SYMBOLIC 0x08
-#define LN_MIXED 0x10
-
-#define DIRECTORY 0x01 /* Tell install it's a directory. */
-#define SETFLAGS 0x02 /* Tell install to set flags. */
+uid_t uid;
+int dobackup, docompare, dodir, dopreserve, dostrip, nommap, safecopy, verbose;
+mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+char *suffix = BACKUP_SUFFIX;
+#ifdef __APPLE__
+u_long string_to_flags __P((char **, u_long *, u_long *));
+#define strtofflags(x,y,z) string_to_flags((x),(y),(z))
+#endif
void copy __P((int, char *, int, char *, off_t));
-void makelink __P((char *, char *));
+int compare __P((int, const char *, size_t, int, const char *, size_t));
+int create_newfile __P((char *, int, struct stat *));
+int create_tempfile __P((char *, char *, size_t));
void install __P((char *, char *, u_long, u_int));
void install_dir __P((char *));
-u_long string_to_flags __P((char **, u_long *, u_long *));
+u_long numeric_id __P((char *, char *));
void strip __P((char *));
+int trymmap __P((int));
void usage __P((void));
-int main __P((int, char *[]));
int
main(argc, argv)
struct stat from_sb, to_sb;
mode_t *set;
u_long fset;
- u_int iflags;
int ch, no_target;
- char *p;
- char *flags = NULL, *to_name, *group = NULL, *owner = NULL;
+ u_int iflags;
+ char *flags, *group, *owner, *to_name;
iflags = 0;
- while ((ch = getopt(argc, argv, "cdf:g:l:m:o:psS:")) != -1)
+ group = owner = NULL;
+ while ((ch = getopt(argc, argv, "B:bCcdf:g:Mm:o:pSsv")) != -1)
switch((char)ch) {
+ case 'B':
+ suffix = optarg;
+ /* FALLTHROUGH */
+ case 'b':
+ dobackup = 1;
+ break;
+ case 'C':
+ docompare = 1;
+ break;
case 'c':
- docopy = 1;
+ /* For backwards compatibility. */
break;
case 'd':
dodir = 1;
break;
case 'f':
flags = optarg;
- if (string_to_flags(&flags, &fset, NULL))
- errx(1, "%s: invalid flag", flags);
+ if (strtofflags(&flags, &fset, NULL))
+ errx(EX_USAGE, "%s: invalid flag", flags);
iflags |= SETFLAGS;
break;
case 'g':
group = optarg;
break;
- case 'l':
- for (p = optarg; *p; p++)
- switch (*p) {
- case 's':
- dolink &= ~(LN_HARD|LN_MIXED);
- dolink |= LN_SYMBOLIC;
- break;
- case 'h':
- dolink &= ~(LN_SYMBOLIC|LN_MIXED);
- dolink |= LN_HARD;
- break;
- case 'm':
- dolink &= ~(LN_SYMBOLIC|LN_HARD);
- dolink |= LN_MIXED;
- break;
- case 'a':
- dolink &= ~LN_RELATIVE;
- dolink |= LN_ABSOLUTE;
- break;
- case 'r':
- dolink &= ~LN_ABSOLUTE;
- dolink |= LN_RELATIVE;
- break;
- default:
- errx(1, "%c: invalid link type", *p);
- break;
- }
+ case 'M':
+ nommap = 1;
break;
case 'm':
if (!(set = setmode(optarg)))
- errx(1, "%s: invalid file mode", optarg);
+ errx(EX_USAGE, "invalid file mode: %s",
+ optarg);
mode = getmode(set, 0);
+ free(set);
break;
case 'o':
owner = optarg;
break;
case 'p':
- dopreserve = 1;
+ docompare = dopreserve = 1;
break;
case 'S':
- stripArgs = (char*)malloc(sizeof(char)*(strlen(optarg)+1));
- strcpy(stripArgs,optarg);
- /* fall through; -S implies -s */
+ safecopy = 1;
+ break;
case 's':
dostrip = 1;
break;
+ case 'v':
+ verbose = 1;
+ break;
case '?':
default:
usage();
argc -= optind;
argv += optind;
- /* strip and link options make no sense when creating directories */
- if ((dostrip || dolink) && dodir)
+ /* some options make no sense when creating directories */
+ if ((safecopy || dostrip) && dodir)
usage();
- /* strip and flags make no sense with links */
- if ((dostrip || flags) && dolink)
- usage();
+ /*
+ * Older versions allowed -d -C combo. Issue a warning
+ * for now, but turn this into an error before 4.5-RELEASE.
+ */
+ if (docompare && dodir)
+ warnx("the -d and -C options may not be specified together");
/* must have at least two arguments, except when creating directories */
if (argc < 2 && !dodir)
usage();
+ /* need to make a temp copy so we can compare stripped version */
+ if (docompare && dostrip)
+ safecopy = 1;
+
/* get group and owner id's */
- if (group && !(gp = getgrnam(group)) && !isdigit(*group))
- errx(1, "unknown group %s", group);
- gid = (group) ? ((gp) ? gp->gr_gid : atoi(group)) : -1;
- if (owner && !(pp = getpwnam(owner)) && !isdigit(*owner))
- errx(1, "unknown user %s", owner);
- uid = (owner) ? ((pp) ? pp->pw_uid : atoi(owner)) : -1;
+ if (group != NULL) {
+ if ((gp = getgrnam(group)) != NULL)
+ gid = gp->gr_gid;
+ else
+ gid = (uid_t)numeric_id(group, "group");
+ } else
+ gid = (gid_t)-1;
+
+ if (owner != NULL) {
+ if ((pp = getpwnam(owner)) != NULL)
+ uid = pp->pw_uid;
+ else
+ uid = (uid_t)numeric_id(owner, "user");
+ } else
+ uid = (uid_t)-1;
if (dodir) {
for (; *argv != NULL; ++argv)
install_dir(*argv);
- exit (0);
+ exit(EX_OK);
+ /* NOTREACHED */
}
no_target = stat(to_name = argv[argc - 1], &to_sb);
if (!no_target && S_ISDIR(to_sb.st_mode)) {
for (; *argv != to_name; ++argv)
install(*argv, to_name, fset, iflags | DIRECTORY);
- exit(0);
+ exit(EX_OK);
+ /* NOTREACHED */
}
/* can't do file1 file2 directory/file */
if (!no_target) {
if (stat(*argv, &from_sb))
- err(1, "%s", *argv);
- if (!S_ISREG(to_sb.st_mode))
- errx(1, "%s: %s", to_name, strerror(EFTYPE));
- if (!dolink && to_sb.st_dev == from_sb.st_dev &&
+ err(EX_OSERR, "%s", *argv);
+ if (!S_ISREG(to_sb.st_mode)) {
+ errno = EFTYPE;
+ err(EX_OSERR, "%s", to_name);
+ }
+ if (to_sb.st_dev == from_sb.st_dev &&
to_sb.st_ino == from_sb.st_ino)
- errx(1, "%s and %s are the same file", *argv, to_name);
- /*
- * Unlink now... avoid ETXTBSY errors later. Try and turn
- * off the append/immutable bits -- if we fail, go ahead,
- * it might work.
- */
-#define NOCHANGEBITS (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
- if (to_sb.st_flags & NOCHANGEBITS)
- (void)chflags(to_name,
- to_sb.st_flags & ~(NOCHANGEBITS));
- (void)unlink(to_name);
+ errx(EX_USAGE,
+ "%s and %s are the same file", *argv, to_name);
}
install(*argv, to_name, fset, iflags);
- exit(0);
+ exit(EX_OK);
+ /* NOTREACHED */
}
-/*
- * makelink --
- * make a link from source to destination
- */
-void
-makelink(from_name, to_name)
- char *from_name;
- char *to_name;
+u_long
+numeric_id(name, type)
+ char *name, *type;
{
- char src[MAXPATHLEN], dst[MAXPATHLEN], lnk[MAXPATHLEN];
-
- /* Try hard links first */
- if (dolink & (LN_HARD|LN_MIXED)) {
- if (link(from_name, to_name) == -1) {
- if ((dolink & LN_HARD) || errno != EXDEV)
- err(1, "link %s -> %s", from_name, to_name);
- }
- else
- return;
- }
-
- /* Symbolic links */
- if (dolink & LN_ABSOLUTE) {
- /* Convert source path to absolute */
- if (realpath(from_name, src) == NULL)
- err(1, "%s", src);
- if (symlink(src, to_name) == -1)
- err(1, "symlink %s -> %s", src, to_name);
- return;
- }
-
- if (dolink & LN_RELATIVE) {
- char *s, *d;
-
- /* Resolve pathnames */
- if (realpath(from_name, src) == NULL)
- err(1, "%s", src);
- if (realpath(to_name, dst) == NULL)
- err(1, "%s", dst);
-
- /* trim common path components */
- for (s = src, d = dst; *s == *d; s++, d++)
- continue;
- while (*s != '/')
- s--, d--;
-
- /* count the number of directories we need to backtrack */
- for (++d, lnk[0] = '\0'; *d; d++)
- if (*d == '/')
- (void) strcat(lnk, "../");
-
- (void) strcat(lnk, ++s);
-
- if (symlink(lnk, dst) == -1)
- err(1, "symlink %s -> %s", lnk, dst);
- return;
- }
+ u_long val;
+ char *ep;
/*
- * If absolute or relative was not specified,
- * try the names the user provided
+ * XXX
+ * We know that uid_t's and gid_t's are unsigned longs.
*/
- if (symlink(from_name, to_name) == -1)
- err(1, "symlink %s -> %s", from_name, to_name);
-
+ errno = 0;
+ val = strtoul(name, &ep, 10);
+ if (errno)
+ err(EX_NOUSER, "%s", name);
+ if (*ep != '\0')
+ errx(EX_NOUSER, "unknown %s %s", type, name);
+ return (val);
}
/*
u_long fset;
u_int flags;
{
- struct stat from_sb, to_sb;
- int devnull, from_fd, to_fd, serrno;
- char *p;
+ struct stat from_sb, temp_sb, to_sb;
+ struct utimbuf utb;
+ int devnull, files_match, from_fd=0, serrno, target;
+ int tempcopy, temp_fd, to_fd=0;
+ char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN];
+
+ files_match = 0;
/* If try to install NULL file to a directory, fails. */
if (flags & DIRECTORY || strcmp(from_name, _PATH_DEVNULL)) {
if (stat(from_name, &from_sb))
- err(1, "%s", from_name);
- if (!S_ISREG(from_sb.st_mode))
- errx(1, "%s: %s", from_name, strerror(EFTYPE));
+ err(EX_OSERR, "%s", from_name);
+ if (!S_ISREG(from_sb.st_mode)) {
+ errno = EFTYPE;
+ err(EX_OSERR, "%s", from_name);
+ }
/* Build the target path. */
if (flags & DIRECTORY) {
(void)snprintf(pathbuf, sizeof(pathbuf), "%s/%s",
}
devnull = 0;
} else {
- from_sb.st_flags = 0; /* XXX */
devnull = 1;
}
- /*
- * Unlink now... avoid ETXTBSY errors later. Try and turn
- * off the append/immutable bits -- if we fail, go ahead,
- * it might work.
- */
- if (stat(to_name, &to_sb) == 0 &&
- to_sb.st_flags & (NOCHANGEBITS))
- (void)chflags(to_name, to_sb.st_flags & ~(NOCHANGEBITS));
- (void)unlink(to_name);
+ target = stat(to_name, &to_sb) == 0;
- if (dolink) {
- makelink(from_name, to_name);
+ /* Only install to regular files. */
+ if (target && !S_ISREG(to_sb.st_mode)) {
+ errno = EFTYPE;
+ warn("%s", to_name);
return;
}
- /* Create target. */
- if ((to_fd = open(to_name,
- O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR)) < 0)
- err(1, "%s", to_name);
- if (!devnull) {
- if ((from_fd = open(from_name, O_RDONLY, 0)) < 0) {
- (void)unlink(to_name);
- err(1, "%s", from_name);
+ /* Only copy safe if the target exists. */
+ tempcopy = safecopy && target;
+
+ if (!devnull && (from_fd = open(from_name, O_RDONLY, 0)) < 0)
+ err(EX_OSERR, "%s", from_name);
+
+ /* If we don't strip, we can compare first. */
+ if (docompare && !dostrip && target) {
+ if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)
+ err(EX_OSERR, "%s", to_name);
+ if (devnull)
+ files_match = to_sb.st_size == 0;
+ else
+ files_match = !(compare(from_fd, from_name,
+ (size_t)from_sb.st_size, to_fd,
+ to_name, (size_t)to_sb.st_size));
+
+ /* Close "to" file unless we match. */
+ if (!files_match)
+ (void)close(to_fd);
+ }
+
+ if (!files_match) {
+ if (tempcopy) {
+ to_fd = create_tempfile(to_name, tempfile,
+ sizeof(tempfile));
+ if (to_fd < 0)
+ err(EX_OSERR, "%s", tempfile);
+ } else {
+ if ((to_fd = create_newfile(to_name, target,
+ &to_sb)) < 0)
+ err(EX_OSERR, "%s", to_name);
+ if (verbose)
+ (void)printf("install: %s -> %s\n",
+ from_name, to_name);
}
- copy(from_fd, from_name, to_fd, to_name, from_sb.st_size);
- (void)close(from_fd);
+ if (!devnull)
+ copy(from_fd, from_name, to_fd,
+ tempcopy ? tempfile : to_name, from_sb.st_size);
}
if (dostrip) {
- strip(to_name);
+ strip(tempcopy ? tempfile : to_name);
/*
* Re-open our fd on the target, in case we used a strip
- * that does not work in-place -- like gnu binutils strip.
+ * that does not work in-place -- like GNU binutils strip.
*/
close(to_fd);
- if ((to_fd = open(to_name, O_RDONLY, S_IRUSR | S_IWUSR)) < 0)
- err(1, "stripping %s", to_name);
+ to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY, 0);
+ if (to_fd < 0)
+ err(EX_OSERR, "stripping %s", to_name);
}
/*
- * Set owner, group, mode for target; do the chown first,
- * chown may lose the setuid bits.
+ * Compare the stripped temp file with the target.
*/
- if ((gid != -1 || uid != -1) && fchown(to_fd, uid, gid)) {
- serrno = errno;
- (void)unlink(to_name);
- errx(1, "%s: chown/chgrp: %s", to_name, strerror(serrno));
+ if (docompare && dostrip && target) {
+ temp_fd = to_fd;
+
+ /* Re-open to_fd using the real target name. */
+ if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)
+ err(EX_OSERR, "%s", to_name);
+
+ if (fstat(temp_fd, &temp_sb)) {
+ serrno = errno;
+ (void)unlink(tempfile);
+ errno = serrno;
+ err(EX_OSERR, "%s", tempfile);
+ }
+
+ if (compare(temp_fd, tempfile, (size_t)temp_sb.st_size, to_fd,
+ to_name, (size_t)to_sb.st_size) == 0) {
+ /*
+ * If target has more than one link we need to
+ * replace it in order to snap the extra links.
+ * Need to preserve target file times, though.
+ */
+ if (to_sb.st_nlink != 1) {
+ utb.actime = to_sb.st_atime;
+ utb.modtime = to_sb.st_mtime;
+ (void)utime(tempfile, &utb);
+ } else {
+ files_match = 1;
+ (void)unlink(tempfile);
+ }
+ (void) close(temp_fd);
+ }
}
- if (fchmod(to_fd, mode)) {
+
+ /*
+ * Move the new file into place if doing a safe copy
+ * and the files are different (or just not compared).
+ */
+ if (tempcopy && !files_match) {
+ /* Try to turn off the immutable bits. */
+ if (to_sb.st_flags & NOCHANGEBITS)
+ (void)chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS);
+ if (dobackup) {
+ if (snprintf(backup, MAXPATHLEN, "%s%s", to_name,
+ suffix) != strlen(to_name) + strlen(suffix)) {
+ unlink(tempfile);
+ errx(EX_OSERR, "%s: backup filename too long",
+ to_name);
+ }
+ if (verbose)
+ (void)printf("install: %s -> %s\n", to_name, backup);
+ if (rename(to_name, backup) < 0) {
+ serrno = errno;
+ unlink(tempfile);
+ errno = serrno;
+ err(EX_OSERR, "rename: %s to %s", to_name,
+ backup);
+ }
+ }
+ if (verbose)
+ (void)printf("install: %s -> %s\n", from_name, to_name);
+ if (rename(tempfile, to_name) < 0) {
+ serrno = errno;
+ unlink(tempfile);
+ errno = serrno;
+ err(EX_OSERR, "rename: %s to %s",
+ tempfile, to_name);
+ }
+
+ /* Re-open to_fd so we aren't hosed by the rename(2). */
+ (void) close(to_fd);
+ if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)
+ err(EX_OSERR, "%s", to_name);
+ }
+
+ /*
+ * Preserve the timestamp of the source file if necessary.
+ */
+ if (dopreserve && !files_match && !devnull) {
+ utb.actime = from_sb.st_atime;
+ utb.modtime = from_sb.st_mtime;
+ (void)utime(to_name, &utb);
+ }
+
+ if (fstat(to_fd, &to_sb) == -1) {
serrno = errno;
(void)unlink(to_name);
- errx(1, "%s: chmod: %s", to_name, strerror(serrno));
+ errno = serrno;
+ err(EX_OSERR, "%s", to_name);
}
/*
- * If provided a set of flags, set them, otherwise, preserve the
- * flags, except for the dump flag.
+ * Set owner, group, mode for target; do the chown first,
+ * chown may lose the setuid bits.
*/
- if (fchflags(to_fd,
- flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) {
- if (errno != EOPNOTSUPP || (from_sb.st_flags & ~UF_NODUMP) != 0)
- warn("%s: chflags", to_name);
+ if ((gid != (gid_t)-1 && gid != to_sb.st_gid) ||
+ (uid != (uid_t)-1 && uid != to_sb.st_uid) ||
+ (mode != to_sb.st_mode)) {
+ /* Try to turn off the immutable bits. */
+ if (to_sb.st_flags & NOCHANGEBITS)
+ (void)fchflags(to_fd, to_sb.st_flags & ~NOCHANGEBITS);
}
+ if ((gid != (gid_t)-1 && gid != to_sb.st_gid) ||
+ (uid != (uid_t)-1 && uid != to_sb.st_uid))
+ if (fchown(to_fd, uid, gid) == -1) {
+ serrno = errno;
+ (void)unlink(to_name);
+ errno = serrno;
+ err(EX_OSERR,"%s: chown/chgrp", to_name);
+ }
+
+ if (mode != to_sb.st_mode)
+ if (fchmod(to_fd, mode)) {
+ serrno = errno;
+ (void)unlink(to_name);
+ errno = serrno;
+ err(EX_OSERR, "%s: chmod", to_name);
+ }
+
/*
- * Preserve the date of the source file.
+ * If provided a set of flags, set them, otherwise, preserve the
+ * flags, except for the dump flag.
+ * NFS does not support flags. Ignore EOPNOTSUPP flags if we're just
+ * trying to turn off UF_NODUMP. If we're trying to set real flags,
+ * then warn if the the fs doesn't support it, otherwise fail.
*/
- if (dopreserve) {
- struct timeval tv[2];
-
- TIMESPEC_TO_TIMEVAL(&tv[0], &from_sb.st_atimespec);
- TIMESPEC_TO_TIMEVAL(&tv[1], &from_sb.st_mtimespec);
-#ifndef __APPLE__
- if (futimes(to_fd, tv) == -1)
- warn("%s: futimes", to_name);
-#else
- if (utimes(to_name, tv) == -1)
- warn("%s: utimes", to_name);
-#endif
+ if (!devnull && fchflags(to_fd,
+ flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) {
+ if (flags & SETFLAGS) {
+ if (errno == EOPNOTSUPP)
+ warn("%s: chflags", to_name);
+ else {
+ serrno = errno;
+ (void)unlink(to_name);
+ errno = serrno;
+ err(EX_OSERR, "%s: chflags", to_name);
+ }
+ }
}
(void)close(to_fd);
- if (!docopy && !devnull && unlink(from_name))
- err(1, "%s", from_name);
+ if (!devnull)
+ (void)close(from_fd);
+}
+
+/*
+ * compare --
+ * compare two files; non-zero means files differ
+ */
+int
+compare(int from_fd, const char *from_name, size_t from_len,
+ int to_fd, const char *to_name, size_t to_len)
+{
+ char *p, *q;
+ int rv;
+ int done_compare;
+
+ rv = 0;
+ if (from_len != to_len)
+ return 1;
+
+ if (from_len <= 8 * 1024 * 1024) {
+ done_compare = 0;
+ if (trymmap(from_fd) && trymmap(to_fd)) {
+ p = mmap(NULL, from_len, PROT_READ, MAP_SHARED, from_fd, (off_t)0);
+ if (p == (char *)MAP_FAILED)
+ goto out;
+ q = mmap(NULL, from_len, PROT_READ, MAP_SHARED, to_fd, (off_t)0);
+ if (q == (char *)MAP_FAILED) {
+ munmap(p, from_len);
+ goto out;
+ }
+
+ rv = memcmp(p, q, from_len);
+ munmap(p, from_len);
+ munmap(q, from_len);
+ done_compare = 1;
+ }
+ out:
+ if (!done_compare) {
+ char buf1[MAXBSIZE];
+ char buf2[MAXBSIZE];
+ int n1, n2;
+
+ rv = 0;
+ lseek(from_fd, 0, SEEK_SET);
+ lseek(to_fd, 0, SEEK_SET);
+ while (rv == 0) {
+ n1 = read(from_fd, buf1, sizeof(buf1));
+ if (n1 == 0)
+ break; /* EOF */
+ else if (n1 > 0) {
+ n2 = read(to_fd, buf2, n1);
+ if (n2 == n1)
+ rv = memcmp(buf1, buf2, n1);
+ else
+ rv = 1; /* out of sync */
+ } else
+ rv = 1; /* read failure */
+ }
+ lseek(from_fd, 0, SEEK_SET);
+ lseek(to_fd, 0, SEEK_SET);
+ }
+ } else
+ rv = 1; /* don't bother in this case */
+
+ return rv;
+}
+
+/*
+ * create_tempfile --
+ * create a temporary file based on path and open it
+ */
+int
+create_tempfile(path, temp, tsize)
+ char *path;
+ char *temp;
+ size_t tsize;
+{
+ char *p;
+
+ (void)strncpy(temp, path, tsize);
+ temp[tsize - 1] = '\0';
+ if ((p = strrchr(temp, '/')) != NULL)
+ p++;
+ else
+ p = temp;
+ (void)strncpy(p, "INS@XXXX", &temp[tsize - 1] - p);
+ temp[tsize - 1] = '\0';
+ return (mkstemp(temp));
+}
+
+/*
+ * create_newfile --
+ * create a new file, overwriting an existing one if necessary
+ */
+int
+create_newfile(path, target, sbp)
+ char *path;
+ int target;
+ struct stat *sbp;
+{
+ char backup[MAXPATHLEN];
+
+ if (target) {
+ /*
+ * Unlink now... avoid ETXTBSY errors later. Try to turn
+ * off the append/immutable bits -- if we fail, go ahead,
+ * it might work.
+ */
+ if (sbp->st_flags & NOCHANGEBITS)
+ (void)chflags(path, sbp->st_flags & ~NOCHANGEBITS);
+
+ if (dobackup) {
+ if (snprintf(backup, MAXPATHLEN, "%s%s",
+ path, suffix) != strlen(path) + strlen(suffix))
+ errx(EX_OSERR, "%s: backup filename too long",
+ path);
+ (void)snprintf(backup, MAXPATHLEN, "%s%s",
+ path, suffix);
+ if (verbose)
+ (void)printf("install: %s -> %s\n",
+ path, backup);
+ if (rename(path, backup) < 0)
+ err(EX_OSERR, "rename: %s to %s", path, backup);
+ } else
+ (void)unlink(path);
+ }
+
+ return (open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR));
}
/*
*/
void
copy(from_fd, from_name, to_fd, to_name, size)
- int from_fd, to_fd;
+ register int from_fd, to_fd;
char *from_name, *to_name;
off_t size;
{
- int nr, nw;
+ register int nr, nw;
int serrno;
- char *p;
- char buf[MAXBSIZE];
+ char *p, buf[MAXBSIZE];
+ int done_copy;
+
+ /* Rewind file descriptors. */
+ if (lseek(from_fd, (off_t)0, SEEK_SET) == (off_t)-1)
+ err(EX_OSERR, "lseek: %s", from_name);
+ if (lseek(to_fd, (off_t)0, SEEK_SET) == (off_t)-1)
+ err(EX_OSERR, "lseek: %s", to_name);
/*
- * There's no reason to do anything other than close the file
- * now if it's empty, so let's not bother.
+ * Mmap and write if less than 8M (the limit is so we don't totally
+ * trash memory on big files. This is really a minor hack, but it
+ * wins some CPU back.
*/
- if (size > 0) {
- /*
- * Mmap and write if less than 8M (the limit is so we don't totally
- * trash memory on big files). This is really a minor hack, but it
- * wins some CPU back.
- */
- if (size <= 8 * 1048576) {
- if ((p = mmap(NULL, (size_t)size, PROT_READ,
- MAP_FILE|MAP_SHARED, from_fd, (off_t)0)) == (char *)-1)
- err(1, "%s", from_name);
- if (write(to_fd, p, size) != size)
- err(1, "%s", to_name);
- } else {
- while ((nr = read(from_fd, buf, sizeof(buf))) > 0)
- if ((nw = write(to_fd, buf, nr)) != nr) {
- serrno = errno;
- (void)unlink(to_name);
- errx(1, "%s: %s",
- to_name, strerror(nw > 0 ? EIO : serrno));
- }
- if (nr != 0) {
+ done_copy = 0;
+ if (size <= 8 * 1048576 && trymmap(from_fd) &&
+ (p = mmap(NULL, (size_t)size, PROT_READ, MAP_SHARED,
+ from_fd, (off_t)0)) != (char *)MAP_FAILED) {
+ if ((nw = write(to_fd, p, size)) != size) {
+ serrno = errno;
+ (void)unlink(to_name);
+ errno = nw > 0 ? EIO : serrno;
+ err(EX_OSERR, "%s", to_name);
+ }
+ done_copy = 1;
+ }
+ if (!done_copy) {
+ while ((nr = read(from_fd, buf, sizeof(buf))) > 0)
+ if ((nw = write(to_fd, buf, nr)) != nr) {
serrno = errno;
(void)unlink(to_name);
- errx(1, "%s: %s", from_name, strerror(serrno));
+ errno = nw > 0 ? EIO : serrno;
+ err(EX_OSERR, "%s", to_name);
}
+ if (nr != 0) {
+ serrno = errno;
+ (void)unlink(to_name);
+ errno = serrno;
+ err(EX_OSERR, "%s", from_name);
}
}
}
char *to_name;
{
int serrno, status;
- char *stripprog;
- switch (vfork()) {
+ switch (fork()) {
case -1:
serrno = errno;
(void)unlink(to_name);
- errx(1, "vfork: %s", strerror(serrno));
+ errno = serrno;
+ err(EX_TEMPFAIL, "fork");
case 0:
- stripprog = getenv("STRIP");
- if (stripprog == NULL)
- stripprog = _PATH_STRIP;
-
- if (stripArgs) {
- /* build up a command line and let /bin/sh parse the arguments */
- char* cmd = (char*)malloc(sizeof(char)*
- (3+strlen(stripprog)+
- strlen(stripArgs)+
- strlen(to_name)));
-
- sprintf(cmd, "%s %s %s", stripprog, stripArgs, to_name);
-
- execl(_PATH_BSHELL, "sh", "-c", cmd, NULL);
- } else
- execl(stripprog, "strip", to_name, NULL);
-
- warn("%s", stripprog);
- _exit(1);
+ execlp("strip", "strip", to_name, NULL);
+ err(EX_OSERR, "exec(strip)");
default:
- if (wait(&status) == -1 || status)
+ if (wait(&status) == -1 || status) {
(void)unlink(to_name);
+ exit(EX_SOFTWARE);
+ /* NOTREACHED */
+ }
}
}
*/
void
install_dir(path)
- char *path;
+ char *path;
{
- char *p;
- struct stat sb;
- int ch;
-
- for (p = path;; ++p)
- if (!*p || (p != path && *p == '/')) {
- ch = *p;
- *p = '\0';
- if (stat(path, &sb)) {
- if (errno != ENOENT || mkdir(path, 0777) < 0) {
- err(1, "%s", path);
+ register char *p;
+ struct stat sb;
+ int ch;
+
+ for (p = path;; ++p)
+ if (!*p || (p != path && *p == '/')) {
+ ch = *p;
+ *p = '\0';
+ if (stat(path, &sb)) {
+ if (errno != ENOENT || mkdir(path, 0755) < 0) {
+ err(EX_OSERR, "mkdir %s", path);
/* NOTREACHED */
- }
- }
- if (!(*p = ch))
+ } else if (verbose)
+ (void)printf("install: mkdir %s\n",
+ path);
+ } else if (!S_ISDIR(sb.st_mode))
+ errx(EX_OSERR, "%s exists but is not a directory", path);
+ if (!(*p = ch))
break;
- }
+ }
- if (((gid != -1 || uid != -1) && chown(path, uid, gid)) ||
- chmod(path, mode)) {
- warn("%s", path);
- }
+ if ((gid != (gid_t)-1 || uid != (uid_t)-1) && chown(path, uid, gid))
+ warn("chown %u:%u %s", uid, gid, path);
+ if (chmod(path, mode))
+ warn("chmod %o %s", mode, path);
}
/*
usage()
{
(void)fprintf(stderr, "\
-usage: install [-cps] [-f flags] [-m mode] [-o owner] [-g group] [-l linkflags] [-S stripflags] file1 file2\n\
- install [-cps] [-f flags] [-m mode] [-o owner] [-g group] [-l linkflags] [-S stripflags] file1 ... fileN directory\n\
- install -pd [-m mode] [-o owner] [-g group] directory ...\n");
- exit(1);
+usage: install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n\
+ [-o owner] file1 file2\n\
+ install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n\
+ [-o owner] file1 ... fileN directory\n\
+ install -d [-v] [-g group] [-m mode] [-o owner] directory ...\n");
+ exit(EX_USAGE);
+ /* NOTREACHED */
+}
+
+/*
+ * trymmap --
+ * return true (1) if mmap should be tried, false (0) if not.
+ */
+int
+trymmap(fd)
+ int fd;
+{
+/*
+ * The ifdef is for bootstrapping - f_fstypename doesn't exist in
+ * pre-Lite2-merge systems.
+ */
+#ifdef MFSNAMELEN
+ struct statfs stfs;
+
+ if (nommap || fstatfs(fd, &stfs) != 0)
+ return (0);
+ if (strcmp(stfs.f_fstypename, "ufs") == 0 ||
+ strcmp(stfs.f_fstypename, "cd9660") == 0)
+ return (1);
+#endif
+ return (0);
}
done = (*slash == '\0');
*slash = '\0';
- if (stat(path, &sb)) {
- if (errno != ENOENT
- || mkdir(path, done ? mode : dir_mode)) {
- warn("%s", path);
- return (-1);
- }
+ if (!mkdir(path, done ? mode : dir_mode)) {
/*
* The mkdir() and umask() calls both honor only the low
* nine bits, so if you try to set a mode including the
warn("%s", path);
return (-1);
}
- } else if (!S_ISDIR(sb.st_mode)) {
- warnx("%s: %s", path, strerror(ENOTDIR));
- return (-1);
+ } else {
+ if (stat(path, &sb)) {
+ warnx("%s: %s", path, strerror(errno));
+ return (-1);
+ } else if (!S_ISDIR(sb.st_mode)) {
+ warnx("%s: %s", path, strerror(ENOTDIR));
+ return (-1);
+ }
}
-
*slash = '/';
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
int main __P((int, char *[]));
static void usage __P((void));
HFILES = extern.h mtree.h
-CFILES = compare.c create.c misc.c mtree.c spec.c verify.c
+CFILES = compare.c create.c excludes.c misc.c mtree.c spec.c verify.c
OTHERSRCS = Makefile Makefile.preamble Makefile.postamble mtree.8
-/* $NetBSD: compare.c,v 1.15 1998/08/27 18:03:45 ross Exp $ */
-
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)compare.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: compare.c,v 1.15 1998/08/27 18:03:45 ross Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/usr.sbin/mtree/compare.c,v 1.15.2.3 2001/01/12 19:17:18 phk Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
+#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <fts.h>
-#include <errno.h>
+#ifdef MD5
+#include <md5.h>
+#endif
+#ifdef SHA1
+#include <sha.h>
+#endif
+#ifdef RMD160
+#include <ripemd.h>
+#endif
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include "mtree.h"
#include "extern.h"
-extern int tflag, uflag;
+extern int uflag;
+extern int lineno;
static char *ftype __P((u_int));
#define INDENTNAMELEN 8
#define LABEL \
if (!label++) { \
- len = printf("%s: ", RP(p)); \
- if (len > INDENTNAMELEN) { \
- tab = "\t"; \
- (void)printf("\n"); \
- } else { \
- tab = ""; \
- (void)printf("%*s", INDENTNAMELEN - (int)len, ""); \
- } \
+ len = printf("%s changed\n", RP(p)); \
+ tab = "\t"; \
}
int
compare(name, s, p)
char *name;
- NODE *s;
- FTSENT *p;
+ register NODE *s;
+ register FTSENT *p;
{
- u_int32_t len, val;
+ extern int uflag;
+ u_long len, val;
int fd, label;
- char *cp, *tab;
+ char *cp, *tab = "";
+ char *fflags;
- tab = NULL;
label = 0;
switch(s->type) {
case F_BLOCK:
case F_SOCK:
if (!S_ISSOCK(p->fts_statp->st_mode)) {
typeerr: LABEL;
- (void)printf("\ttype (%s, %s)\n",
+ (void)printf("\ttype expected %s found %s\n",
ftype(s->type), inotype(p->fts_statp->st_mode));
+ return (label);
}
break;
}
/* Set the uid/gid first, then set the mode. */
if (s->flags & (F_UID | F_UNAME) && s->st_uid != p->fts_statp->st_uid) {
LABEL;
- (void)printf("%suser (%u, %u",
- tab, s->st_uid, p->fts_statp->st_uid);
+ (void)printf("%suser expected %lu found %lu",
+ tab, (u_long)s->st_uid, (u_long)p->fts_statp->st_uid);
if (uflag)
if (chown(p->fts_accpath, s->st_uid, -1))
- (void)printf(", not modified: %s)\n",
+ (void)printf(" not modified: %s\n",
strerror(errno));
else
- (void)printf(", modified)\n");
+ (void)printf(" modified\n");
else
- (void)printf(")\n");
+ (void)printf("\n");
tab = "\t";
}
if (s->flags & (F_GID | F_GNAME) && s->st_gid != p->fts_statp->st_gid) {
LABEL;
- (void)printf("%sgid (%u, %u",
- tab, s->st_gid, p->fts_statp->st_gid);
+ (void)printf("%sgid expected %lu found %lu",
+ tab, (u_long)s->st_gid, (u_long)p->fts_statp->st_gid);
if (uflag)
if (chown(p->fts_accpath, -1, s->st_gid))
- (void)printf(", not modified: %s)\n",
+ (void)printf(" not modified: %s\n",
strerror(errno));
else
- (void)printf(", modified)\n");
+ (void)printf(" modified\n");
else
- (void)printf(")\n");
+ (void)printf("\n");
tab = "\t";
}
if (s->flags & F_MODE &&
+ !S_ISLNK(p->fts_statp->st_mode) &&
s->st_mode != (p->fts_statp->st_mode & MBITS)) {
LABEL;
- (void)printf("%spermissions (%#o, %#o",
+ (void)printf("%spermissions expected %#o found %#o",
tab, s->st_mode, p->fts_statp->st_mode & MBITS);
if (uflag)
if (chmod(p->fts_accpath, s->st_mode))
- (void)printf(", not modified: %s)\n",
+ (void)printf(" not modified: %s\n",
strerror(errno));
else
- (void)printf(", modified)\n");
+ (void)printf(" modified\n");
else
- (void)printf(")\n");
+ (void)printf("\n");
tab = "\t";
}
if (s->flags & F_NLINK && s->type != F_DIR &&
s->st_nlink != p->fts_statp->st_nlink) {
LABEL;
- (void)printf("%slink count (%u, %u)\n",
+ (void)printf("%slink_count expected %u found %u\n",
tab, s->st_nlink, p->fts_statp->st_nlink);
tab = "\t";
}
- if (s->flags & F_SIZE && s->st_size != p->fts_statp->st_size) {
+ if (s->flags & F_SIZE && s->st_size != p->fts_statp->st_size &&
+ !S_ISDIR(p->fts_statp->st_mode)) {
LABEL;
- (void)printf("%ssize (%qd, %qd)\n",
- tab, (long long)s->st_size,
- (long long)p->fts_statp->st_size);
+ (void)printf("%ssize expected %qd found %qd\n",
+ tab, s->st_size, p->fts_statp->st_size);
tab = "\t";
}
/*
* XXX
- * Since utimes(2) only takes a timeval, there's no point in
- * comparing the low bits of the timespec nanosecond field. This
- * will only result in mismatches that we can never fix.
- *
- * Doesn't display microsecond differences.
+ * Catches nano-second differences, but doesn't display them.
*/
- if (s->flags & F_TIME) {
- struct timeval tv[2];
-
- TIMESPEC_TO_TIMEVAL(&tv[0], &s->st_mtimespec);
- TIMESPEC_TO_TIMEVAL(&tv[1], &p->fts_statp->st_mtimespec);
- if (tv[0].tv_sec != tv[1].tv_sec ||
- tv[0].tv_usec != tv[1].tv_usec) {
- LABEL;
- (void)printf("%smodification time (%.24s, ",
- tab, ctime(&s->st_mtimespec.tv_sec));
- (void)printf("%.24s",
- ctime(&p->fts_statp->st_mtimespec.tv_sec));
- if (tflag) {
- tv[1] = tv[0];
- if (utimes(p->fts_accpath, tv))
- (void)printf(", not modified: %s)\n",
- strerror(errno));
- else
- (void)printf(", modified)\n");
- } else
- (void)printf(")\n");
- tab = "\t";
- }
+ if ((s->flags & F_TIME) &&
+ ((s->st_mtimespec.tv_sec != p->fts_statp->st_mtimespec.tv_sec) ||
+ (s->st_mtimespec.tv_nsec != p->fts_statp->st_mtimespec.tv_nsec))) {
+ LABEL;
+ (void)printf("%smodification time expected %.24s ",
+ tab, ctime(&s->st_mtimespec.tv_sec));
+ (void)printf("found %.24s\n",
+ ctime(&p->fts_statp->st_mtimespec.tv_sec));
+ tab = "\t";
}
if (s->flags & F_CKSUM) {
if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0) {
(void)close(fd);
if (s->cksum != val) {
LABEL;
- (void)printf("%scksum (%lu, %lu)\n",
- tab, s->cksum, (unsigned long)val);
+ (void)printf("%scksum expected %lu found %lu\n",
+ tab, s->cksum, val);
}
tab = "\t";
}
}
- if (s->flags & F_SLINK && strcmp(cp = rlink(name), s->slink)) {
+ /*
+ * XXX
+ * since chflags(2) will reset file times, the utimes() above
+ * may have been useless! oh well, we'd rather have correct
+ * flags, rather than times?
+ */
+ if ((s->flags & F_FLAGS) && s->st_flags != p->fts_statp->st_flags) {
+ LABEL;
+ fflags = flags_to_string(s->st_flags);
+ (void)printf("%sflags expected \"%s\"", tab, fflags);
+ free(fflags);
+
+ fflags = flags_to_string(p->fts_statp->st_flags);
+ (void)printf(" found \"%s\"", fflags);
+ free(fflags);
+
+ if (uflag)
+ if (chflags(p->fts_accpath, s->st_flags))
+ (void)printf(" not modified: %s\n",
+ strerror(errno));
+ else
+ (void)printf(" modified\n");
+ else
+ (void)printf("\n");
+ tab = "\t";
+ }
+#ifdef MD5
+ if (s->flags & F_MD5) {
+ char *new_digest, buf[33];
+
+ new_digest = MD5File(p->fts_accpath, buf);
+ if (!new_digest) {
+ LABEL;
+ printf("%sMD5: %s: %s\n", tab, p->fts_accpath,
+ strerror(errno));
+ tab = "\t";
+ } else if (strcmp(new_digest, s->md5digest)) {
+ LABEL;
+ printf("%sMD5 expected %s found %s\n", tab, s->md5digest,
+ new_digest);
+ tab = "\t";
+ }
+ }
+#endif /* MD5 */
+#ifdef SHA1
+ if (s->flags & F_SHA1) {
+ char *new_digest, buf[41];
+
+ new_digest = SHA1_File(p->fts_accpath, buf);
+ if (!new_digest) {
+ LABEL;
+ printf("%sSHA-1: %s: %s\n", tab, p->fts_accpath,
+ strerror(errno));
+ tab = "\t";
+ } else if (strcmp(new_digest, s->sha1digest)) {
+ LABEL;
+ printf("%sSHA-1 expected %s found %s\n",
+ tab, s->sha1digest, new_digest);
+ tab = "\t";
+ }
+ }
+#endif /* SHA1 */
+#ifdef RMD160
+ if (s->flags & F_RMD160) {
+ char *new_digest, buf[41];
+
+ new_digest = RIPEMD160_File(p->fts_accpath, buf);
+ if (!new_digest) {
+ LABEL;
+ printf("%sRIPEMD160: %s: %s\n", tab,
+ p->fts_accpath, strerror(errno));
+ tab = "\t";
+ } else if (strcmp(new_digest, s->rmd160digest)) {
+ LABEL;
+ printf("%sRIPEMD160 expected %s found %s\n",
+ tab, s->rmd160digest, new_digest);
+ tab = "\t";
+ }
+ }
+#endif /* RMD160 */
+
+ if (s->flags & F_SLINK &&
+ strcmp(cp = rlink(p->fts_accpath), s->slink)) {
LABEL;
- (void)printf("%slink ref (%s, %s)\n", tab, cp, s->slink);
+ (void)printf("%slink_ref expected %s found %s\n",
+ tab, cp, s->slink);
}
return (label);
}
char *name;
{
static char lbuf[MAXPATHLEN];
- int len;
+ register int len;
- if ((len = readlink(name, lbuf, sizeof(lbuf))) == -1)
- mtree_err("%s: %s", name, strerror(errno));
+ if ((len = readlink(name, lbuf, sizeof(lbuf) - 1)) == -1)
+ err(1, "line %d: %s", lineno, name);
lbuf[len] = '\0';
return (lbuf);
}
-/* $NetBSD: create.c,v 1.16 1998/08/30 03:20:09 nathanw Exp $ */
-
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)create.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: create.c,v 1.16 1998/08/30 03:20:09 nathanw Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/usr.sbin/mtree/create.c,v 1.18.2.3 2001/01/12 19:17:18 phk Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fts.h>
#include <grp.h>
+#ifdef MD5
+#include <md5.h>
+#endif
+#ifdef SHA1
+#include <sha.h>
+#endif
+#ifdef RMD160
+#include <ripemd.h>
+#endif
#include <pwd.h>
#include <stdio.h>
-#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <vis.h>
#include "mtree.h"
#include "extern.h"
#define INDENTNAMELEN 15
#define MAXLINELEN 80
-extern int crc_total, ftsoptions;
-extern int dflag, sflag;
-extern u_short keys;
+extern long int crc_total;
+extern int ftsoptions;
+extern int dflag, iflag, nflag, sflag;
+extern u_int keys;
extern char fullpath[MAXPATHLEN];
+extern int lineno;
static gid_t gid;
static uid_t uid;
static mode_t mode;
+static u_long flags = 0xffffffff;
static int dsort __P((const FTSENT **, const FTSENT **));
-static void output __P((int *, const char *, ...));
-static int statd __P((FTS *, FTSENT *, uid_t *, gid_t *, mode_t *));
-static void statf __P((FTSENT *));
+static void output __P((int, int *, const char *, ...));
+static int statd __P((FTS *, FTSENT *, uid_t *, gid_t *, mode_t *,
+ u_long *));
+static void statf __P((int, FTSENT *));
void
cwalk()
{
- FTS *t;
- FTSENT *p;
+ register FTS *t;
+ register FTSENT *p;
time_t clock;
- char *argv[2], host[MAXHOSTNAMELEN + 1];
+ char *argv[2], host[MAXHOSTNAMELEN];
+ int indent = 0;
(void)time(&clock);
(void)gethostname(host, sizeof(host));
- host[sizeof(host) - 1] = '\0';
(void)printf(
"#\t user: %s\n#\tmachine: %s\n#\t tree: %s\n#\t date: %s",
getlogin(), host, fullpath, ctime(&clock));
argv[0] = ".";
argv[1] = NULL;
if ((t = fts_open(argv, ftsoptions, dsort)) == NULL)
- mtree_err("fts_open: %s", strerror(errno));
- while ((p = fts_read(t)) != NULL)
+ err(1, "line %d: fts_open", lineno);
+ while ((p = fts_read(t))) {
+ if (iflag)
+ indent = p->fts_level * 4;
+ if (check_excludes(p->fts_name, p->fts_path)) {
+ fts_set(t, p, FTS_SKIP);
+ continue;
+ }
switch(p->fts_info) {
case FTS_D:
- (void)printf("\n# %s\n", p->fts_path);
- statd(t, p, &uid, &gid, &mode);
- statf(p);
+ if (!dflag)
+ (void)printf("\n");
+ if (!nflag)
+ (void)printf("# %s\n", p->fts_path);
+ statd(t, p, &uid, &gid, &mode, &flags);
+ statf(indent, p);
break;
case FTS_DP:
- if (p->fts_level > 0)
- (void)printf("# %s\n..\n\n", p->fts_path);
+ if (!nflag && (p->fts_level > 0))
+ (void)printf("%*s# %s\n", indent, "", p->fts_path);
+ (void)printf("%*s..\n", indent, "");
+ if (!dflag)
+ (void)printf("\n");
break;
case FTS_DNR:
case FTS_ERR:
case FTS_NS:
- (void)fprintf(stderr,
- "mtree: %s: %s\n", p->fts_path, strerror(errno));
+ warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
break;
default:
if (!dflag)
- statf(p);
+ statf(indent, p);
break;
-
+
}
+ }
(void)fts_close(t);
if (sflag && keys & F_CKSUM)
- (void)fprintf(stderr,
- "mtree: %s checksum: %u\n", fullpath, crc_total);
+ warnx("%s checksum: %lu", fullpath, crc_total);
}
static void
-statf(p)
+statf(indent, p)
+ int indent;
FTSENT *p;
{
struct group *gr;
struct passwd *pw;
- u_int32_t len, val;
- int fd, indent;
+ u_long len, val;
+ int fd, offset;
+ char *fflags;
+ char *escaped_name;
+
+ escaped_name = calloc(1, p->fts_namelen * 4 + 1);
+ if (escaped_name == NULL)
+ errx(1, "statf(): calloc() failed");
+ strvis(escaped_name, p->fts_name, VIS_WHITE | VIS_OCTAL);
- if (S_ISDIR(p->fts_statp->st_mode))
- indent = printf("%s", p->fts_name);
+ if (iflag || S_ISDIR(p->fts_statp->st_mode))
+ offset = printf("%*s%s", indent, "", escaped_name);
else
- indent = printf(" %s", p->fts_name);
+ offset = printf("%*s %s", indent, "", escaped_name);
+
+ free(escaped_name);
- if (indent > INDENTNAMELEN)
- indent = MAXLINELEN;
+ if (offset > (INDENTNAMELEN + indent))
+ offset = MAXLINELEN;
else
- indent += printf("%*s", INDENTNAMELEN - indent, "");
+ offset += printf("%*s", (INDENTNAMELEN + indent) - offset, "");
- if (!S_ISREG(p->fts_statp->st_mode))
- output(&indent, "type=%s", inotype(p->fts_statp->st_mode));
- if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) {
- if (keys & F_UNAME && (pw = getpwuid(p->fts_statp->st_uid)))
- output(&indent, "uname=%s", pw->pw_name);
- else /* if (keys & F_UID) */
- output(&indent, "uid=%u", p->fts_statp->st_uid);
+ if (!S_ISREG(p->fts_statp->st_mode) && !dflag)
+ output(indent, &offset, "type=%s", inotype(p->fts_statp->st_mode));
+ if (p->fts_statp->st_uid != uid) {
+ if (keys & F_UNAME) {
+ if ((pw = getpwuid(p->fts_statp->st_uid)) != NULL) {
+ output(indent, &offset, "uname=%s", pw->pw_name);
+ } else {
+ errx(1,
+ "line %d: could not get uname for uid=%u",
+ lineno, p->fts_statp->st_uid);
+ }
+ }
+ if (keys & F_UID)
+ output(indent, &offset, "uid=%u", p->fts_statp->st_uid);
}
- if (keys & (F_GID | F_GNAME) && p->fts_statp->st_gid != gid) {
- if (keys & F_GNAME && (gr = getgrgid(p->fts_statp->st_gid)))
- output(&indent, "gname=%s", gr->gr_name);
- else /* if (keys & F_GID) */
- output(&indent, "gid=%u", p->fts_statp->st_gid);
+ if (p->fts_statp->st_gid != gid) {
+ if (keys & F_GNAME) {
+ if ((gr = getgrgid(p->fts_statp->st_gid)) != NULL) {
+ output(indent, &offset, "gname=%s", gr->gr_name);
+ } else {
+ errx(1,
+ "line %d: could not get gname for gid=%u",
+ lineno, p->fts_statp->st_gid);
+ }
+ }
+ if (keys & F_GID)
+ output(indent, &offset, "gid=%u", p->fts_statp->st_gid);
}
if (keys & F_MODE && (p->fts_statp->st_mode & MBITS) != mode)
- output(&indent, "mode=%#o", p->fts_statp->st_mode & MBITS);
+ output(indent, &offset, "mode=%#o", p->fts_statp->st_mode & MBITS);
if (keys & F_NLINK && p->fts_statp->st_nlink != 1)
- output(&indent, "nlink=%u", p->fts_statp->st_nlink);
- if (keys & F_SIZE && S_ISREG(p->fts_statp->st_mode))
- output(&indent, "size=%qd", p->fts_statp->st_size);
+ output(indent, &offset, "nlink=%u", p->fts_statp->st_nlink);
+ if (keys & F_SIZE)
+ output(indent, &offset, "size=%qd", p->fts_statp->st_size);
if (keys & F_TIME)
- output(&indent, "time=%ld.%ld",
+ output(indent, &offset, "time=%ld.%ld",
p->fts_statp->st_mtimespec.tv_sec,
p->fts_statp->st_mtimespec.tv_nsec);
if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 ||
crc(fd, &val, &len))
- mtree_err("%s: %s", p->fts_accpath, strerror(errno));
+ err(1, "line %d: %s", lineno, p->fts_accpath);
(void)close(fd);
- output(&indent, "cksum=%lu", val);
+ output(indent, &offset, "cksum=%lu", val);
+ }
+#ifdef MD5
+ if (keys & F_MD5 && S_ISREG(p->fts_statp->st_mode)) {
+ char *digest, buf[33];
+
+ digest = MD5File(p->fts_accpath, buf);
+ if (!digest) {
+ err(1, "line %d: %s", lineno, p->fts_accpath);
+ } else {
+ output(indent, &offset, "md5digest=%s", digest);
+ }
}
+#endif /* MD5 */
+#ifdef SHA1
+ if (keys & F_SHA1 && S_ISREG(p->fts_statp->st_mode)) {
+ char *digest, buf[41];
+
+ digest = SHA1_File(p->fts_accpath, buf);
+ if (!digest) {
+ err(1, "line %d: %s", lineno, p->fts_accpath);
+ } else {
+ output(indent, &offset, "sha1digest=%s", digest);
+ }
+ }
+#endif /* SHA1 */
+#ifdef RMD160
+ if (keys & F_RMD160 && S_ISREG(p->fts_statp->st_mode)) {
+ char *digest, buf[41];
+
+ digest = RIPEMD160_File(p->fts_accpath, buf);
+ if (!digest) {
+ err(1, "line %d: %s", lineno, p->fts_accpath);
+ } else {
+ output(indent, &offset, "ripemd160digest=%s", digest);
+ }
+ }
+#endif /* RMD160 */
if (keys & F_SLINK &&
(p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE))
- output(&indent, "link=%s", rlink(p->fts_accpath));
+ output(indent, &offset, "link=%s", rlink(p->fts_accpath));
+ if (keys & F_FLAGS && p->fts_statp->st_flags != flags) {
+ fflags = flags_to_string(p->fts_statp->st_flags);
+ output(indent, &offset, "flags=%s", fflags);
+ free(fflags);
+ }
(void)putchar('\n');
}
#define MAXGID 5000
#define MAXUID 5000
#define MAXMODE MBITS + 1
+#define MAXFLAGS 256
+#define MAXS 16
static int
-statd(t, parent, puid, pgid, pmode)
+statd(t, parent, puid, pgid, pmode, pflags)
FTS *t;
FTSENT *parent;
uid_t *puid;
gid_t *pgid;
mode_t *pmode;
+ u_long *pflags;
{
- FTSENT *p;
- gid_t sgid;
- uid_t suid;
- mode_t smode;
+ register FTSENT *p;
+ register gid_t sgid;
+ register uid_t suid;
+ register mode_t smode;
+ register u_long sflags;
struct group *gr;
struct passwd *pw;
- gid_t savegid;
- uid_t saveuid;
- mode_t savemode;
- u_short maxgid, maxuid, maxmode, g[MAXGID], u[MAXUID], m[MAXMODE];
+ gid_t savegid = *pgid;
+ uid_t saveuid = *puid;
+ mode_t savemode = *pmode;
+ u_long saveflags = *pflags;
+ u_short maxgid, maxuid, maxmode, maxflags;
+ u_short g[MAXGID], u[MAXUID], m[MAXMODE], f[MAXFLAGS];
+ char *fflags;
+ static int first = 1;
- savegid = 0;
- saveuid = 0;
- savemode = 0;
if ((p = fts_children(t, 0)) == NULL) {
if (errno)
- mtree_err("%s: %s", RP(parent), strerror(errno));
+ err(1, "line %d: %s", lineno, RP(parent));
return (1);
}
- memset(g, 0, sizeof(g));
- memset(u, 0, sizeof(u));
- memset(m, 0, sizeof(m));
+ bzero(g, sizeof(g));
+ bzero(u, sizeof(u));
+ bzero(m, sizeof(m));
+ bzero(f, sizeof(f));
- maxuid = maxgid = maxmode = 0;
+ maxuid = maxgid = maxmode = maxflags = 0;
for (; p; p = p->fts_link) {
- smode = p->fts_statp->st_mode & MBITS;
- if (smode < MAXMODE && ++m[smode] > maxmode) {
- savemode = smode;
- maxmode = m[smode];
- }
- sgid = p->fts_statp->st_gid;
- if (sgid < MAXGID && ++g[sgid] > maxgid) {
- savegid = sgid;
- maxgid = g[sgid];
- }
- suid = p->fts_statp->st_uid;
- if (suid < MAXUID && ++u[suid] > maxuid) {
- saveuid = suid;
- maxuid = u[suid];
+ if (!dflag || (dflag && S_ISDIR(p->fts_statp->st_mode))) {
+ smode = p->fts_statp->st_mode & MBITS;
+ if (smode < MAXMODE && ++m[smode] > maxmode) {
+ savemode = smode;
+ maxmode = m[smode];
+ }
+ sgid = p->fts_statp->st_gid;
+ if (sgid < MAXGID && ++g[sgid] > maxgid) {
+ savegid = sgid;
+ maxgid = g[sgid];
+ }
+ suid = p->fts_statp->st_uid;
+ if (suid < MAXUID && ++u[suid] > maxuid) {
+ saveuid = suid;
+ maxuid = u[suid];
+ }
+
+ /*
+ * XXX
+ * note that the below will break when file flags
+ * are extended beyond the first 4 bytes of each
+ * half word of the flags
+ */
+#define FLAGS2IDX(f) ((f & 0xf) | ((f >> 12) & 0xf0))
+ sflags = p->fts_statp->st_flags;
+ if (FLAGS2IDX(sflags) < MAXFLAGS &&
+ ++f[FLAGS2IDX(sflags)] > maxflags) {
+ saveflags = sflags;
+ maxflags = f[FLAGS2IDX(sflags)];
+ }
}
}
- (void)printf("/set type=file");
- if (keys & F_GID)
- (void)printf(" gid=%u", savegid);
- if (keys & F_GNAME) {
- if ((gr = getgrgid(savegid)) != NULL)
- (void)printf(" gname=%s", gr->gr_name);
- else
- (void)printf(" gid=%u", savegid);
- }
- if (keys & F_UNAME) {
- if ((pw = getpwuid(saveuid)) != NULL)
- (void)printf(" uname=%s", pw->pw_name);
+ /*
+ * If the /set record is the same as the last one we do not need to output
+ * a new one. So first we check to see if anything changed. Note that we
+ * always output a /set record for the first directory.
+ */
+ if ((((keys & F_UNAME) | (keys & F_UID)) && (*puid != saveuid)) ||
+ (((keys & F_GNAME) | (keys & F_GID)) && (*pgid != savegid)) ||
+ ((keys & F_MODE) && (*pmode != savemode)) ||
+ ((keys & F_FLAGS) && (*pflags != saveflags)) ||
+ (first)) {
+ first = 0;
+ if (dflag)
+ (void)printf("/set type=dir");
else
- (void)printf(" uid=%u", saveuid);
+ (void)printf("/set type=file");
+ if (keys & F_UNAME) {
+ if ((pw = getpwuid(saveuid)) != NULL)
+ (void)printf(" uname=%s", pw->pw_name);
+ else
+ errx(1,
+ "line %d: could not get uname for uid=%u",
+ lineno, saveuid);
+ }
+ if (keys & F_UID)
+ (void)printf(" uid=%lu", (u_long)saveuid);
+ if (keys & F_GNAME) {
+ if ((gr = getgrgid(savegid)) != NULL)
+ (void)printf(" gname=%s", gr->gr_name);
+ else
+ errx(1,
+ "line %d: could not get gname for gid=%u",
+ lineno, savegid);
+ }
+ if (keys & F_GID)
+ (void)printf(" gid=%lu", (u_long)savegid);
+ if (keys & F_MODE)
+ (void)printf(" mode=%#o", savemode);
+ if (keys & F_NLINK)
+ (void)printf(" nlink=1");
+ if (keys & F_FLAGS) {
+ fflags = flags_to_string(saveflags);
+ (void)printf(" flags=%s", fflags);
+ free(fflags);
+ }
+ (void)printf("\n");
+ *puid = saveuid;
+ *pgid = savegid;
+ *pmode = savemode;
+ *pflags = saveflags;
}
- if (keys & F_UID)
- (void)printf(" uid=%u", saveuid);
- if (keys & F_MODE)
- (void)printf(" mode=%#o", savemode);
- if (keys & F_NLINK)
- (void)printf(" nlink=1");
- (void)printf("\n");
- *puid = saveuid;
- *pgid = savegid;
- *pmode = savemode;
return (0);
}
void
#if __STDC__
-output(int *offset, const char *fmt, ...)
+output(int indent, int *offset, const char *fmt, ...)
#else
-output(offset, fmt, va_alist)
+output(indent, offset, fmt, va_alist)
+ int indent;
int *offset;
char *fmt;
va_dcl
va_end(ap);
if (*offset + strlen(buf) > MAXLINELEN - 3) {
- (void)printf(" \\\n%*s", INDENTNAMELEN, "");
- *offset = INDENTNAMELEN;
+ (void)printf(" \\\n%*s", INDENTNAMELEN + indent, "");
+ *offset = INDENTNAMELEN + indent;
}
*offset += printf(" %s", buf) + 1;
}
--- /dev/null
+/*
+ * Copyright 2000 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+static const char rcsid[] =
+ "$FreeBSD: src/usr.sbin/mtree/excludes.c,v 1.1.2.4 2001/01/12 19:17:18 phk Exp $";
+
+#include <sys/types.h>
+#include <sys/time.h> /* XXX for mtree.h */
+#include <sys/queue.h>
+
+#include <err.h>
+#include <fnmatch.h>
+#include <fts.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mtree.h" /* XXX for extern.h */
+#include "extern.h"
+
+/*
+ * We're assuming that there won't be a whole lot of excludes,
+ * so it's OK to use a stupid algorithm.
+ */
+struct exclude {
+ LIST_ENTRY(exclude) link;
+ const char *glob;
+ int pathname;
+};
+static LIST_HEAD(, exclude) excludes;
+
+void
+init_excludes(void)
+{
+ LIST_INIT(&excludes);
+}
+
+void
+read_excludes_file(const char *name)
+{
+ FILE *fp;
+ char *line, *str;
+ struct exclude *e;
+ size_t len;
+
+ fp = fopen(name, "r");
+ if (fp == 0)
+ err(1, "%s", name);
+
+ while ((line = fgetln(fp, &len)) != 0) {
+ if (line[len - 1] == '\n')
+ len--;
+ if (len == 0)
+ continue;
+
+ str = malloc(len + 1);
+ e = malloc(sizeof *e);
+ if (str == 0 || e == 0)
+ errx(1, "memory allocation error");
+ e->glob = str;
+ memcpy(str, line, len);
+ str[len] = '\0';
+ if (strchr(str, '/'))
+ e->pathname = 1;
+ else
+ e->pathname = 0;
+ LIST_INSERT_HEAD(&excludes, e, link);
+ }
+ fclose(fp);
+}
+
+int
+check_excludes(const char *fname, const char *path)
+{
+ struct exclude *e;
+
+ /* fnmatch(3) has a funny return value convention... */
+#define MATCH(g, n) (fnmatch((g), (n), FNM_PATHNAME) == 0)
+
+ LIST_FOREACH(e, &excludes, link) {
+ if (e->pathname && MATCH(e->glob, path)
+ || MATCH(e->glob, fname))
+ return 1;
+ }
+ return 0;
+}
-/* $NetBSD: extern.h,v 1.3 1995/03/07 21:12:07 cgd Exp $ */
-
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*
* @(#)extern.h 8.1 (Berkeley) 6/6/93
+ * $FreeBSD: src/usr.sbin/mtree/extern.h,v 1.3.2.2 2000/06/28 02:33:17 joe Exp $
*/
-#include "mtree.h"
-
-#ifdef __APPLE__
-#include <fts.h>
-#endif
-
int compare __P((char *, NODE *, FTSENT *));
-int crc __P((int, u_int32_t *, u_int32_t *));
+int crc __P((int, u_long *, u_long *));
void cwalk __P((void));
-void mtree_err __P((const char *, ...));
+char *flags_to_string __P((u_long));
+
char *inotype __P((u_int));
u_int parsekey __P((char *, int *));
char *rlink __P((char *));
NODE *spec __P((void));
int verify __P((void));
+
+int check_excludes __P((const char *, const char *));
+void init_excludes __P((void));
+void read_excludes_file __P((const char *));
-/* $NetBSD: misc.c,v 1.5 1997/10/17 11:46:40 lukem Exp $ */
-
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * @(#)misc.c 8.1 (Berkeley) 6/6/93
*/
-#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: misc.c,v 1.5 1997/10/17 11:46:40 lukem Exp $");
-#endif /* not lint */
+#if 0
+static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/6/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD: src/usr.sbin/mtree/misc.c,v 1.8.2.1 2000/06/28 02:33:17 joe Exp $";
+#endif /*not lint */
#include <sys/types.h>
#include <sys/stat.h>
+#include <err.h>
#include <fts.h>
#include <stdio.h>
+#include <unistd.h>
#include "mtree.h"
#include "extern.h"
/* NB: the following table must be sorted lexically. */
static KEY keylist[] = {
{"cksum", F_CKSUM, NEEDVALUE},
+ {"flags", F_FLAGS, NEEDVALUE},
{"gid", F_GID, NEEDVALUE},
{"gname", F_GNAME, NEEDVALUE},
{"ignore", F_IGN, 0},
{"link", F_SLINK, NEEDVALUE},
+#ifdef MD5
+ {"md5digest", F_MD5, NEEDVALUE},
+#endif
{"mode", F_MODE, NEEDVALUE},
{"nlink", F_NLINK, NEEDVALUE},
- {"optional", F_OPT, 0},
+ {"nochange", F_NOCHANGE, 0},
+#ifdef RMD160
+ {"ripemd160digest", F_RMD160, NEEDVALUE},
+#endif
+#ifdef SHA1
+ {"sha1digest", F_SHA1, NEEDVALUE},
+#endif
{"size", F_SIZE, NEEDVALUE},
{"time", F_TIME, NEEDVALUE},
{"type", F_TYPE, NEEDVALUE},
{"uid", F_UID, NEEDVALUE},
- {"uname", F_UNAME, NEEDVALUE}
+ {"uname", F_UNAME, NEEDVALUE},
};
-int keycompare __P((const void *, const void *));
-
u_int
parsekey(name, needvaluep)
char *name;
int *needvaluep;
{
KEY *k, tmp;
+ int keycompare __P((const void *, const void *));
tmp.name = name;
k = (KEY *)bsearch(&tmp, keylist, sizeof(keylist) / sizeof(KEY),
sizeof(KEY), keycompare);
if (k == NULL)
- mtree_err("unknown keyword %s", name);
+ errx(1, "line %d: unknown keyword %s", lineno, name);
if (needvaluep)
*needvaluep = k->flags & NEEDVALUE ? 1 : 0;
return (strcmp(((KEY *)a)->name, ((KEY *)b)->name));
}
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-void
-#if __STDC__
-mtree_err(const char *fmt, ...)
-#else
-mtree_err(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
+char *
+flags_to_string(fflags)
+ u_long fflags;
{
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- (void)fprintf(stderr, "mtree: ");
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- (void)fprintf(stderr, "\n");
- if (lineno)
- (void)fprintf(stderr,
- "mtree: failed at line %d of the specification\n", lineno);
- exit(1);
- /* NOTREACHED */
+ char *string;
+
+ string = fflagstostr(fflags);
+ if (string != NULL && *string == '\0') {
+ free(string);
+ string = strdup("none");
+ }
+ if (string == NULL)
+ err(1, NULL);
+
+ return string;
}
-.\" $NetBSD: mtree.8,v 1.7 1997/10/17 11:46:46 lukem Exp $
-.\"
.\" Copyright (c) 1989, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)mtree.8 8.2 (Berkeley) 12/11/93
+.\" From: @(#)mtree.8 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD: src/usr.sbin/mtree/mtree.8,v 1.16.2.9 2001/08/16 15:56:08 ru Exp $
.\"
-.Dd December 11, 1993
+.Dd February 26, 1999
.Dt MTREE 8
.Os
.Sh NAME
.Nd map a directory hierarchy
.Sh SYNOPSIS
.Nm
-.Op Fl cderux
+.Op Fl LPUcdeinqrux
+.Bk -words
.Op Fl f Ar spec
+.Ek
+.Bk -words
.Op Fl K Ar keywords
+.Ek
+.Bk -words
.Op Fl k Ar keywords
+.Ek
+.Bk -words
.Op Fl p Ar path
+.Ek
+.Bk -words
.Op Fl s Ar seed
+.Ek
+.Bk -words
+.Op Fl X Ar exclude-list
+.Ek
.Sh DESCRIPTION
The utility
.Nm
compares the file hierarchy rooted in the current directory against a
specification read from the standard input.
Messages are written to the standard output for any files whose
-characteristics do not match the specification, or which are
+characteristics do not match the specifications, or which are
missing from either the file hierarchy or the specification.
.Pp
The options are as follows:
.Bl -tag -width flag
+.It Fl L
+Follow all symbolic links in the file hierarchy.
+.It Fl P
+Don't follow symbolic links in the file hierarchy, instead consider
+the symbolic link itself in any comparisons. This is the default.
+.It Fl U
+Modify the owner, group and permissions of existing files to match
+the specification and create any missing directories or symbolic links.
+User, group and permissions must all be specified for missing directories
+to be created.
+Corrected mismatches are not considered errors.
.It Fl c
Print a specification for the file hierarchy to the standard output.
.It Fl d
.It Fl e
Don't complain about files that are in the file hierarchy, but not in the
specification.
-.It Fl f
+.It Fl i
+Indent the output 4 spaces each time a directory level is descended when
+create a specification with the
+.Fl c
+option.
+This does not affect either the /set statements or the comment before each
+directory.
+It does however affect the comment before the close of each directory.
+.It Fl n
+Do not emit pathname comments when creating a specification. Normally
+a comment is emitted before each directory and before the close of that
+directory when using the
+.Fl c
+option.
+.It Fl q
+Quiet mode. Do not complain when a
+.Dq missing
+directory cannot be created because it is already exists.
+This occurs when the directory is a symbolic link.
+.It Fl r
+Remove any files in the file hierarchy that are not described in the
+specification.
+.It Fl u
+Same as
+.Fl U
+except a status of 2 is returned if the file hierarchy did not match
+the specification.
+.It Fl x
+Don't descend below mount points in the file hierarchy.
+.It Fl f Ar file
Read the specification from
.Ar file ,
instead of from the standard input.
-.It Fl K
-Add the specified (whitespace or comma separated) keywords to the current
-set of keywords.
-.It Fl k
+.It Fl K Ar keywords
+Add the specified (whitespace or comma separated)
+.Ar keywords
+to the current set of keywords.
+.It Fl k Ar keywords
Use the ``type'' keyword plus the specified (whitespace or comma separated)
-keywords instead of the current set of keywords.
-.It Fl p
+.Ar keywords
+instead of the current set of keywords.
+.It Fl p Ar path
Use the file hierarchy rooted in
.Ar path ,
instead of the current directory.
-.It Fl r
-Remove any files in the file hierarchy that are not described in the
-specification.
-.It Fl s
+.It Fl s Ar seed
Display a single checksum to the standard error output that represents all
of the files for which the keyword
.Cm cksum
was specified.
The checksum is seeded with the specified value.
-.It Fl U
-Modify the owner, group, and permissions of existing files to match
-the specification and create any missing directories.
-User, group, and permissions must all be specified for missing directories
-to be created.
-Exit with a status of 0 on success, 1 if any error occurred;
-a mismatch is not considered to be an error if it was corrected.
-.It Fl u
-Same as
-.Fl U
-except a status of 2 is returned if the file hierarchy did not match
-the specification.
-.It Fl x
-Don't descend below mount points in the file hierarchy.
+.It Fl X Ar exclude-list
+The specified file contains
+.Xr fnmatch 3
+patterns matching files to be excluded from
+the specification, one to a line.
+If the pattern contains a
+.Ql \&/
+character, it will be matched against entire pathnames (relative to
+the starting directory); otherwise,
+it will be matched against basenames only. No comments are allowed in
+the
+.Ar exclude-list
+file.
.El
.Pp
Specifications are mostly composed of ``keywords'', i.e. strings that
the
.Xr cksum 1
utility.
+.It Cm flags
+The file flags as a symbolic name. See
+.Xr chflags 1
+for information on these names. If no flags are to be set the string
+.Dq none
+may be used to override the current default.
.It Cm ignore
Ignore any file hierarchy below this file.
.It Cm gid
The file group as a numeric value.
.It Cm gname
The file group as a symbolic name.
-.It Cm link
-The file the symbolic link is expected to reference.
+.\" .It Cm md5digest
+.\" The MD5 message digest of the file.
+.\" .It Cm sha1digest
+.\" The
+.\" .Tn FIPS
+.\" 160-1
+.\" .Pq Dq Tn SHA-1
+.\" message digest of the file.
+.\" .It Cm ripemd160digest
+.\" The
+.\" .Tn RIPEMD160
+.\" message digest of the file.
.It Cm mode
The current file's permissions as a numeric (octal) or symbolic
value.
.It Cm nlink
The number of hard links the file is expected to have.
-.It Cm optional
-The file is optional; don't complain about the file if it's
-not in the file hierarchy.
+.It Cm nochange
+Make sure this file or directory exists but otherwise ignore all attributes.
.It Cm uid
The file owner as a numeric value.
.It Cm uname
The file owner as a symbolic name.
.It Cm size
The size, in bytes, of the file.
+.It Cm link
+The file the symbolic link is expected to reference.
.It Cm time
The last modification time of the file.
.It Cm type
The type of the file; may be set to any one of the following:
-.sp
+.Pp
.Bl -tag -width Cm -compact
.It Cm block
block special device
.El
.Pp
The default set of keywords are
+.Cm flags ,
.Cm gid ,
-.Cm link ,
.Cm mode ,
.Cm nlink ,
.Cm size ,
+.Cm link ,
.Cm time ,
and
.Cm uid .
for in that directory hierarchy.
Which brings us to the last type of line in a specification: a line
containing only the string
-.Dq Nm \&..
+.Dq Pa ..\&
causes the current directory
path to ascend one level.
.Pp
.Nm
utility exits with a status of 0 on success, 1 if any error occurred,
and 2 if the file hierarchy did not match the specification.
-.Sh EXAMPLES
-To detect system binaries that have been ``trojan horsed'', it is recommended
-that
-.Nm
-be run on the file systems, and a copy of the results stored on a different
-machine, or, at least, in encrypted form.
-The seed for the
-.Fl s
-option should not be an obvious value and the final checksum should not be
-stored on-line under any circumstances!
-Then, periodically,
-.Nm
-should be run against the on-line specifications and the final checksum
-compared with the previous value.
-While it is possible for the bad guys to change the on-line specifications
-to conform to their modified binaries, it shouldn't be possible for them
-to make it produce the same final checksum value.
-If the final checksum value changes, the off-line copies of the specification
-can be used to detect which of the binaries have actually been modified.
-.Pp
-The
-.Fl d
-and
-.Fl u
-options can be used in combination to create directory hierarchies
-for distributions and other such things.
+A status of 2 is converted to a status of 0 if the
+.Fl U
+option is used.
+.\" .Sh EXAMPLES
+.\" To detect system binaries that have been ``trojan horsed'', it is recommended
+.\" that
+.\" .Nm
+.\" .Fl K
+.\" .Cm sha1digest
+.\" be run on the file systems, and a copy of the results stored on a different
+.\" machine, or, at least, in encrypted form.
+.\" The output file itself should be digested using the
+.\" .Xr md5 1
+.\" utility.
+.\" Then, periodically,
+.\" .Nm
+.\" and
+.\" .Xr md5 1
+.\" should be run against the on-line specifications.
+.\" While it is possible for the bad guys to change the on-line specifications
+.\" to conform to their modified binaries, it is believed to be
+.\" impractical for them to create a modified specification which has
+.\" the same MD5 digest as the original.
+.\" .Pp
+.\" The
+.\" .Fl d
+.\" and
+.\" .Fl u
+.\" options can be used in combination to create directory hierarchies
+.\" for distributions and other such things; the files in
+.\" .Pa /etc/mtree
+.\" were used to create almost all directories in this
+.\" .Fx
+.\" distribution.
.Sh FILES
.Bl -tag -width /etc/mtree -compact
.It Pa /etc/mtree
system specification directory
.El
+.Sh DIAGNOSTICS
+.Ex -std
.Sh SEE ALSO
-.Xr chmod 1 ,
+.Xr chflags 1 ,
.Xr chgrp 1 ,
+.Xr chmod 1 ,
.Xr cksum 1 ,
+.\" .Xr md5 1 ,
.Xr stat 2 ,
.Xr fts 3 ,
+.\" .Xr md5 3 ,
.Xr chown 8
.Sh HISTORY
The
.Nm
utility appeared in
.Bx 4.3 Reno .
+The
+.Tn MD5
+digest capability was added in
+.Fx 2.1 ,
+in response to the widespread use of programs which can spoof
+.Xr cksum 1 .
+The
+.Tn SHA-1
+and
+.Tn RIPEMD160
+digests were added in
+.Fx 4.0 ,
+as new attacks have demonstrated weaknesses in
+.Tn MD5 .
+Support for file flags was added in
+.Fx 4.0 ,
+and mostly comes from
+.Nx .
-/* $NetBSD: mtree.c,v 1.9 1997/10/17 11:46:51 lukem Exp $ */
-
/*-
* Copyright (c) 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1989, 1990, 1993\n\
- The Regents of the University of California. All rights reserved.\n");
+static const char copyright[] =
+"@(#) Copyright (c) 1989, 1990, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)mtree.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: mtree.c,v 1.9 1997/10/17 11:46:51 lukem Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/usr.sbin/mtree/mtree.c,v 1.8.2.2 2001/01/12 19:17:18 phk Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
+#include <err.h>
#include <errno.h>
-#include <unistd.h>
-#include <stdio.h>
#include <fts.h>
+#include <stdio.h>
+#include <unistd.h>
#include "mtree.h"
#include "extern.h"
-extern int crc_total;
+extern long int crc_total;
int ftsoptions = FTS_PHYSICAL;
-int cflag, dflag, eflag, rflag, sflag, tflag, uflag, Uflag;
-u_short keys;
+int cflag, dflag, eflag, iflag, nflag, qflag, rflag, sflag, uflag, Uflag;
+u_int keys;
char fullpath[MAXPATHLEN];
- int main __P((int, char **));
-static void usage __P((void));
+static void usage __P((void));
int
main(argc, argv)
dir = NULL;
keys = KEYDEFAULT;
- while ((ch = getopt(argc, argv, "cdef:K:k:p:rs:tUux")) != -1)
+ init_excludes();
+
+ while ((ch = getopt(argc, argv, "cdef:iK:k:LnPp:qrs:UuxX:")) != -1)
switch((char)ch) {
case 'c':
cflag = 1;
break;
case 'f':
if (!(freopen(optarg, "r", stdin)))
- mtree_err("%s: %s", optarg, strerror(errno));
+ err(1, "%s", optarg);
+ break;
+ case 'i':
+ iflag = 1;
break;
case 'K':
while ((p = strsep(&optarg, " \t,")) != NULL)
if (*p != '\0')
keys |= parsekey(p, NULL);
break;
+ case 'L':
+ ftsoptions &= ~FTS_PHYSICAL;
+ ftsoptions |= FTS_LOGICAL;
+ break;
+ case 'n':
+ nflag = 1;
+ break;
+ case 'P':
+ ftsoptions &= ~FTS_LOGICAL;
+ ftsoptions |= FTS_PHYSICAL;
+ break;
case 'p':
dir = optarg;
break;
+ case 'q':
+ qflag = 1;
+ break;
case 'r':
rflag = 1;
break;
sflag = 1;
crc_total = ~strtol(optarg, &p, 0);
if (*p)
- mtree_err("illegal seed value -- %s", optarg);
- break;
- case 't':
- tflag = 1;
- break;
+ errx(1, "illegal seed value -- %s", optarg);
case 'U':
- Uflag = uflag = 1;
+ Uflag = 1;
+ uflag = 1;
break;
case 'u':
uflag = 1;
case 'x':
ftsoptions |= FTS_XDEV;
break;
+ case 'X':
+ read_excludes_file(optarg);
+ break;
case '?':
default:
usage();
usage();
if (dir && chdir(dir))
- mtree_err("%s: %s", dir, strerror(errno));
+ err(1, "%s", dir);
if ((cflag || sflag) && !getwd(fullpath))
- mtree_err("%s", fullpath);
+ errx(1, "%s", fullpath);
if (cflag) {
cwalk();
usage()
{
(void)fprintf(stderr,
-"usage: mtree [-cderUux] [-f spec] [-K key] [-k key] [-p path] [-s seed]\n");
+"usage: mtree [-LPUcdeinqrux] [-f spec] [-K key] [-k key] [-p path] [-s seed]\n"
+"\t[-X excludes]\n");
exit(1);
}
-/* $NetBSD: mtree.h,v 1.7 1995/03/07 21:26:27 cgd Exp $ */
-
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*
* @(#)mtree.h 8.1 (Berkeley) 6/6/93
+ * $FreeBSD: src/usr.sbin/mtree/mtree.h,v 1.5 1999/12/09 20:38:35 joe Exp $
*/
-#ifndef _MTREE_H_
-#define _MTREE_H_
-
#include <string.h>
#include <stdlib.h>
-#include <sys/time.h>
#define KEYDEFAULT \
- (F_GID | F_MODE | F_NLINK | F_SIZE | F_SLINK | F_TIME | F_UID)
+ (F_GID | F_MODE | F_NLINK | F_SIZE | F_SLINK | F_TIME | F_UID | F_FLAGS)
#define MISMATCHEXIT 2
off_t st_size; /* size */
struct timespec st_mtimespec; /* last modification time */
u_long cksum; /* check sum */
+ char *md5digest; /* MD5 digest */
+ char *sha1digest; /* SHA-1 digest */
+ char *rmd160digest; /* RIPEMD160 digest */
char *slink; /* symbolic link reference */
uid_t st_uid; /* uid */
gid_t st_gid; /* gid */
#define MBITS (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
mode_t st_mode; /* mode */
+ u_long st_flags; /* flags */
nlink_t st_nlink; /* link count */
#define F_CKSUM 0x0001 /* check sum */
#define F_MAGIC 0x0020 /* name has magic chars */
#define F_MODE 0x0040 /* mode */
#define F_NLINK 0x0080 /* number of links */
-#define F_OPT 0x0100 /* existence optional */
-#define F_SIZE 0x0200 /* size */
-#define F_SLINK 0x0400 /* link count */
-#define F_TIME 0x0800 /* modification time */
-#define F_TYPE 0x1000 /* file type */
-#define F_UID 0x2000 /* uid */
-#define F_UNAME 0x4000 /* user name */
-#define F_VISIT 0x8000 /* file visited */
- u_short flags; /* items set */
+#define F_SIZE 0x0100 /* size */
+#define F_SLINK 0x0200 /* link count */
+#define F_TIME 0x0400 /* modification time */
+#define F_TYPE 0x0800 /* file type */
+#define F_UID 0x1000 /* uid */
+#define F_UNAME 0x2000 /* user name */
+#define F_VISIT 0x4000 /* file visited */
+#define F_MD5 0x8000 /* MD5 digest */
+#define F_NOCHANGE 0x10000 /* If owner/mode "wrong", do */
+ /* not change */
+#define F_SHA1 0x20000 /* SHA-1 digest */
+#define F_RMD160 0x40000 /* RIPEMD160 digest */
+#define F_FLAGS 0x80000 /* file flags */
+ u_int flags; /* items set */
#define F_BLOCK 0x001 /* block special */
#define F_CHAR 0x002 /* char special */
#define RP(p) \
((p)->fts_path[0] == '.' && (p)->fts_path[1] == '/' ? \
(p)->fts_path + 2 : (p)->fts_path)
-
-#endif /* _MTREE_H_ */
-/* $NetBSD: spec.c,v 1.12 1998/09/23 19:46:00 itohy Exp $ */
-
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
-static char sccsid[] = "@(#)spec.c 8.2 (Berkeley) 4/28/95";
-#else
-__RCSID("$NetBSD: spec.c,v 1.12 1998/09/23 19:46:00 itohy Exp $");
+static char sccsid[] = "@(#)spec.c 8.1 (Berkeley) 6/6/93";
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/usr.sbin/mtree/spec.c,v 1.13.2.1 2000/06/28 02:33:17 joe Exp $";
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
+#include <err.h>
#include <errno.h>
#include <fts.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
-#include <string.h>
#include <unistd.h>
-
+#include <vis.h>
#include "mtree.h"
#include "extern.h"
NODE *
spec()
{
- NODE *centry, *last;
- char *p;
+ register NODE *centry, *last;
+ register char *p;
NODE ginfo, *root;
int c_cur, c_next;
char buf[2048];
- root = NULL;
- centry = last = NULL;
- memset(&ginfo, 0, sizeof(ginfo));
+ centry = last = root = NULL;
+ bzero(&ginfo, sizeof(ginfo));
c_cur = c_next = 0;
for (lineno = 1; fgets(buf, sizeof(buf), stdin);
++lineno, c_cur = c_next, c_next = 0) {
continue;
/* Find end of line. */
- if ((p = strchr(buf, '\n')) == NULL)
- mtree_err("line %d too long", lineno);
+ if ((p = index(buf, '\n')) == NULL)
+ errx(1, "line %d too long", lineno);
/* See if next line is continuation line. */
if (p[-1] == '\\') {
set(p, centry);
continue;
}
-
+
/* Grab file name, "$", "set", or "unset". */
if ((p = strtok(p, "\n\t ")) == NULL)
- mtree_err("missing field");
+ errx(1, "line %d: missing field", lineno);
if (p[0] == '/')
switch(p[1]) {
continue;
}
- if (strchr(p, '/'))
- mtree_err("slash character in file name");
+ if (index(p, '/'))
+ errx(1, "line %d: slash character in file name",
+ lineno);
if (!strcmp(p, "..")) {
/* Don't go up, if haven't gone down. */
last->flags |= F_DONE;
continue;
-noparent: mtree_err("no parent node");
+noparent: errx(1, "line %d: no parent node", lineno);
}
if ((centry = calloc(1, sizeof(NODE) + strlen(p))) == NULL)
- mtree_err("%s", strerror(errno));
+ errx(1, "calloc");
*centry = ginfo;
- (void)strcpy(centry->name, p);
#define MAGIC "?*["
if (strpbrk(p, MAGIC))
centry->flags |= F_MAGIC;
+ if (strunvis(centry->name, p) == -1) {
+ warnx("filename %s is ill-encoded and literally used",
+ p);
+ strcpy(centry->name, p);
+ }
set(NULL, centry);
if (!root) {
char *t;
NODE *ip;
{
- int type;
- char *kw, *val;
+ register int type;
+ char *kw, *val = NULL;
struct group *gr;
struct passwd *pw;
mode_t *m;
int value;
char *ep;
- val = NULL;
- for (; (kw = strtok(t, "= \t\n")) != NULL; t = NULL) {
+ for (; (kw = strtok(t, "= \t\n")); t = NULL) {
ip->flags |= type = parsekey(kw, &value);
if (value && (val = strtok(NULL, " \t\n")) == NULL)
- mtree_err("missing value");
+ errx(1, "line %d: missing value", lineno);
switch(type) {
case F_CKSUM:
ip->cksum = strtoul(val, &ep, 10);
if (*ep)
- mtree_err("invalid checksum %s", val);
+ errx(1, "line %d: invalid checksum %s",
+ lineno, val);
+ break;
+ case F_MD5:
+ ip->md5digest = strdup(val);
+ if(!ip->md5digest) {
+ errx(1, "strdup");
+ }
break;
+ case F_SHA1:
+ ip->sha1digest = strdup(val);
+ if(!ip->sha1digest) {
+ errx(1, "strdup");
+ }
+ break;
+ case F_RMD160:
+ ip->rmd160digest = strdup(val);
+ if(!ip->rmd160digest) {
+ errx(1, "strdup");
+ }
+ break;
+ case F_FLAGS:
+ if (strcmp("none", val) == 0)
+ ip->st_flags = 0;
+ else if (strtofflags(&val, &ip->st_flags, NULL) != 0)
+ errx(1, "line %d: invalid flag %s",lineno, val);
+ break;
case F_GID:
- ip->st_gid = (gid_t)strtoul(val, &ep, 10);
+ ip->st_gid = strtoul(val, &ep, 10);
if (*ep)
- mtree_err("invalid gid %s", val);
+ errx(1, "line %d: invalid gid %s", lineno, val);
break;
case F_GNAME:
if ((gr = getgrnam(val)) == NULL)
- mtree_err("unknown group %s", val);
+ errx(1, "line %d: unknown group %s", lineno, val);
ip->st_gid = gr->gr_gid;
break;
case F_IGN:
break;
case F_MODE:
if ((m = setmode(val)) == NULL)
- mtree_err("invalid file mode %s", val);
+ errx(1, "line %d: invalid file mode %s",
+ lineno, val);
ip->st_mode = getmode(m, 0);
free(m);
break;
case F_NLINK:
- ip->st_nlink = (nlink_t)strtoul(val, &ep, 10);
+ ip->st_nlink = strtoul(val, &ep, 10);
if (*ep)
- mtree_err("invalid link count %s", val);
+ errx(1, "line %d: invalid link count %s",
+ lineno, val);
break;
case F_SIZE:
- ip->st_size = (off_t)strtoq(val, &ep, 10);
+ ip->st_size = strtoq(val, &ep, 10);
if (*ep)
- mtree_err("invalid size %s", val);
+ errx(1, "line %d: invalid size %s",
+ lineno, val);
break;
case F_SLINK:
if ((ip->slink = strdup(val)) == NULL)
- mtree_err("%s", strerror(errno));
+ errx(1, "strdup");
break;
case F_TIME:
- ip->st_mtimespec.tv_sec =
- (time_t)strtoul(val, &ep, 10);
+ ip->st_mtimespec.tv_sec = strtoul(val, &ep, 10);
if (*ep != '.')
- mtree_err("invalid time %s", val);
+ errx(1, "line %d: invalid time %s",
+ lineno, val);
val = ep + 1;
- ip->st_mtimespec.tv_nsec = strtol(val, &ep, 10);
+ ip->st_mtimespec.tv_nsec = strtoul(val, &ep, 10);
if (*ep)
- mtree_err("invalid time %s", val);
+ errx(1, "line %d: invalid time %s",
+ lineno, val);
break;
case F_TYPE:
switch(*val) {
ip->type = F_SOCK;
break;
default:
- mtree_err("unknown file type %s", val);
+ errx(1, "line %d: unknown file type %s",
+ lineno, val);
}
break;
case F_UID:
- ip->st_uid = (uid_t)strtoul(val, &ep, 10);
+ ip->st_uid = strtoul(val, &ep, 10);
if (*ep)
- mtree_err("invalid uid %s", val);
+ errx(1, "line %d: invalid uid %s", lineno, val);
break;
case F_UNAME:
if ((pw = getpwnam(val)) == NULL)
- mtree_err("unknown user %s", val);
+ errx(1, "line %d: unknown user %s", lineno, val);
ip->st_uid = pw->pw_uid;
break;
}
static void
unset(t, ip)
char *t;
- NODE *ip;
+ register NODE *ip;
{
- char *p;
+ register char *p;
- while ((p = strtok(t, "\n\t ")) != NULL)
+ while ((p = strtok(t, "\n\t ")))
ip->flags &= ~parsekey(p, NULL);
}
-/* $NetBSD: verify.c,v 1.14 1998/08/27 18:03:45 ross Exp $ */
-
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)verify.c 8.1 (Berkeley) 6/6/93";
-#else
-__RCSID("$NetBSD: verify.c,v 1.14 1998/08/27 18:03:45 ross Exp $");
#endif
+static const char rcsid[] =
+ "$FreeBSD: src/usr.sbin/mtree/verify.c,v 1.10.2.2 2001/01/12 19:17:18 phk Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
+#include <err.h>
+#include <errno.h>
#include <fts.h>
#include <fnmatch.h>
-#include <unistd.h>
-#include <errno.h>
#include <stdio.h>
+#include <unistd.h>
#include "mtree.h"
#include "extern.h"
-extern int crc_total, ftsoptions;
-extern int dflag, eflag, rflag, sflag, uflag;
+extern long int crc_total;
+extern int ftsoptions;
+extern int dflag, eflag, qflag, rflag, sflag, uflag;
extern char fullpath[MAXPATHLEN];
+extern int lineno;
static NODE *root;
static char path[MAXPATHLEN];
static int
vwalk()
{
- FTS *t;
- FTSENT *p;
- NODE *ep, *level;
- int ftsdepth, specdepth, rval;
+ register FTS *t;
+ register FTSENT *p;
+ register NODE *ep, *level;
+ int specdepth, rval;
char *argv[2];
argv[0] = ".";
argv[1] = NULL;
if ((t = fts_open(argv, ftsoptions, NULL)) == NULL)
- mtree_err("fts_open: %s", strerror(errno));
+ err(1, "line %d: fts_open", lineno);
level = root;
- ftsdepth = specdepth = rval = 0;
- while ((p = fts_read(t)) != NULL) {
+ specdepth = rval = 0;
+ while ((p = fts_read(t))) {
+ if (check_excludes(p->fts_name, p->fts_path)) {
+ fts_set(t, p, FTS_SKIP);
+ continue;
+ }
switch(p->fts_info) {
case FTS_D:
- ++ftsdepth;
+ case FTS_SL:
break;
case FTS_DP:
- --ftsdepth;
- if (specdepth > ftsdepth) {
+ if (specdepth > p->fts_level) {
for (level = level->parent; level->prev;
- level = level->prev);
+ level = level->prev);
--specdepth;
}
continue;
case FTS_DNR:
case FTS_ERR:
case FTS_NS:
- (void)fprintf(stderr, "mtree: %s: %s\n",
- RP(p), strerror(errno));
+ warnx("%s: %s", RP(p), strerror(p->fts_errno));
continue;
default:
if (dflag)
continue;
}
+ if (specdepth != p->fts_level)
+ goto extra;
for (ep = level; ep; ep = ep->next)
if ((ep->flags & F_MAGIC &&
!fnmatch(ep->name, p->fts_name, FNM_PATHNAME)) ||
!strcmp(ep->name, p->fts_name)) {
ep->flags |= F_VISIT;
- if (compare(ep->name, ep, p))
+ if ((ep->flags & F_NOCHANGE) == 0 &&
+ compare(ep->name, ep, p))
rval = MISMATCHEXIT;
- if (!(ep->flags & F_IGN) &&
- ep->child && ep->type == F_DIR &&
+ if (ep->flags & F_IGN)
+ (void)fts_set(t, p, FTS_SKIP);
+ else if (ep->child && ep->type == F_DIR &&
p->fts_info == FTS_D) {
level = ep->child;
++specdepth;
- } else
- (void)fts_set(t, p, FTS_SKIP);
+ }
break;
}
if (ep)
continue;
+extra:
if (!eflag) {
- (void)printf("extra: %s", RP(p));
+ (void)printf("%s extra", RP(p));
if (rflag) {
- if (unlink(p->fts_accpath)) {
+ if ((S_ISDIR(p->fts_statp->st_mode)
+ ? rmdir : unlink)(p->fts_accpath)) {
(void)printf(", not removed: %s",
strerror(errno));
} else
}
(void)fts_close(t);
if (sflag)
- (void)fprintf(stderr,
- "mtree: %s checksum: %u\n", fullpath, crc_total);
+ warnx("%s checksum: %lu", fullpath, crc_total);
return (rval);
}
static void
miss(p, tail)
- NODE *p;
- char *tail;
+ register NODE *p;
+ register char *tail;
{
- int create;
- char *tp;
+ register int create;
+ register char *tp;
+ const char *type;
for (; p; p = p->next) {
- if (p->flags & F_OPT && !(p->flags & F_VISIT))
- continue;
if (p->type != F_DIR && (dflag || p->flags & F_VISIT))
continue;
(void)strcpy(tail, p->name);
- if (!(p->flags & F_VISIT))
- (void)printf("missing: %s", path);
- if (p->type != F_DIR) {
+ if (!(p->flags & F_VISIT)) {
+ /* Don't print missing message if file exists as a
+ symbolic link and the -q flag is set. */
+ struct stat statbuf;
+
+ if (qflag && stat(path, &statbuf) == 0)
+ p->flags |= F_VISIT;
+ else
+ (void)printf("%s missing", path);
+ }
+ if (p->type != F_DIR && p->type != F_LINK) {
putchar('\n');
continue;
}
create = 0;
+ if (p->type == F_LINK)
+ type = "symlink";
+ else
+ type = "directory";
if (!(p->flags & F_VISIT) && uflag) {
if (!(p->flags & (F_UID | F_UNAME)))
- (void)printf(" (not created: user not specified)");
+ (void)printf(" (%s not created: user not specified)", type);
else if (!(p->flags & (F_GID | F_GNAME)))
- (void)printf(" (not created: group not specified)");
- else if (!(p->flags & F_MODE))
- (void)printf(" (not created: mode not specified)");
+ (void)printf(" (%s not created: group not specified)", type);
+ else if (p->type == F_LINK) {
+ if (symlink(p->slink, path))
+ (void)printf(" (symlink not created: %s)\n",
+ strerror(errno));
+ else
+ (void)printf(" (created)\n");
+#if 0 /* lchown() does not exist on Darwin. */
+ if (lchown(path, p->st_uid, p->st_gid))
+ (void)printf("%s: user/group not modified: %s\n",
+ path, strerror(errno));
+#endif
+ continue;
+ } else if (!(p->flags & F_MODE))
+ (void)printf(" (directory not created: mode not specified)");
else if (mkdir(path, S_IRWXU))
- (void)printf(" (not created: %s)",
+ (void)printf(" (directory not created: %s)",
strerror(errno));
else {
create = 1;
if (chown(path, p->st_uid, p->st_gid)) {
(void)printf("%s: user/group/mode not modified: %s\n",
path, strerror(errno));
+ (void)printf("%s: warning: file mode %snot set\n", path,
+ (p->flags & F_FLAGS) ? "and file flags " : "");
continue;
}
if (chmod(path, p->st_mode))
(void)printf("%s: permissions not set: %s\n",
path, strerror(errno));
+ if ((p->flags & F_FLAGS) && p->st_flags &&
+ chflags(path, p->st_flags))
+ (void)printf("%s: file flags not set: %s\n",
+ path, strerror(errno));
}
}
+vpath stat_flags.c ../ls
+CFILES += stat_flags.c
include $(CoreOSMakefiles)/ProjectBuilder/Makefile.Preamble.Common
-.\" $NetBSD: rm.1,v 1.9 1997/10/20 08:53:14 enami Exp $
-.\"
.\" Copyright (c) 1990, 1993, 1994
.\" The Regents of the University of California. All rights reserved.
.\"
.\" SUCH DAMAGE.
.\"
.\" @(#)rm.1 8.5 (Berkeley) 12/5/94
+.\" $FreeBSD: src/bin/rm/rm.1,v 1.23 2001/07/15 07:49:05 dd Exp $
.\"
-.Dd December 5, 1994
+.Dd January 28, 1999
.Dt RM 1
.Os
.Sh NAME
-.Nm rm
+.Nm rm ,
+.Nm unlink
.Nd remove directory entries
.Sh SYNOPSIS
.Nm
-.Op Fl f | Fl i
-.Op Fl dPRrW
-.Ar file ...
+.Op Fl dfiPRrvW
+.Ar
+.Nm unlink
+.Ar file
.Sh DESCRIPTION
The
.Nm
output) for confirmation.
.Pp
The options are as follows:
-.Bl -tag -width flag
+.Bl -tag -width Fl
.It Fl d
Attempt to remove directories as well as other types of files.
.It Fl f
The
.Fl f
option overrides any previous
-.Fl i
+.Fl i
options.
.It Fl i
Request confirmation before attempting to remove each file, regardless of
The
.Fl i
option overrides any previous
-.Fl f
+.Fl f
options.
.It Fl P
Overwrite regular files before deleting them.
then 0x00, and then 0xff again, before they are deleted.
.It Fl R
Attempt to remove the file hierarchy rooted in each file argument.
-The
+The
.Fl R
option implies the
.Fl d
option.
If the
.Fl i
-option is specified, the user is prompted for confirmation before
+option is specified, the user is prompted for confirmation before
each directory's contents are processed (as well as before the attempt
is made to remove the directory).
If the user does not respond affirmatively, the file hierarchy rooted in
.It Fl r
Equivalent to
.Fl R .
+.It Fl v
+Be verbose when deleting files, showing them as they are removed.
.It Fl W
-Attempts to undelete the named files.
+Attempt to undelete the named files.
Currently, this option can only be used to recover
files covered by whiteouts.
.El
.Nm
utility removes symbolic links, not the files referenced by the links.
.Pp
-It is an error to attempt to remove the files ``.'' and ``..''.
+It is an error to attempt to remove the files
+.Dq .\&
+or
+.Dq .. .
+.Pp
+When the utility is called as
+.Nm unlink ,
+only one argument,
+which must not be a directory,
+may be supplied.
+No options may be supplied in this simple mode of operation,
+which performs an
+.Xr unlink 2
+operation on the passed argument.
.Pp
The
.Nm
If an error occurs,
.Nm
exits with a value >0.
+.Sh NOTE
+The
+.Nm
+command uses
+.Xr getopt 3
+to parse its arguments, which allows it to accept
+the
+.Sq Li --
+option which will cause it to stop processing flag options at that
+point. This will allow the removal of file names that begin
+with a dash
+.Pq Sq - .
+For example:
+.Dl rm -- -filename
+The same behavior can be obtained by using an absolute or relative
+path reference. For example:
+.Dl rm /home/user/-filename
+.Dl rm ./-filename
.Sh SEE ALSO
.Xr rmdir 1 ,
.Xr undelete 2 ,
.Xr unlink 2 ,
.Xr fts 3 ,
+.Xr getopt 3 ,
.Xr symlink 7
.Sh BUGS
The
.Fl f
option only masks attempts to remove non-existent files instead of
masking a large variety of errors.
+The
+.Fl v
+option is non-standard and its use in scripts is not recommended.
.Pp
Also, historical
.Bx
.Sh STANDARDS
The
.Nm
-utility is expected to be
+command is almost
.St -p1003.2
-compatible.
+compatible, except that
+.Tn POSIX
+requires
+.Nm
+to act like
+.Xr rmdir 1
+when the
+.Ar file
+specified is a directory. This implementation requires the
+.Fl d
+option if such behavior is desired. This follows the historical
+behavior of
+.Nm
+with respect to directories.
+.Pp
+The simplified
+.Nm unlink
+command conforms to
+.St -susv2 .
+.Sh HISTORY
+A
+.Nm
+command appeared in
+.At v1 .
-/* $NetBSD: rm.c,v 1.24 1998/07/28 11:41:51 mycroft Exp $ */
-
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1990, 1993, 1994\n\
- The Regents of the University of California. All rights reserved.\n");
+static const char copyright[] =
+"@(#) Copyright (c) 1990, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
-static char sccsid[] = "@(#)rm.c 8.8 (Berkeley) 4/27/95";
+static char sccsid[] = "@(#)rm.c 8.5 (Berkeley) 4/18/94";
#else
-__RCSID("$NetBSD: rm.c,v 1.24 1998/07/28 11:41:51 mycroft Exp $");
+static const char rcsid[] =
+ "$FreeBSD: src/bin/rm/rm.c,v 1.33 2001/06/13 15:01:25 ru Exp $";
#endif
#endif /* not lint */
-#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/mount.h>
-#include <locale.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sysexits.h>
#include <unistd.h>
-#include <pwd.h>
-#include <grp.h>
-int dflag, eval, fflag, iflag, Pflag, Wflag, stdin_ok;
+int dflag, eval, fflag, iflag, Pflag, vflag, Wflag, stdin_ok;
+uid_t uid;
int check __P((char *, char *, struct stat *));
void checkdot __P((char **));
void rm_overwrite __P((char *, struct stat *));
void rm_tree __P((char **));
void usage __P((void));
-int main __P((int, char *[]));
-#ifdef __APPLE__ /* We're missing this prototype */
+#ifdef __APPLE__
+/* We lack fflagstostr(), but ls has a flags_to_string function
+ * that does the same thing. So... We really use that.
+ */
+char * flags_to_string(u_long, char *);
+#define fflagstostr(x) flags_to_string((x), NULL)
+
+/* We're missing this prototype */
int undelete __P((char *));
#endif
-/*
- * For the sake of the `-f' flag, check whether an error number indicates the
- * failure of an operation due to an non-existent file, either per se (ENOENT)
- * or because its filename argument was illegal (ENAMETOOLONG, ENOTDIR).
- */
-#define NONEXISTENT(x) \
- ((x) == ENOENT || (x) == ENAMETOOLONG || (x) == ENOTDIR)
-
/*
* rm --
* This rm is different from historic rm's, but is expected to match
char *argv[];
{
int ch, rflag;
+ char *p;
- (void)setlocale(LC_ALL, "");
+ /*
+ * Test for the special case where the utility is called as
+ * "unlink", for which the functionality provided is greatly
+ * simplified.
+ */
+ if ((p = rindex(argv[0], '/')) == NULL)
+ p = argv[0];
+ else
+ ++p;
+ if (strcmp(p, "unlink") == 0) {
+ if (argc == 2) {
+ rm_file(&argv[1]);
+ exit(eval);
+ } else
+ usage();
+ }
Pflag = rflag = 0;
- while ((ch = getopt(argc, argv, "dfiPRrW")) != -1)
+ while ((ch = getopt(argc, argv, "dfiPRrvW")) != -1)
switch(ch) {
case 'd':
dflag = 1;
case 'r': /* Compatibility. */
rflag = 1;
break;
+ case 'v':
+ vflag = 1;
+ break;
case 'W':
Wflag = 1;
break;
- case '?':
default:
usage();
}
argc -= optind;
argv += optind;
- if (argc < 1)
+ if (argc < 1) {
+ if (fflag)
+ return 0;
usage();
+ }
checkdot(argv);
+ uid = geteuid();
if (*argv) {
stdin_ok = isatty(STDIN_FILENO);
rm_file(argv);
}
- exit(eval);
- /* NOTREACHED */
+ exit (eval);
}
void
FTSENT *p;
int needstat;
int flags;
+ int rval;
/*
* Remove a file hierarchy. If forcing removal (-f), or interactive
* (-i) or can't ask anyway (stdin_ok), don't stat the file.
*/
- needstat = !fflag && !iflag && stdin_ok;
+ needstat = !uid || (!fflag && !iflag && stdin_ok);
/*
* If the -i option is specified, the user can skip on the pre-order
flags |= FTS_NOSTAT;
if (Wflag)
flags |= FTS_WHITEOUT;
- if (!(fts = fts_open(argv, flags,
- (int (*) __P((const FTSENT **, const FTSENT **)))NULL)))
- err(1, "%s", "");
+ if (!(fts = fts_open(argv, flags, NULL)))
+ err(1, NULL);
while ((p = fts_read(fts)) != NULL) {
switch (p->fts_info) {
case FTS_DNR:
continue;
case FTS_ERR:
errx(1, "%s: %s", p->fts_path, strerror(p->fts_errno));
- /* NOTREACHED */
case FTS_NS:
/*
* FTS_NS: assume that if can't stat the file, it
*/
if (!needstat)
break;
- if (!fflag || !NONEXISTENT(p->fts_errno)) {
+ if (!fflag || p->fts_errno != ENOENT) {
warnx("%s: %s",
p->fts_path, strerror(p->fts_errno));
eval = 1;
(void)fts_set(fts, p, FTS_SKIP);
p->fts_number = SKIPPED;
}
+ else if (!uid &&
+ (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
+ !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
+ chflags(p->fts_accpath,
+ p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE)) < 0)
+ goto err;
continue;
case FTS_DP:
/* Post-order: see if user skipped. */
continue;
}
- /*
- * If we can't read or search the directory, may still be
- * able to remove it. Don't print out the un{read,search}able
- * message unless the remove fails.
- */
- switch (p->fts_info) {
- case FTS_DP:
- case FTS_DNR:
- if (!rmdir(p->fts_accpath) ||
- (fflag && errno == ENOENT))
- continue;
- break;
+ rval = 0;
+ if (!uid &&
+ (p->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
+ !(p->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)))
+ rval = chflags(p->fts_accpath,
+ p->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE));
+ if (rval == 0) {
+ /*
+ * If we can't read or search the directory, may still be
+ * able to remove it. Don't print out the un{read,search}able
+ * message unless the remove fails.
+ */
+ switch (p->fts_info) {
+ case FTS_DP:
+ case FTS_DNR:
+ rval = rmdir(p->fts_accpath);
+ if (rval == 0 || (fflag && errno == ENOENT)) {
+ if (rval == 0 && vflag)
+ (void)printf("%s\n",
+ p->fts_path);
+ continue;
+ }
+ break;
- case FTS_W:
- if (!undelete(p->fts_accpath) ||
- (fflag && errno == ENOENT))
- continue;
- break;
+ case FTS_W:
+ rval = undelete(p->fts_accpath);
+ if (rval == 0 && (fflag && errno == ENOENT)) {
+ if (vflag)
+ (void)printf("%s\n",
+ p->fts_path);
+ continue;
+ }
+ break;
- default:
- if (Pflag)
- rm_overwrite(p->fts_accpath, NULL);
- if (!unlink(p->fts_accpath) ||
- (fflag && NONEXISTENT(errno)))
- continue;
+ default:
+ if (Pflag)
+ rm_overwrite(p->fts_accpath, NULL);
+ rval = unlink(p->fts_accpath);
+ if (rval == 0 || (fflag && errno == ENOENT)) {
+ if (rval == 0 && vflag)
+ (void)printf("%s\n",
+ p->fts_path);
+ continue;
+ }
+ }
}
+err:
warn("%s", p->fts_path);
eval = 1;
}
if (Wflag) {
sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR;
} else {
- if (!fflag || !NONEXISTENT(errno)) {
+ if (!fflag || errno != ENOENT) {
warn("%s", f);
eval = 1;
}
}
if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb))
continue;
- if (S_ISWHT(sb.st_mode))
- rval = undelete(f);
- else if (S_ISDIR(sb.st_mode))
- rval = rmdir(f);
- else {
- if (Pflag)
- rm_overwrite(f, &sb);
- rval = unlink(f);
+ rval = 0;
+ if (!uid &&
+ (sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
+ !(sb.st_flags & (SF_APPEND|SF_IMMUTABLE)))
+ rval = chflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE));
+ if (rval == 0) {
+ if (S_ISWHT(sb.st_mode))
+ rval = undelete(f);
+ else if (S_ISDIR(sb.st_mode))
+ rval = rmdir(f);
+ else {
+ if (Pflag)
+ rm_overwrite(f, &sb);
+ rval = unlink(f);
+ }
}
- if (rval && (!fflag || !NONEXISTENT(errno))) {
+ if (rval && (!fflag || errno != ENOENT)) {
warn("%s", f);
eval = 1;
}
+ if (vflag && rval == 0)
+ (void)printf("%s\n", f);
}
}
struct stat *sbp;
{
struct stat sb;
+ struct statfs fsb;
off_t len;
- int fd, wlen;
- char buf[8 * 1024];
+ int bsize, fd, wlen;
+ char *buf = NULL;
fd = -1;
if (sbp == NULL) {
return;
if ((fd = open(file, O_WRONLY, 0)) == -1)
goto err;
+ if (fstatfs(fd, &fsb) == -1)
+ goto err;
+ bsize = MAX(fsb.f_iosize, 1024);
+ if ((buf = malloc(bsize)) == NULL)
+ err(1, "malloc");
#define PASS(byte) { \
- memset(buf, byte, sizeof(buf)); \
+ memset(buf, byte, bsize); \
for (len = sbp->st_size; len > 0; len -= wlen) { \
- wlen = len < sizeof(buf) ? len : sizeof(buf); \
+ wlen = len < bsize ? len : bsize; \
if (write(fd, buf, wlen) != wlen) \
goto err; \
} \
if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))
goto err;
PASS(0xff);
- if (!fsync(fd) && !close(fd))
+ if (!fsync(fd) && !close(fd)) {
+ free(buf);
return;
+ }
err: eval = 1;
+ if (buf)
+ free(buf);
warn("%s", file);
}
struct stat *sp;
{
int ch, first;
- char modep[15];
+ char modep[15], *flagsp;
/* Check -i first. */
if (iflag)
* because their permissions are meaningless. Check stdin_ok
* first because we may not have stat'ed the file.
*/
- if (!stdin_ok || S_ISLNK(sp->st_mode) || !access(name, W_OK))
+ if (!stdin_ok || S_ISLNK(sp->st_mode) ||
+ (!access(name, W_OK) &&
+ !(sp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
+ (!(sp->st_flags & (UF_APPEND|UF_IMMUTABLE)) || !uid)))
return (1);
strmode(sp->st_mode, modep);
- (void)fprintf(stderr, "override %s%s%s/%s for %s? ",
+ if ((flagsp = fflagstostr(sp->st_flags)) == NULL)
+ err(1, NULL);
+ (void)fprintf(stderr, "override %s%s%s/%s %s%sfor %s? ",
modep + 1, modep[9] == ' ' ? "" : " ",
user_from_uid(sp->st_uid, 0),
- group_from_gid(sp->st_gid, 0), path);
+ group_from_gid(sp->st_gid, 0),
+ *flagsp ? flagsp : "", *flagsp ? " " : "",
+ path);
+#ifndef __APPLE__
+ free(flagsp);
+#endif
}
(void)fflush(stderr);
return (first == 'y' || first == 'Y');
}
-/*
- * POSIX.2 requires that if "." or ".." are specified as the basename
- * portion of an operand, a diagnostic message be written to standard
- * error and nothing more be done with such operands.
- *
- * Since POSIX.2 defines basename as the final portion of a path after
- * trailing slashes have been removed, we'll remove them here.
- */
-#define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2])))
+#define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2])))
void
checkdot(argv)
char **argv;
complained = 0;
for (t = argv; *t;) {
- /* strip trailing slashes */
- p = strrchr (*t, '\0');
- while (--p > *t && *p == '/')
- *p = '\0';
-
- /* extract basename */
if ((p = strrchr(*t, '/')) != NULL)
++p;
else
p = *t;
-
if (ISDOT(p)) {
if (!complained++)
warnx("\".\" and \"..\" may not be removed");
usage()
{
- (void)fprintf(stderr, "usage: rm [-dfiPRrW] file ...\n");
- exit(1);
- /* NOTREACHED */
+ (void)fprintf(stderr, "%s\n%s\n",
+ "usage: rm [-f | -i] [-dPRrvW] file ...",
+ " unlink file");
+ exit(EX_USAGE);
}
.Xr utimes 2
.Sh COMPATIBILITY
The obsolescent form of
-.Nm "" ,
+.Nm touch,
where a time format is specified as the first argument, is supported.
When no
.Fl r
If the
.Dq YY
letter pair is in the range 69 to 99, the year is set to 1969 to 1999,
-otherwise, the year is set in the 21st century.
+otherwise, the year is set in the 2000's.
.Sh STANDARDS
The
.Nm
continue;
/* Try reading/writing. */
- if (!S_ISLNK(sb.st_mode) && rw(*argv, &sb, fflag))
+ if (!S_ISLNK(sb.st_mode) && !S_ISDIR(sb.st_mode) &&
+ rw(*argv, &sb, fflag))
rval = 1;
+ else
+ warn("%s", *argv);
}
exit(rval);
}
int fd, needed_chmod, rval;
u_char byte;
- /* Try regular files and directories. */
- if (!S_ISREG(sbp->st_mode) && !S_ISDIR(sbp->st_mode)) {
+ /* Try regular files. */
+ if (!S_ISREG(sbp->st_mode)) {
warnx("%s: %s", fname, strerror(EFTYPE));
return (1);
}