]> granicus.if.org Git - file/commitdiff
Factor out finding CDF files by directory names. Add quickbooks
authorChristos Zoulas <christos@zoulas.com>
Sun, 11 Jan 2015 16:58:25 +0000 (16:58 +0000)
committerChristos Zoulas <christos@zoulas.com>
Sun, 11 Jan 2015 16:58:25 +0000 (16:58 +0000)
src/cdf.c
src/cdf.h
src/readcdf.c

index 43664e4ebb1efa8a081ee430417e59821fe48c36..73274902b78efebd856811b7e037cee72c043803 100644 (file)
--- a/src/cdf.c
+++ b/src/cdf.c
@@ -35,7 +35,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: cdf.c,v 1.72 2015/01/05 18:09:40 christos Exp $")
+FILE_RCSID("@(#)$File: cdf.c,v 1.73 2015/01/11 16:58:25 christos Exp $")
 #endif
 
 #include <assert.h>
@@ -747,24 +747,33 @@ cdf_read_user_stream(const cdf_info_t *info, const cdf_header_t *h,
     const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
     const cdf_dir_t *dir, const char *name, cdf_stream_t *scn)
 {
-       size_t i;
        const cdf_directory_t *d;
-       size_t name_len = strlen(name) + 1;
+       int i = cdf_find_stream(dir, name, CDF_DIR_TYPE_USER_STREAM);
+
+       if (i <= 0)
+               return i;
+
+       d = &dir->dir_tab[i - 1];
+       return cdf_read_sector_chain(info, h, sat, ssat, sst,
+           d->d_stream_first_sector, d->d_size, scn);
+}
+
+int
+cdf_find_stream(const cdf_dir_t *dir, const char *name, int type)
+{
+       size_t i, name_len = strlen(name) + 1;
 
        for (i = dir->dir_len; i > 0; i--)
-               if (dir->dir_tab[i - 1].d_type == CDF_DIR_TYPE_USER_STREAM &&
+               if (dir->dir_tab[i - 1].d_type == type &&
                    cdf_namecmp(name, dir->dir_tab[i - 1].d_name, name_len)
                    == 0)
                        break;
+       if (i > 0)
+               return i;
 
-       if (i == 0) {
-               DPRINTF(("Cannot find user stream `%s'\n", name));
-               errno = ESRCH;
-               return -1;
-       }
-       d = &dir->dir_tab[i - 1];
-       return cdf_read_sector_chain(info, h, sat, ssat, sst,
-           d->d_stream_first_sector, d->d_size, scn);
+       DPRINTF(("Cannot find type %d `%s'\n", type, name));
+       errno = ESRCH;
+       return 0;
 }
 
 int
@@ -1213,6 +1222,7 @@ cdf_dump(const void *v, size_t len)
        size_t i, j;
        const unsigned char *p = v;
        char abuf[16];
+
        (void)fprintf(stderr, "%.4x: ", 0);
        for (i = 0, j = 0; i < len; i++, p++) {
                (void)fprintf(stderr, "%.2x ", *p);
index eca5d647ba983bff2ed2ea9331d9020c466b820d..cee8d771e3ba8f89b764fa5852c27111f260a143 100644 (file)
--- a/src/cdf.h
+++ b/src/cdf.h
@@ -314,12 +314,7 @@ int cdf_read_property_info(const cdf_stream_t *, const cdf_header_t *, uint32_t,
 int cdf_read_user_stream(const cdf_info_t *, const cdf_header_t *,
     const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
     const cdf_dir_t *, const char *, cdf_stream_t *);
-#define cdf_read_catalog(info, header, sat, ssat, stream, dir, scn) \
-    cdf_read_user_stream(info, header, sat, ssat, stream, dir, "Catalog", \
-    scn)
-#define cdf_read_encrypted_package(info, header, sat, ssat, stream, dir, scn) \
-    cdf_read_user_stream(info, header, sat, ssat, stream, dir, \
-    "EncryptedPackage", scn)
+int cdf_find_stream(const cdf_dir_t *, const char *, int);
 int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *,
     const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
     const cdf_dir_t *, cdf_stream_t *);
index 60fc633aa993c22af44b7227c9929b03990b4696..e827bc90a3cc8e8cf20629126662380b367ebd80 100644 (file)
@@ -26,7 +26,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.50 2015/01/02 21:29:39 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.51 2015/01/11 16:58:25 christos Exp $")
 #endif
 
 #include <assert.h>
@@ -100,6 +100,10 @@ cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv)
                if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1])
                        return cv[i].mime;
        }
+#ifdef CDF_DEBUG
+       fprintf(stderr, "unknown mime %" PRIx64 ", %" PRIx64 "\n", clsid[0],
+           clsid[1]);
+#endif
        return NULL;
 }
 
@@ -121,6 +125,9 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv)
                        rv = nv[i].mime;
                        break;
                }
+#ifdef CDF_DEBUG
+       fprintf(stderr, "unknown app %s\n", vbuf);
+#endif
 #ifdef USE_C_LOCALE
        (void)uselocale(old_lc_ctype);
        freelocale(c_lc_ctype);
@@ -347,6 +354,90 @@ format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
 }
 #endif
 
+private int
+cdf_file_catalog_info(struct magic_set *ms, const cdf_info_t *info,
+    const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat,
+    const cdf_stream_t *sst, const cdf_dir_t *dir, cdf_stream_t *scn)
+{
+       int i;
+
+       if ((i = cdf_read_user_stream(info, h, sat, ssat, sst,
+           dir, "Catalog", scn)) <= 0)
+               return i;
+#ifdef CDF_DEBUG
+       cdf_dump_catalog(&h, &scn);
+#endif
+       if ((i = cdf_file_catalog(ms, h, scn)) == -1)
+               return -1;
+       return i;
+}
+
+private struct sinfo {
+       const char *name;
+       const char *mime;
+       const char *sections[5];
+       const int  types[5];
+} sectioninfo[] = {
+       { "Encrypted", "encrypted", 
+               {
+                       "EncryptedPackage", NULL, NULL, NULL, NULL,
+               },
+               {
+                       CDF_DIR_TYPE_USER_STREAM, 0, 0, 0, 0,
+
+               },
+       },
+       { "QuickBooks", "quickbooks", 
+               {
+#if 0
+                       "TaxForms", "PDFTaxForms", "modulesInBackup",
+#endif
+                       "mfbu_header", NULL, NULL, NULL, NULL,
+               },
+               {
+#if 0
+                       CDF_DIR_TYPE_USER_STORAGE,
+                       CDF_DIR_TYPE_USER_STORAGE,
+                       CDF_DIR_TYPE_USER_STREAM,
+#endif
+                       CDF_DIR_TYPE_USER_STREAM,
+                       0, 0, 0, 0
+               },
+       },
+};
+
+private int
+cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir)
+{
+       size_t sd, j;
+
+       for (sd = 0; sd < __arraycount(sectioninfo); sd++) {
+               const struct sinfo *si = &sectioninfo[sd];
+               for (j = 0; si->sections[j]; j++) {
+                       if (cdf_find_stream(dir, si->sections[j], si->types[j])
+                           <= 0) {
+#ifdef CDF_DEBUG
+                               fprintf(stderr, "Can't read %s\n",
+                                   si->sections[j]);
+#endif
+                               break;
+                       }
+               }
+               if (si->sections[j] != NULL)
+                       continue;
+               if (NOTMIME(ms)) {
+                       if (file_printf(ms, "CDFV2 %s", si->name) == -1)
+                               return -1;
+               } else {
+                       if (file_printf(ms, "application/CDFV2-%s",
+                           si->mime) == -1)
+                               return -1;
+               }
+               return 1;
+       }
+       return -1;
+}
+
 protected int
 file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
     size_t nbytes)
@@ -358,7 +449,6 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
         cdf_dir_t dir;
         int i;
         const char *expn = "";
-        const char *corrupt = "corrupt: ";
         const cdf_directory_t *root_storage;
 
         info.i_fd = fd;
@@ -439,30 +529,21 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
 
         if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
             &scn)) == -1) {
-                if (errno == ESRCH) {
-                       if ((i = cdf_read_catalog(&info, &h, &sat, &ssat, &sst,
-                           &dir, &scn)) == -1) {
-                               corrupt = expn;
-                               if ((i = cdf_read_encrypted_package(&info, &h,
-                                   &sat, &ssat, &sst, &dir, &scn)) == -1)
-                                       expn = "No summary info";
-                               else {
-                                       expn = "Encrypted";
-                                       i = -1;
-                               }
-                               goto out4;
-                       }
-#ifdef CDF_DEBUG
-                       cdf_dump_catalog(&h, &scn);
-#endif
-                       if ((i = cdf_file_catalog(ms, &h, &scn))
-                           < 0)
-                               expn = "Can't expand catalog";
-                } else {
+                if (errno != ESRCH) {
                         expn = "Cannot read summary info";
-                }
-                goto out4;
-        }
+                       goto out4;
+               }
+               i = cdf_file_catalog_info(ms, &info, &h, &sat, &ssat, &sst,
+                   &dir, &scn);
+               if (i > 0)
+                       goto out4;
+               i = cdf_file_dir_info(ms, &dir);
+               if (i < 0)
+                        expn = "Cannot read section info";
+               goto out4;
+       }
+
+
 #ifdef CDF_DEBUG
         cdf_dump_summary_info(&h, &scn);
 #endif
@@ -513,11 +594,10 @@ out0:
                    "Composite Document File V2 Document") == -1)
                    return -1;
                if (*expn)
-                   if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
+                   if (file_printf(ms, ", %s", expn) == -1)
                        return -1;
            } else {
-               if (file_printf(ms, "application/CDFV2-%s",
-                   *corrupt ? "corrupt" : "encrypted") == -1)
+               if (file_printf(ms, "application/CDFV2-unknown") == -1)
                    return -1;
            }
            i = 1;