#include "names.h"
#ifndef lint
-FILE_RCSID("@(#)$File: ascmagic.c,v 1.51 2007/08/19 03:45:07 christos Exp $")
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.52 2007/10/17 19:33:31 christos Exp $")
#endif /* lint */
typedef unsigned long unichar;
size_t ulen;
struct names *p;
int rv = -1;
+ int mime = ms->flags & MAGIC_MIME;
const char *code = NULL;
const char *code_mime = NULL;
if (seen_cr && nbytes < HOWMANY)
n_cr++;
- if ((ms->flags & MAGIC_MIME)) {
- if (subtype_mime) {
- if (file_printf(ms, subtype_mime) == -1)
- goto done;
- } else {
- if (file_printf(ms, "text/plain") == -1)
- goto done;
+ if (mime) {
+ if (mime & MAGIC_MIME_TYPE) {
+ if (subtype_mime) {
+ if (file_printf(ms, subtype_mime) == -1)
+ goto done;
+ } else {
+ if (file_printf(ms, "text/plain") == -1)
+ goto done;
+ }
}
- if (code_mime) {
- if (file_printf(ms, " charset=") == -1)
+ if ((mime == 0 || mime == MAGIC_MIME) && code_mime) {
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, " charset=") == -1)
goto done;
if (file_printf(ms, code_mime) == -1)
goto done;
}
+
+ if (mime == MAGIC_MIME_ENCODING)
+ file_printf(ms, "binary");
} else {
if (file_printf(ms, code) == -1)
goto done;
#ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.52 2007/08/19 03:45:08 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.53 2007/10/17 19:33:31 christos Exp $")
#endif
private struct {
unsigned char *newbuf = NULL;
size_t i, nsz;
int rv = 0;
+ int mime = ms->flags & MAGIC_MIME;
if ((ms->flags & MAGIC_COMPRESS) == 0)
return 0;
rv = -1;
if (file_buffer(ms, -1, name, newbuf, nsz) == -1)
goto error;
- if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
- " compressed-encoding=" : " (") == -1)
- goto error;
- if (file_buffer(ms, -1, NULL, buf, nbytes) == -1)
+
+ if (mime == MAGIC_MIME || mime == 0) {
+ if (file_printf(ms, mime ?
+ " compressed-encoding=" : " (") == -1)
+ goto error;
+ }
+
+ if ((mime == 0 || mime & MAGIC_MIME_ENCODING) &&
+ file_buffer(ms, -1, NULL, buf, nbytes) == -1)
goto error;
- if (!(ms->flags & MAGIC_MIME) &&
- file_printf(ms, ")") == -1)
+
+ if (!mime && file_printf(ms, ")") == -1)
goto error;
rv = 1;
break;
#include "patchlevel.h"
#ifndef lint
-FILE_RCSID("@(#)$File: file.c,v 1.111 2007/05/08 14:44:18 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.112 2007/10/17 19:33:31 christos Exp $")
#endif /* lint */
int longindex;
static const struct option long_options[] =
{
- {"version", 0, 0, 'v'},
+ /* Put long-only options first */
{"help", 0, 0, 0},
+ {"mime-type", 0, 0, 0},
+ {"mime-encoding", 0, 0, 0},
+
+ {"version", 0, 0, 'v'},
{"brief", 0, 0, 'b'},
{"checking-printout", 0, 0, 'c'},
{"debug", 0, 0, 'd'},
switch (c) {
#ifdef HAVE_GETOPT_LONG
case 0 :
- if (longindex == 1)
+ switch (longindex) {
+ case 0:
help();
- break;
+ break;
+ case 1:
+ flags |= MAGIC_MIME_TYPE;
+ break;
+ case 2:
+ flags |= MAGIC_MIME_ENCODING;
+ break;
+ }
#endif
case '0':
nulsep = 1;
" ascii, apptype, elf, compress, soft, tar\n"
" -f, --files-from FILE read the filenames to be examined from FILE\n"
" -F, --separator string use string as separator instead of `:'\n"
-" -i, --mime output mime type strings\n"
+" -i, --mime output MIME type strings (--mime-type and\n"
+" --mime-encoding)\n"
+" --mime-type output the MIME type\n"
+" --mime-encoding output the MIME encoding\n"
" -k, --keep-going don't stop at the first match\n"
" -L, --dereference causes symlinks to be followed\n"
" -n, --no-buffer do not buffer output\n"
#undef HAVE_MAJOR
#ifndef lint
-FILE_RCSID("@(#)$File: fsmagic.c,v 1.47 2007/01/12 17:38:28 christos Exp $")
+FILE_RCSID("@(#)$File: fsmagic.c,v 1.48 2007/10/17 19:33:31 christos Exp $")
#endif /* lint */
protected int
file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
{
int ret = 0;
+ int mime = ms->flags & MAGIC_MIME;
#ifdef S_IFLNK
char buf[BUFSIZ+4];
int nch;
return 1;
}
- if ((ms->flags & MAGIC_MIME) != 0) {
+ if (mime) {
if ((sb->st_mode & S_IFMT) != S_IFREG) {
- if (file_printf(ms, "application/x-not-regular-file")
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-not-regular-file")
== -1)
- return -1;
+ return -1;
return 1;
}
}
* when we read the file.)
*/
if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
- if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
- "application/x-empty" : "empty") == -1)
+ if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
+ file_printf(ms, mime ? "application/x-empty" :
+ "empty") == -1)
return -1;
return 1;
}
#endif
#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.33 2007/06/15 00:01:15 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.34 2007/10/17 19:33:31 christos Exp $")
#endif /* lint */
#ifndef HAVE_VSNPRINTF
file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
size_t nb)
{
- int m;
+ int m;
+ int mime = ms->flags & MAGIC_MIME;
+
+ if (nb == 0) {
+ if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
+ file_printf(ms, mime ? "application/x-empty" :
+ "empty") == -1)
+ return -1;
+ return 1;
+ } else if (nb == 1) {
+ if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
+ file_printf(ms, mime ? "application/octet-stream" :
+ "very short file (no magic)") == -1)
+ return -1;
+ return 1;
+ }
#ifdef __EMX__
- if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
- switch (file_os2_apptype(ms, inname, buf, nb)) {
- case -1:
- return -1;
- case 0:
- break;
- default:
- return 1;
+ if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
+ switch (file_os2_apptype(ms, inname, buf, nb)) {
+ case -1:
+ return -1;
+ case 0:
+ break;
+ default:
+ return 1;
+ }
}
- }
#endif
- /* try compression stuff */
- if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 ||
- (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) {
- /* Check if we have a tar file */
- if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 ||
- (m = file_is_tar(ms, buf, nb)) == 0) {
- /* try tests in /etc/magic (or surrogate magic file) */
- if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 ||
- (m = file_softmagic(ms, buf, nb)) == 0) {
- /* try known keywords, check whether it is ASCII */
- if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 ||
- (m = file_ascmagic(ms, buf, nb)) == 0) {
- /* abandon hope, all ye who remain here */
- if (file_printf(ms, ms->flags & MAGIC_MIME ?
- (nb ? "application/octet-stream" :
- "application/empty") :
- (nb ? "data" :
- "empty")) == -1)
- return -1;
- m = 1;
+ /* try compression stuff */
+ if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 ||
+ (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) {
+ /* Check if we have a tar file */
+ if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 ||
+ (m = file_is_tar(ms, buf, nb)) == 0) {
+ /* try tests in /etc/magic (or surrogate magic file) */
+ if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 ||
+ (m = file_softmagic(ms, buf, nb)) == 0) {
+ /* try known keywords, check whether it is ASCII */
+ if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 ||
+ (m = file_ascmagic(ms, buf, nb)) == 0) {
+ /* abandon hope, all ye who remain here */
+ if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
+ file_printf(ms, mime ? "application/octet-stream" :
+ "data") == -1)
+ return -1;
+ m = 1;
+ }
}
}
}
- }
#ifdef BUILTIN_ELF
- if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 && nb > 5 && fd != -1) {
- /*
- * We matched something in the file, so this *might*
- * be an ELF file, and the file is at least 5 bytes
- * long, so if it's an ELF file it has at least one
- * byte past the ELF magic number - try extracting
- * information from the ELF headers that cannot easily
- * be extracted with rules in the magic file.
- */
- (void)file_tryelf(ms, fd, buf, nb);
- }
+ if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 &&
+ nb > 5 && fd != -1) {
+ /*
+ * We matched something in the file, so this *might*
+ * be an ELF file, and the file is at least 5 bytes
+ * long, so if it's an ELF file it has at least one
+ * byte past the ELF magic number - try extracting
+ * information from the ELF headers that cannot easily
+ * be extracted with rules in the magic file.
+ */
+ (void)file_tryelf(ms, fd, buf, nb);
+ }
#endif
- return m;
+ return m;
}
#endif
#include "tar.h"
#ifndef lint
-FILE_RCSID("@(#)$File: is_tar.c,v 1.28 2007/08/19 03:45:08 christos Exp $")
+FILE_RCSID("@(#)$File: is_tar.c,v 1.29 2007/10/17 19:33:31 christos Exp $")
#endif
#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
private int is_tar(const unsigned char *, size_t);
private int from_oct(int, const char *); /* Decode octal number */
+static const char *tartype[] = {
+ "tar archive",
+ "POSIX tar archive",
+ "POSIX tar archive (GNU)",
+};
+
protected int
file_is_tar(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
{
* 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:
- if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
- "application/x-tar" : "tar archive") == -1)
- return -1;
- return 1;
- case 2:
- if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
- "application/x-tar" : "POSIX tar archive") == -1)
- return -1;
- return 1;
- case 3:
- if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
- "application/x-tar" : "POSIX tar archive (GNU)") == -1)
- return -1;
- return 1;
- default:
+ int tar = is_tar(buf, nbytes);
+ int mime = ms->flags & MAGIC_MIME;
+
+ if (tar < 1 || tar > 3)
return 0;
- }
+
+ if (mime == MAGIC_MIME_ENCODING)
+ return 0;
+
+ if (file_printf(ms, mime ? "application/x-tar" :
+ tartype[tar - 1]) == -1)
+ return -1;
+ return 1;
}
/*
#include "patchlevel.h"
#ifndef lint
-FILE_RCSID("@(#)$File: magic.c,v 1.43 2007/09/26 20:45:26 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.44 2007/10/17 19:33:31 christos Exp $")
#endif /* lint */
#ifdef __EMX__
struct stat sb;
ssize_t nbytes = 0; /* number of bytes read from a datafile */
int ispipe = 0;
+ int mime = ms->flags & MAGIC_MIME;
/*
* one extra for terminating '\0', and
}
}
- if (nbytes == 0) {
- if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
- "application/x-empty" : "empty") == -1)
- goto done;
- } else if (nbytes == 1) {
- if (file_printf(ms, (ms->flags & MAGIC_MIME) ?
- "application/octet-stream" : "very short file (no magic)")
- == -1)
- goto done;
- } else {
- (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
- if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
- goto done;
- }
+ (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
+ if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
+ goto done;
rv = 0;
done:
free(buf);
#define MAGIC_SYMLINK 0x000002 /* Follow symlinks */
#define MAGIC_COMPRESS 0x000004 /* Check inside compressed files */
#define MAGIC_DEVICES 0x000008 /* Look at the contents of devices */
-#define MAGIC_MIME 0x000010 /* Return a mime string */
+#define MAGIC_MIME_TYPE 0x000010 /* Return only the MIME type */
#define MAGIC_CONTINUE 0x000020 /* Return all matches */
#define MAGIC_CHECK 0x000040 /* Print warnings to stderr */
#define MAGIC_PRESERVE_ATIME 0x000080 /* Restore access time on exit */
-#define MAGIC_RAW 0x000100 /* Don't translate unprintable chars */
+#define MAGIC_RAW 0x000100 /* Don't translate unprint chars */
#define MAGIC_ERROR 0x000200 /* Handle ENOENT etc as real errors */
-#define MAGIC_NO_CHECK_COMPRESS 0x001000 /* Don't check for compressed files */
-#define MAGIC_NO_CHECK_TAR 0x002000 /* Don't check for tar files */
-#define MAGIC_NO_CHECK_SOFT 0x004000 /* Don't check magic entries */
-#define MAGIC_NO_CHECK_APPTYPE 0x008000 /* Don't check application type */
-#define MAGIC_NO_CHECK_ELF 0x010000 /* Don't check for elf details */
-#define MAGIC_NO_CHECK_ASCII 0x020000 /* Don't check for ascii files */
-#define MAGIC_NO_CHECK_TROFF 0x040000 /* Don't check ascii/troff */
-#define MAGIC_NO_CHECK_FORTRAN 0x080000 /* Don't check ascii/fortran */
-#define MAGIC_NO_CHECK_TOKENS 0x100000 /* Don't check ascii/tokens */
+#define MAGIC_MIME_ENCODING 0x000400 /* Return only the MIME encoding */
+#define MAGIC_MIME (MAGIC_MIME_TYPE|MAGIC_MIME_ENCODING)
+#define MAGIC_NO_CHECK_COMPRESS 0x001000 /* Don't check for compressed files */
+#define MAGIC_NO_CHECK_TAR 0x002000 /* Don't check for tar files */
+#define MAGIC_NO_CHECK_SOFT 0x004000 /* Don't check magic entries */
+#define MAGIC_NO_CHECK_APPTYPE 0x008000 /* Don't check application type */
+#define MAGIC_NO_CHECK_ELF 0x010000 /* Don't check for elf details */
+#define MAGIC_NO_CHECK_ASCII 0x020000 /* Don't check for ascii files */
+#define MAGIC_NO_CHECK_TROFF 0x040000 /* Don't check ascii/troff */
+#define MAGIC_NO_CHECK_FORTRAN 0x080000 /* Don't check ascii/fortran */
+#define MAGIC_NO_CHECK_TOKENS 0x100000 /* Don't check ascii/tokens */
#ifdef __cplusplus
extern "C" {
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.100 2007/09/26 20:19:05 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.101 2007/10/17 19:33:31 christos Exp $")
#endif /* lint */
private int match(struct magic_set *, struct magic *, uint32_t,
break;
}
}
- firstline = 0;
- if (printed_something)
+ if (printed_something) {
+ firstline = 0;
returnval = 1;
+ }
if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) {
return 1; /* don't keep searching */
}