From: Christos Zoulas Date: Sun, 11 Jan 2015 16:58:25 +0000 (+0000) Subject: Factor out finding CDF files by directory names. Add quickbooks X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4f66b527aaa958b4476136253729687efcdc337a;p=file Factor out finding CDF files by directory names. Add quickbooks --- diff --git a/src/cdf.c b/src/cdf.c index 43664e4e..73274902 100644 --- 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 @@ -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); diff --git a/src/cdf.h b/src/cdf.h index eca5d647..cee8d771 100644 --- 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 *); diff --git a/src/readcdf.c b/src/readcdf.c index 60fc633a..e827bc90 100644 --- a/src/readcdf.c +++ b/src/readcdf.c @@ -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 @@ -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 = §ioninfo[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;