diff options
author | David E. O'Brien <obrien@FreeBSD.org> | 2009-05-04 00:37:44 +0000 |
---|---|---|
committer | David E. O'Brien <obrien@FreeBSD.org> | 2009-05-04 00:37:44 +0000 |
commit | 7dbb948b5f00eabb81904e9db0aa9fc712939aca (patch) | |
tree | 12756817ab8bc4334652c625c7731c9e7fd0cefc /contrib/file/readcdf.c | |
parent | 8ee6f90a0c45383950152583c7fd62172e27bb73 (diff) | |
parent | 4f3dd34290f174adbda2b9668cc6b6c554ae9bb0 (diff) |
Merge vendor/file/dist@191739, bringing FILE 5.00 to 8-CURRENT.
Notes
Notes:
svn path=/head/; revision=191771
Diffstat (limited to 'contrib/file/readcdf.c')
-rw-r--r-- | contrib/file/readcdf.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/contrib/file/readcdf.c b/contrib/file/readcdf.c new file mode 100644 index 000000000000..27031dbd9dd3 --- /dev/null +++ b/contrib/file/readcdf.c @@ -0,0 +1,256 @@ +/*- + * Copyright (c) 2008 Christos Zoulas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "file.h" + +#ifndef lint +FILE_RCSID("@(#)$File: readcdf.c,v 1.11 2009/02/03 20:27:51 christos Exp $") +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <time.h> +#include <ctype.h> + +#include "cdf.h" +#include "magic.h" + +#define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0) + +private int +cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, + size_t count) +{ + size_t i; + cdf_timestamp_t tp; + struct timespec ts; + char buf[64]; + const char *str = "vnd.ms-office"; + const char *s; + int len; + + for (i = 0; i < count; i++) { + cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); + switch (info[i].pi_type) { + case CDF_SIGNED16: + if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf, + info[i].pi_s16) == -1) + return -1; + break; + case CDF_SIGNED32: + if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf, + info[i].pi_s32) == -1) + return -1; + break; + case CDF_UNSIGNED32: + if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf, + info[i].pi_u32) == -1) + return -1; + break; + case CDF_LENGTH32_STRING: + len = info[i].pi_str.s_len; + if (len > 1) { + s = info[i].pi_str.s_buf; + if (NOTMIME(ms)) { + if (file_printf(ms, ", %s: %.*s", buf, + len, s) == -1) + return -1; + } else if (info[i].pi_id == + CDF_PROPERTY_NAME_OF_APPLICATION) { + if (strstr(s, "Word")) + str = "msword"; + else if (strstr(s, "Excel")) + str = "vnd.ms-excel"; + else if (strstr(s, "Powerpoint")) + str = "vnd.ms-powerpoint"; + } + } + break; + case CDF_FILETIME: + tp = info[i].pi_tp; + if (tp != 0) { + if (tp < 1000000000000000LL) { + char tbuf[64]; + cdf_print_elapsed_time(tbuf, + sizeof(tbuf), tp); + if (NOTMIME(ms) && file_printf(ms, + ", %s: %s", buf, tbuf) == -1) + return -1; + } else { + char *c, *ec; + cdf_timestamp_to_timespec(&ts, tp); + c = ctime(&ts.tv_sec); + if ((ec = strchr(c, '\n')) != NULL) + *ec = '\0'; + + if (NOTMIME(ms) && file_printf(ms, + ", %s: %s", buf, c) == -1) + return -1; + } + } + break; + case CDF_CLIPBOARD: + break; + default: + file_error(ms, 0, "Internal parsing error"); + return -1; + } + } + if (!NOTMIME(ms)) { + if (file_printf(ms, "application/%s", str) == -1) + return -1; + } + return 1; +} + +private int +cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst) +{ + cdf_summary_info_header_t si; + cdf_property_info_t *info; + size_t count; + int m; + + if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1) { + if (si.si_byte_order != 0xfffe) + return 0; + else + return -1; + } + + if (si.si_byte_order != 0xfffe) + return 0; + + if (NOTMIME(ms)) { + if (file_printf(ms, "CDF V2 Document") == -1) + return -1; + + if (file_printf(ms, ", %s Endian", + si.si_byte_order == 0xfffe ? "Little" : "Big") == -1) + return -1; + switch (si.si_os) { + case 2: + if (file_printf(ms, ", Os: Windows, Version %d.%d", + si.si_os_version & 0xff, si.si_os_version >> 8) + == -1) + return -1; + break; + case 1: + if (file_printf(ms, ", Os: MacOS, Version %d.%d", + si.si_os_version >> 8, si.si_os_version & 0xff) + == -1) + return -1; + break; + default: + if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os, + si.si_os_version & 0xff, si.si_os_version >> 8) + == -1) + return -1; + break; + } + } + + m = cdf_file_property_info(ms, info, count); + free(info); + + return m; +} + +protected int +file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, + size_t nbytes) +{ + cdf_header_t h; + cdf_sat_t sat, ssat; + cdf_stream_t sst, scn; + cdf_dir_t dir; + int i; + (void)&nbytes; + (void)&buf; + + if (ms->flags & MAGIC_APPLE) + return 0; + if (cdf_read_header(fd, &h) == -1) + return 0; +#ifdef CDF_DEBUG + cdf_dump_header(&h); +#endif + + if (cdf_read_sat(fd, &h, &sat) == -1) { + file_error(ms, errno, "Can't read SAT"); + return -1; + } +#ifdef CDF_DEBUG + cdf_dump_sat("SAT", &h, &sat); +#endif + + if ((i = cdf_read_ssat(fd, &h, &sat, &ssat)) == -1) { + file_error(ms, errno, "Can't read SAT"); + goto out1; + } +#ifdef CDF_DEBUG + cdf_dump_sat("SSAT", &h, &ssat); +#endif + + if ((i = cdf_read_dir(fd, &h, &sat, &dir)) == -1) { + file_error(ms, errno, "Can't read directory"); + goto out2; + } + + if ((i = cdf_read_short_stream(fd, &h, &sat, &dir, &sst)) == -1) { + file_error(ms, errno, "Cannot read short stream"); + goto out3; + } + +#ifdef CDF_DEBUG + cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir); +#endif + if ((i = cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir, &scn)) + == -1) { + /* Some files don't have summary info! */ +#ifdef notyet + file_error(ms, errno, "Can't read summary_info"); +#else + i = 0; +#endif + goto out4; + } +#ifdef CDF_DEBUG + cdf_dump_summary_info(&h, &scn); +#endif + if ((i = cdf_file_summary_info(ms, &scn)) == -1) + file_error(ms, errno, "Can't expand summary_info"); + free(scn.sst_tab); +out4: + free(sst.sst_tab); +out3: + free(dir.dir_tab); +out2: + free(ssat.sat_tab); +out1: + free(sat.sat_tab); + return i; +} |