diff options
Diffstat (limited to 'src/plugins/old/applefile_extractor.c')
-rw-r--r-- | src/plugins/old/applefile_extractor.c | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/src/plugins/old/applefile_extractor.c b/src/plugins/old/applefile_extractor.c new file mode 100644 index 0000000..704bda6 --- /dev/null +++ b/src/plugins/old/applefile_extractor.c | |||
@@ -0,0 +1,250 @@ | |||
1 | /* | ||
2 | This file is part of libextractor. | ||
3 | Copyright (C) 2008 Heikki Lindholm | ||
4 | |||
5 | libextractor is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | libextractor is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with libextractor; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * handles AppleSingle and AppleDouble header files | ||
23 | * see RFC 1740 | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "extractor.h" | ||
27 | #include "pack.h" | ||
28 | |||
29 | #define DEBUG 0 | ||
30 | |||
31 | #define APPLESINGLE_SIGNATURE "\x00\x05\x16\x00" | ||
32 | #define APPLEDOUBLE_SIGNATURE "\x00\x05\x16\x07" | ||
33 | |||
34 | typedef struct | ||
35 | { | ||
36 | unsigned char magic[4]; | ||
37 | unsigned int version; | ||
38 | char homeFileSystem[16]; /* v1: in ASCII v2: zero filler */ | ||
39 | unsigned short entries; | ||
40 | } ApplefileHeader; | ||
41 | |||
42 | #define APPLEFILE_HEADER_SIZE 26 | ||
43 | #define APPLEFILE_HEADER_SPEC "4bW16bH" | ||
44 | #define APPLEFILE_HEADER_FIELDS(p) \ | ||
45 | &(p)->magic, \ | ||
46 | &(p)->version, \ | ||
47 | &(p)->homeFileSystem, \ | ||
48 | &(p)->entries | ||
49 | |||
50 | typedef struct | ||
51 | { | ||
52 | unsigned int id; | ||
53 | unsigned int offset; | ||
54 | unsigned int length; | ||
55 | } ApplefileEntryDescriptor; | ||
56 | |||
57 | #define APPLEFILE_ENTRY_DESCRIPTOR_SIZE 12 | ||
58 | #define APPLEFILE_ENTRY_DESCRIPTOR_SPEC "WWW" | ||
59 | #define APPLEFILE_ENTRY_DESCRIPTOR_FIELDS(p) \ | ||
60 | &(p)->id, \ | ||
61 | &(p)->offset, \ | ||
62 | &(p)->length | ||
63 | |||
64 | #define AED_ID_DATA_FORK 1 | ||
65 | #define AED_ID_RESOURCE_FORK 2 | ||
66 | #define AED_ID_REAL_NAME 3 | ||
67 | #define AED_ID_COMMENT 4 | ||
68 | #define AED_ID_ICON_BW 5 | ||
69 | #define AED_ID_ICON_COLOUR 6 | ||
70 | #define AED_ID_FILE_DATES_INFO 8 | ||
71 | #define AED_ID_FINDER_INFO 9 | ||
72 | #define AED_ID_MACINTOSH_FILE_INFO 10 | ||
73 | #define AED_ID_PRODOS_FILE_INFO 11 | ||
74 | #define AED_ID_MSDOS_FILE_INFO 12 | ||
75 | #define AED_ID_SHORT_NAME 13 | ||
76 | #define AED_ID_AFP_FILE_INFO 14 | ||
77 | #define AED_ID_DIRECTORY_ID 15 | ||
78 | |||
79 | static int readApplefileHeader(const unsigned char *data, | ||
80 | size_t *offset, | ||
81 | size_t size, | ||
82 | ApplefileHeader *hdr) | ||
83 | { | ||
84 | if ((*offset + APPLEFILE_HEADER_SIZE) > size) | ||
85 | return -1; | ||
86 | |||
87 | EXTRACTOR_common_cat_unpack(data + *offset, | ||
88 | APPLEFILE_HEADER_SPEC, | ||
89 | APPLEFILE_HEADER_FIELDS(hdr)); | ||
90 | *offset += APPLEFILE_HEADER_SIZE; | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int readEntryDescriptor(const unsigned char *data, | ||
95 | size_t *offset, | ||
96 | size_t size, | ||
97 | ApplefileEntryDescriptor *dsc) | ||
98 | { | ||
99 | if ((*offset + APPLEFILE_ENTRY_DESCRIPTOR_SIZE) > size) | ||
100 | return -1; | ||
101 | |||
102 | EXTRACTOR_common_cat_unpack(data + *offset, | ||
103 | APPLEFILE_ENTRY_DESCRIPTOR_SPEC, | ||
104 | APPLEFILE_ENTRY_DESCRIPTOR_FIELDS(dsc)); | ||
105 | *offset += APPLEFILE_ENTRY_DESCRIPTOR_SIZE; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | /* mimetype = application/applefile */ | ||
110 | int | ||
111 | EXTRACTOR_applefile_extract (const char *sdata, | ||
112 | size_t size, | ||
113 | EXTRACTOR_MetaDataProcessor proc, | ||
114 | void *proc_cls, | ||
115 | const char *options) | ||
116 | { | ||
117 | const unsigned char *data = (const unsigned char*) sdata; | ||
118 | size_t offset; | ||
119 | ApplefileHeader header; | ||
120 | ApplefileEntryDescriptor dsc; | ||
121 | int i; | ||
122 | |||
123 | offset = 0; | ||
124 | if (readApplefileHeader(data, &offset, size, &header) == -1) | ||
125 | return 0; | ||
126 | if ( (memcmp(header.magic, APPLESINGLE_SIGNATURE, 4) != 0) && | ||
127 | (memcmp(header.magic, APPLEDOUBLE_SIGNATURE, 4) != 0) ) | ||
128 | return 0; | ||
129 | if (0 != proc (proc_cls, | ||
130 | "applefile", | ||
131 | EXTRACTOR_METATYPE_MIMETYPE, | ||
132 | EXTRACTOR_METAFORMAT_UTF8, | ||
133 | "text/plain", | ||
134 | "application/applefile", | ||
135 | strlen ("application/applefile")+1)) | ||
136 | return 1; | ||
137 | #if DEBUG | ||
138 | fprintf(stderr, | ||
139 | "applefile header: %08x %d\n", header.version, header.entries); | ||
140 | #endif | ||
141 | if ( (header.version != 0x00010000) && | ||
142 | (header.version != 0x00020000) ) | ||
143 | return 0; | ||
144 | |||
145 | for (i = 0; i < header.entries; i++) { | ||
146 | if (readEntryDescriptor(data, &offset, size, &dsc) == -1) | ||
147 | break; | ||
148 | |||
149 | #if DEBUG | ||
150 | fprintf(stderr, | ||
151 | "applefile entry: %u %u %u\n", dsc.id, dsc.offset, dsc.length); | ||
152 | #endif | ||
153 | switch (dsc.id) | ||
154 | { | ||
155 | case AED_ID_DATA_FORK: | ||
156 | { | ||
157 | /* same as in filenameextractor.c */ | ||
158 | char s[14]; | ||
159 | |||
160 | if (dsc.length >= 1000000000) | ||
161 | snprintf (s, 13, "%.2f %s", dsc.length / 1000000000.0, | ||
162 | _("GB")); | ||
163 | else if (dsc.length >= 1000000) | ||
164 | snprintf (s, 13, "%.2f %s", dsc.length / 1000000.0, _("MB")); | ||
165 | else if (dsc.length >= 1000) | ||
166 | snprintf (s, 13, "%.2f %s", dsc.length / 1000.0, _("KB")); | ||
167 | else | ||
168 | snprintf (s, 13, "%.2f %s", (double) dsc.length, _("Bytes")); | ||
169 | |||
170 | if (0 != proc (proc_cls, | ||
171 | "applefile", | ||
172 | EXTRACTOR_METATYPE_EMBEDDED_FILE_SIZE, | ||
173 | EXTRACTOR_METAFORMAT_UTF8, | ||
174 | "text/plain", | ||
175 | s, | ||
176 | strlen (s) + 1)) | ||
177 | return 1; | ||
178 | } | ||
179 | break; | ||
180 | case AED_ID_REAL_NAME: | ||
181 | { | ||
182 | char s[2048]; | ||
183 | if ( (dsc.length < sizeof(s)) && | ||
184 | ((dsc.offset + dsc.length) < size) ) { | ||
185 | memcpy(s, data + dsc.offset, dsc.length); | ||
186 | s[dsc.length] = '\0'; | ||
187 | if (0 != proc (proc_cls, | ||
188 | "applefile", | ||
189 | EXTRACTOR_METATYPE_FILENAME, | ||
190 | EXTRACTOR_METAFORMAT_UTF8, | ||
191 | "text/plain", | ||
192 | s, | ||
193 | dsc.length + 1)) | ||
194 | return 1; | ||
195 | } | ||
196 | } | ||
197 | break; | ||
198 | case AED_ID_COMMENT: | ||
199 | if ( (dsc.length < 65536) && ((dsc.offset + dsc.length) < size) ) { | ||
200 | char *s = malloc(dsc.length + 1); | ||
201 | if (s != NULL) { | ||
202 | memcpy(s, data + dsc.offset, dsc.length); | ||
203 | s[dsc.length] = '\0'; | ||
204 | if (0 != proc (proc_cls, | ||
205 | "applefile", | ||
206 | EXTRACTOR_METATYPE_COMMENT, | ||
207 | EXTRACTOR_METAFORMAT_UTF8, | ||
208 | "text/plain", | ||
209 | s, | ||
210 | dsc.length + 1)) | ||
211 | { | ||
212 | free (s); | ||
213 | return 1; | ||
214 | } | ||
215 | free (s); | ||
216 | } | ||
217 | } | ||
218 | break; | ||
219 | case AED_ID_FINDER_INFO: | ||
220 | if (dsc.length >= 16 && (dsc.offset + dsc.length) < size) { | ||
221 | char s[5]; | ||
222 | memcpy(s, data + dsc.offset, 4); | ||
223 | s[4] = '\0'; | ||
224 | if (0 != proc (proc_cls, | ||
225 | "applefile", | ||
226 | EXTRACTOR_METATYPE_FINDER_FILE_TYPE, | ||
227 | EXTRACTOR_METAFORMAT_C_STRING, | ||
228 | "text/plain", | ||
229 | s, | ||
230 | strlen(s) + 1)) | ||
231 | return 1; | ||
232 | |||
233 | memcpy(s, data + dsc.offset + 4, 4); | ||
234 | s[4] = '\0'; | ||
235 | if (0 != proc (proc_cls, | ||
236 | "applefile", | ||
237 | EXTRACTOR_METATYPE_FINDER_FILE_CREATOR, | ||
238 | EXTRACTOR_METAFORMAT_C_STRING, | ||
239 | "text/plain", | ||
240 | s, | ||
241 | strlen(s) + 1)) | ||
242 | return 1; | ||
243 | } | ||
244 | break; | ||
245 | default: | ||
246 | break; | ||
247 | } | ||
248 | } | ||
249 | return 0; | ||
250 | } | ||