aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/old/applefile_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/old/applefile_extractor.c')
-rw-r--r--src/plugins/old/applefile_extractor.c250
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
34typedef 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
50typedef 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
79static 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
94static 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 */
110int
111EXTRACTOR_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}