2 * Copyright (c) 2008 Christos Zoulas
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
15 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
29 FILE_RCSID("@(#)$File: readcdf.c,v 1.11 2009/02/03 20:27:51 christos Exp $")
41 #define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0)
44 cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
51 const char *str = "vnd.ms-office";
55 for (i = 0; i < count; i++) {
56 cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
57 switch (info[i].pi_type) {
59 if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
60 info[i].pi_s16) == -1)
64 if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
65 info[i].pi_s32) == -1)
69 if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
70 info[i].pi_u32) == -1)
73 case CDF_LENGTH32_STRING:
74 len = info[i].pi_str.s_len;
76 s = info[i].pi_str.s_buf;
78 if (file_printf(ms, ", %s: %.*s", buf,
81 } else if (info[i].pi_id ==
82 CDF_PROPERTY_NAME_OF_APPLICATION) {
83 if (strstr(s, "Word"))
85 else if (strstr(s, "Excel"))
87 else if (strstr(s, "Powerpoint"))
88 str = "vnd.ms-powerpoint";
95 if (tp < 1000000000000000LL) {
97 cdf_print_elapsed_time(tbuf,
99 if (NOTMIME(ms) && file_printf(ms,
100 ", %s: %s", buf, tbuf) == -1)
104 cdf_timestamp_to_timespec(&ts, tp);
105 c = ctime(&ts.tv_sec);
106 if ((ec = strchr(c, '\n')) != NULL)
109 if (NOTMIME(ms) && file_printf(ms,
110 ", %s: %s", buf, c) == -1)
118 file_error(ms, 0, "Internal parsing error");
123 if (file_printf(ms, "application/%s", str) == -1)
130 cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst)
132 cdf_summary_info_header_t si;
133 cdf_property_info_t *info;
137 if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1) {
138 if (si.si_byte_order != 0xfffe)
144 if (si.si_byte_order != 0xfffe)
148 if (file_printf(ms, "CDF V2 Document") == -1)
151 if (file_printf(ms, ", %s Endian",
152 si.si_byte_order == 0xfffe ? "Little" : "Big") == -1)
156 if (file_printf(ms, ", Os: Windows, Version %d.%d",
157 si.si_os_version & 0xff, si.si_os_version >> 8)
162 if (file_printf(ms, ", Os: MacOS, Version %d.%d",
163 si.si_os_version >> 8, si.si_os_version & 0xff)
168 if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
169 si.si_os_version & 0xff, si.si_os_version >> 8)
176 m = cdf_file_property_info(ms, info, count);
183 file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
188 cdf_stream_t sst, scn;
194 if (ms->flags & MAGIC_APPLE)
196 if (cdf_read_header(fd, &h) == -1)
202 if (cdf_read_sat(fd, &h, &sat) == -1) {
203 file_error(ms, errno, "Can't read SAT");
207 cdf_dump_sat("SAT", &h, &sat);
210 if ((i = cdf_read_ssat(fd, &h, &sat, &ssat)) == -1) {
211 file_error(ms, errno, "Can't read SAT");
215 cdf_dump_sat("SSAT", &h, &ssat);
218 if ((i = cdf_read_dir(fd, &h, &sat, &dir)) == -1) {
219 file_error(ms, errno, "Can't read directory");
223 if ((i = cdf_read_short_stream(fd, &h, &sat, &dir, &sst)) == -1) {
224 file_error(ms, errno, "Cannot read short stream");
229 cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir);
231 if ((i = cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir, &scn))
233 /* Some files don't have summary info! */
235 file_error(ms, errno, "Can't read summary_info");
242 cdf_dump_summary_info(&h, &scn);
244 if ((i = cdf_file_summary_info(ms, &scn)) == -1)
245 file_error(ms, errno, "Can't expand summary_info");