]> granicus.if.org Git - file/commitdiff
- separate mime encoding from mime type
authorChristos Zoulas <christos@zoulas.com>
Wed, 17 Oct 2007 19:33:31 +0000 (19:33 +0000)
committerChristos Zoulas <christos@zoulas.com>
Wed, 17 Oct 2007 19:33:31 +0000 (19:33 +0000)
- fix printing -\012

src/ascmagic.c
src/compress.c
src/file.c
src/fsmagic.c
src/funcs.c
src/is_tar.c
src/magic.c
src/magic.h
src/softmagic.c

index add8bf4cf00310b6f3a91f84868a78c931ce36b1..92c83a26705954297784b8767b96a61c7fd2b72e 100644 (file)
@@ -49,7 +49,7 @@
 #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;
@@ -76,6 +76,7 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
        size_t ulen;
        struct names *p;
        int rv = -1;
+       int mime = ms->flags & MAGIC_MIME;
 
        const char *code = NULL;
        const char *code_mime = NULL;
@@ -271,21 +272,27 @@ subtype_identified:
        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;
index 5f8a7bbcf0de369b8e699fc8924a68be50ac840f..610320084191030e01f7d7fcb73bc20c1495c9e0 100644 (file)
@@ -55,7 +55,7 @@
 
 
 #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 {
@@ -98,6 +98,7 @@ file_zmagic(struct magic_set *ms, int fd, const char *name,
        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;
@@ -112,13 +113,18 @@ file_zmagic(struct magic_set *ms, int fd, const char *name,
                        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;
index 0cd55ffae4d286f972dcb7f400ec588d2b211b90..b9bfd9e578f17d85e86101d2d7c3379249910342 100644 (file)
@@ -71,7 +71,7 @@
 #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 */
 
 
@@ -133,8 +133,12 @@ main(int argc, char *argv[])
        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'},
@@ -220,9 +224,17 @@ main(int argc, char *argv[])
                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;
@@ -567,7 +579,10 @@ help(void)
 "                               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"
index aa3e509352a56a912e82779f0c40b9c7061665e9..e04f5981876f95afd71a3b6c1d7bb793a8bbe28b 100644 (file)
 #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;
@@ -95,11 +96,12 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
                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;
                }
        }
@@ -303,8 +305,9 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
         * 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;
        }
index 026235253cf1b53c14c4016c524d72b9875dc258..706c4b5a01f28993ae7323941372e6841f90106a 100644 (file)
@@ -48,7 +48,7 @@
 #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
@@ -164,59 +164,73 @@ protected int
 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
 
index 02ef975db3984479a5da0cf93ac7f925084af7e2..142b4870f988e357044f4655d8452198d06e3937 100644 (file)
@@ -45,7 +45,7 @@
 #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') )
@@ -53,6 +53,12 @@ FILE_RCSID("@(#)$File: is_tar.c,v 1.28 2007/08/19 03:45:08 christos Exp $")
 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)
 {
@@ -60,25 +66,19 @@ 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;
 }
 
 /*
index b7b38cda2ca026b7ff345ce8842b00a0b8ccb95c..3242f76a16ae10b83a90c1512b88049acb64010e 100644 (file)
@@ -63,7 +63,7 @@
 #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__
@@ -260,6 +260,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
        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
@@ -343,20 +344,9 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
                }
        }
 
-       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);
index 483cac3fc2a52844c52952a53d94656d5cb911f5..96aa2f68ced0966432738cba16eb03c3b3707ea1 100644 (file)
 #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" {
index e74f09f2cd5bddf090b504c2b760afd9ff5def99..efa63e94874f53c49a751c37a43b73ff7993bad0 100644 (file)
@@ -38,7 +38,7 @@
 
 
 #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,
@@ -254,9 +254,10 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
                                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 */
                }