No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / file / dist / src / readcdf.c
blobf84ff8405690bd81954fbc425bf2949a5ea5593c
1 /* $NetBSD: readcdf.c,v 1.1.1.1 2009/05/08 16:35:06 christos Exp $ */
3 /*-
4 * Copyright (c) 2008 Christos Zoulas
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
28 #include "file.h"
30 #ifndef lint
31 #if 0
32 FILE_RCSID("@(#)$File: readcdf.c,v 1.18 2009/05/06 20:48:22 christos Exp $")
33 #else
34 __RCSID("$NetBSD: readcdf.c,v 1.1.1.1 2009/05/08 16:35:06 christos Exp $");
35 #endif
36 #endif
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <string.h>
41 #include <time.h>
42 #include <ctype.h>
44 #include "cdf.h"
45 #include "magic.h"
47 #define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0)
49 private int
50 cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
51 size_t count)
53 size_t i;
54 cdf_timestamp_t tp;
55 struct timespec ts;
56 char buf[64];
57 const char *str = "vnd.ms-office";
58 const char *s;
59 int len;
61 for (i = 0; i < count; i++) {
62 cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
63 switch (info[i].pi_type) {
64 case CDF_SIGNED16:
65 if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
66 info[i].pi_s16) == -1)
67 return -1;
68 break;
69 case CDF_SIGNED32:
70 if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
71 info[i].pi_s32) == -1)
72 return -1;
73 break;
74 case CDF_UNSIGNED32:
75 if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
76 info[i].pi_u32) == -1)
77 return -1;
78 break;
79 case CDF_LENGTH32_STRING:
80 len = info[i].pi_str.s_len;
81 if (len > 1) {
82 s = info[i].pi_str.s_buf;
83 if (NOTMIME(ms)) {
84 char vbuf[1024];
85 size_t j;
86 for (j = 0; j < sizeof(vbuf) && len--;
87 j++, s++) {
88 if (*s == '\0')
89 break;
90 if (isprint((unsigned char)*s))
91 vbuf[j] = *s;
93 if (j == sizeof(vbuf))
94 --j;
95 vbuf[j] = '\0';
96 if (vbuf[0]) {
97 if (file_printf(ms, ", %s: %s",
98 buf, vbuf) == -1)
99 return -1;
101 } else if (info[i].pi_id ==
102 CDF_PROPERTY_NAME_OF_APPLICATION) {
103 if (strstr(s, "Word"))
104 str = "msword";
105 else if (strstr(s, "Excel"))
106 str = "vnd.ms-excel";
107 else if (strstr(s, "Powerpoint"))
108 str = "vnd.ms-powerpoint";
111 break;
112 case CDF_FILETIME:
113 tp = info[i].pi_tp;
114 if (tp != 0) {
115 if (tp < 1000000000000000LL) {
116 char tbuf[64];
117 cdf_print_elapsed_time(tbuf,
118 sizeof(tbuf), tp);
119 if (NOTMIME(ms) && file_printf(ms,
120 ", %s: %s", buf, tbuf) == -1)
121 return -1;
122 } else {
123 char *c, *ec;
124 cdf_timestamp_to_timespec(&ts, tp);
125 c = ctime(&ts.tv_sec);
126 if ((ec = strchr(c, '\n')) != NULL)
127 *ec = '\0';
129 if (NOTMIME(ms) && file_printf(ms,
130 ", %s: %s", buf, c) == -1)
131 return -1;
134 break;
135 case CDF_CLIPBOARD:
136 break;
137 default:
138 return -1;
141 if (!NOTMIME(ms)) {
142 if (file_printf(ms, "application/%s", str) == -1)
143 return -1;
145 return 1;
148 private int
149 cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst)
151 cdf_summary_info_header_t si;
152 cdf_property_info_t *info;
153 size_t count;
154 int m;
156 if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1)
157 return -1;
159 if (NOTMIME(ms)) {
160 if (file_printf(ms, "CDF V2 Document") == -1)
161 return -1;
163 if (file_printf(ms, ", %s Endian",
164 si.si_byte_order == 0xfffe ? "Little" : "Big") == -1)
165 return -1;
166 switch (si.si_os) {
167 case 2:
168 if (file_printf(ms, ", Os: Windows, Version %d.%d",
169 si.si_os_version & 0xff,
170 (uint32_t)si.si_os_version >> 8) == -1)
171 return -1;
172 break;
173 case 1:
174 if (file_printf(ms, ", Os: MacOS, Version %d.%d",
175 (uint32_t)si.si_os_version >> 8,
176 si.si_os_version & 0xff) == -1)
177 return -1;
178 break;
179 default:
180 if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
181 si.si_os_version & 0xff,
182 (uint32_t)si.si_os_version >> 8) == -1)
183 return -1;
184 break;
188 m = cdf_file_property_info(ms, info, count);
189 free(info);
191 return m;
194 protected int
195 file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
196 size_t nbytes)
198 cdf_info_t info;
199 cdf_header_t h;
200 cdf_sat_t sat, ssat;
201 cdf_stream_t sst, scn;
202 cdf_dir_t dir;
203 int i;
204 const char *expn = "";
206 info.i_fd = fd;
207 info.i_buf = buf;
208 info.i_len = nbytes;
209 if (ms->flags & MAGIC_APPLE)
210 return 0;
211 if (cdf_read_header(&info, &h) == -1)
212 return 0;
213 #ifdef CDF_DEBUG
214 cdf_dump_header(&h);
215 #endif
217 if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
218 expn = "Can't read SAT";
219 goto out0;
221 #ifdef CDF_DEBUG
222 cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
223 #endif
225 if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
226 expn = "Can't read SSAT";
227 goto out1;
229 #ifdef CDF_DEBUG
230 cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
231 #endif
233 if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
234 expn = "Can't read directory";
235 goto out2;
238 if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) {
239 expn = "Cannot read short stream";
240 goto out3;
242 #ifdef CDF_DEBUG
243 cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
244 #endif
246 if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
247 &scn)) == -1) {
248 expn = "Cannot read summary info";
249 goto out4;
251 #ifdef CDF_DEBUG
252 cdf_dump_summary_info(&h, &scn);
253 #endif
254 if ((i = cdf_file_summary_info(ms, &scn)) == -1)
255 expn = "Can't expand summary_info";
256 free(scn.sst_tab);
257 out4:
258 free(sst.sst_tab);
259 out3:
260 free(dir.dir_tab);
261 out2:
262 free(ssat.sat_tab);
263 out1:
264 free(sat.sat_tab);
265 out0:
266 if (i != 1) {
267 if (file_printf(ms, "CDF V2 Document") == -1)
268 return -1;
269 if (*expn)
270 if (file_printf(ms, ", corrupt: %s", expn) == -1)
271 return -1;
272 i = 1;
274 return i;