/*
* compress routines:
- * is_compress() returns 0 if uncompressed, number of bits if compressed.
- * uncompress(old, n, newch) - uncompress old into new, return sizeof new
- * $Id: compress.c,v 1.6 1992/09/08 15:32:17 ian Exp $
+ * 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
+ * $Id: compress.c,v 1.7 1993/10/27 20:59:05 christos Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include "file.h"
-/* Check for compression, return nbits. Algorithm, in magic(4) format:
- * 0 string \037\235 compressed data
- * >2 byte&0x80 >0 block compressed
- * >2 byte&0x1f x %d bits
- */
+static struct {
+ char *magic;
+ int maglen;
+ char *argv[3];
+ int silent;
+} compr[] = {
+ { "\037\235", 2, { "uncompress", "-c", NULL }, 0 },
+ { "\037\213", 2, { "gzip", "-dq", NULL }, 1 },
+#if 0
+ /* XXX pcat does not work, cause I don't know how to make it read stdin */
+ { "\037\036", 2, { "pcat", NULL, NULL }, 0 },
+#endif
+};
+
+static int ncompr = sizeof(compr) / sizeof(compr[0]);
+
+
+static int uncompress __P((int, const unsigned char *, unsigned char **, int));
+
int
-is_compress(p, b)
-const unsigned char *p;
-int *b;
+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 (*p != '\037' || *(/*signed*/ char*)(p+1) != '\235')
- return 0; /* not compress()ed */
+ if (i == ncompr)
+ return 0;
- *b = *(p+2) & 0x80;
- return *(p+2) & 0x1f;
+ if ((newsize = uncompress(i, buf, &newbuf, nbytes)) != 0) {
+ tryit(newbuf, newsize, 1);
+ free(newbuf);
+ printf(" (");
+ tryit(buf, nbytes, 0);
+ printf(")");
+ }
+ return 1;
}
-int
-uncompress(old, newch, n)
+
+static int
+uncompress(method, old, newch, n)
+int method;
const unsigned char *old;
unsigned char **newch;
int n;
(void) dup(fdout[1]);
(void) close(fdout[0]);
(void) close(fdout[1]);
+ if (compr[method].silent)
+ (void) close(2);
- execlp("uncompress", "uncompress", "-c", NULL);
- error("could not execute `uncompress' (%s).\n",
- strerror(errno));
+ 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));
return n;
}
}
+
+
*/
#ifndef lint
static char *moduleid =
- "@(#)$Id: file.c,v 1.28 1993/09/23 21:47:01 christos Exp $";
+ "@(#)$Id: file.c,v 1.29 1993/10/27 20:59:05 christos Exp $";
#endif /* lint */
#include <stdio.h>
ckfputs("empty", stdout);
else {
buf[nbytes++] = '\0'; /* null-terminate it */
- tryit(buf, nbytes);
+ tryit(buf, nbytes, zflag);
}
if (inname != stdname) {
void
-tryit(buf, nb)
+tryit(buf, nb, zflag)
unsigned char *buf;
-int nb;
+int nb, zflag;
{
/*
- * try tests in /etc/magic (or surrogate magic file)
+ * Try compression stuff
*/
- if (softmagic(buf, nb) != 1)
- /*
- * try known keywords, check for ascii-ness too.
- */
- if (ascmagic(buf, nb) != 1)
+ if (!zflag || zmagic(buf, nb) != 1)
/*
- * abandon hope, all ye who remain here
+ * try tests in /etc/magic (or surrogate magic file)
*/
- ckfputs("data", stdout);
+ if (softmagic(buf, nb) != 1)
+ /*
+ * try known keywords, check for ascii-ness too.
+ */
+ if (ascmagic(buf, nb) != 1)
+ /*
+ * abandon hope, all ye who remain here
+ */
+ ckfputs("data", stdout);
}
-
/*
* file.h - definitions for file(1) program
- * @(#)$Id: file.h,v 1.17 1993/09/23 21:47:01 christos Exp $
+ * @(#)$Id: file.h,v 1.18 1993/10/27 20:59:05 christos Exp $
*
* Copyright (c) Ian F. Darwin, 1987.
* Written by Ian F. Darwin.
* 4. This notice may not be removed or altered.
*/
-#define HOWMANY 1024 /* how much of the file to look at */
+#define HOWMANY 8192 /* how much of the file to look at */
#define MAXMAGIS 1000 /* max entries in /etc/magic */
#define MAXDESC 50 /* max leng of text description */
#define MAXstring 32 /* max leng of "string" types */
extern void process __P((const char *, int));
extern void showstr __P((FILE *, const char *, int));
extern int softmagic __P((unsigned char *, int));
-extern void tryit __P((unsigned char *, int));
-extern int uncompress __P((const unsigned char *, unsigned char **, int));
+extern void tryit __P((unsigned char *, int, int));
+extern int zmagic __P((unsigned char *, int));
extern void ckfprintf __P((FILE *, const char *, ...));
extern int optind; /* From getopt(3) */
extern char *optarg;
-#if !defined(__STDC__) || defined(sun) || defined(__sun__)
+#if !defined(__STDC__) || defined(sun) || defined(__sun__) || defined(__convex__)
extern int sys_nerr;
extern char *sys_errlist[];
#define strerror(e) \
#define FILE_VERSION_MAJOR 3
-#define patchlevel 10
+#define patchlevel 12
/*
* Patchlevel file for Ian Darwin's MAGIC command.
- * $Id: patchlevel.h,v 1.11 1993/09/24 18:49:06 christos Exp $
+ * $Id: patchlevel.h,v 1.12 1993/10/27 20:59:05 christos Exp $
*
* $Log: patchlevel.h,v $
- * Revision 1.11 1993/09/24 18:49:06 christos
+ * 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
#ifndef lint
static char *moduleid =
- "@(#)$Id: softmagic.c,v 1.23 1993/09/24 18:47:48 christos Exp $";
+ "@(#)$Id: softmagic.c,v 1.24 1993/10/27 20:59:05 christos Exp $";
#endif /* lint */
static int match __P((unsigned char *, int));
struct magic *m;
{
char *pp, *rt;
+ unsigned long mask = m->mask ? m->mask : ~0;
switch (m->type) {
case BYTE:
- (void) printf(m->desc, p->b);
+ (void) printf(m->desc, (unsigned char) p->b & mask);
break;
case SHORT:
case BESHORT:
case LESHORT:
- (void) printf(m->desc, p->h);
+ (void) printf(m->desc, (unsigned short) p->h & mask);
break;
case LONG:
case BELONG:
case LELONG:
- (void) printf(m->desc, p->l);
+ (void) printf(m->desc, (unsigned long) p->l & mask);
break;
case STRING:
if (m->reln == '=') {
switch (m->reln) {
case 'x':
if (debug)
- (void) fprintf(stderr, "*any* = 1\n");
+ (void) fprintf(stderr, "%d == *any* = 1\n", v);
return 1;
case '!':
if (debug)