diff options
Diffstat (limited to 'src/plugins/old/applefile_extractor.c')
-rw-r--r-- | src/plugins/old/applefile_extractor.c | 267 |
1 files changed, 138 insertions, 129 deletions
diff --git a/src/plugins/old/applefile_extractor.c b/src/plugins/old/applefile_extractor.c index cc82dc8..dcaf7d0 100644 --- a/src/plugins/old/applefile_extractor.c +++ b/src/plugins/old/applefile_extractor.c | |||
@@ -42,10 +42,10 @@ typedef struct | |||
42 | #define APPLEFILE_HEADER_SIZE 26 | 42 | #define APPLEFILE_HEADER_SIZE 26 |
43 | #define APPLEFILE_HEADER_SPEC "4bW16bH" | 43 | #define APPLEFILE_HEADER_SPEC "4bW16bH" |
44 | #define APPLEFILE_HEADER_FIELDS(p) \ | 44 | #define APPLEFILE_HEADER_FIELDS(p) \ |
45 | &(p)->magic, \ | 45 | & (p)->magic, \ |
46 | &(p)->version, \ | 46 | &(p)->version, \ |
47 | &(p)->homeFileSystem, \ | 47 | &(p)->homeFileSystem, \ |
48 | &(p)->entries | 48 | &(p)->entries |
49 | 49 | ||
50 | typedef struct | 50 | typedef struct |
51 | { | 51 | { |
@@ -57,9 +57,9 @@ typedef struct | |||
57 | #define APPLEFILE_ENTRY_DESCRIPTOR_SIZE 12 | 57 | #define APPLEFILE_ENTRY_DESCRIPTOR_SIZE 12 |
58 | #define APPLEFILE_ENTRY_DESCRIPTOR_SPEC "WWW" | 58 | #define APPLEFILE_ENTRY_DESCRIPTOR_SPEC "WWW" |
59 | #define APPLEFILE_ENTRY_DESCRIPTOR_FIELDS(p) \ | 59 | #define APPLEFILE_ENTRY_DESCRIPTOR_FIELDS(p) \ |
60 | &(p)->id, \ | 60 | & (p)->id, \ |
61 | &(p)->offset, \ | 61 | &(p)->offset, \ |
62 | &(p)->length | 62 | &(p)->length |
63 | 63 | ||
64 | #define AED_ID_DATA_FORK 1 | 64 | #define AED_ID_DATA_FORK 1 |
65 | #define AED_ID_RESOURCE_FORK 2 | 65 | #define AED_ID_RESOURCE_FORK 2 |
@@ -76,43 +76,47 @@ typedef struct | |||
76 | #define AED_ID_AFP_FILE_INFO 14 | 76 | #define AED_ID_AFP_FILE_INFO 14 |
77 | #define AED_ID_DIRECTORY_ID 15 | 77 | #define AED_ID_DIRECTORY_ID 15 |
78 | 78 | ||
79 | static int readApplefileHeader(const unsigned char *data, | 79 | static int |
80 | size_t *offset, | 80 | readApplefileHeader (const unsigned char *data, |
81 | size_t size, | 81 | size_t *offset, |
82 | ApplefileHeader *hdr) | 82 | size_t size, |
83 | ApplefileHeader *hdr) | ||
83 | { | 84 | { |
84 | if ((*offset + APPLEFILE_HEADER_SIZE) > size) | 85 | if ((*offset + APPLEFILE_HEADER_SIZE) > size) |
85 | return -1; | 86 | return -1; |
86 | 87 | ||
87 | EXTRACTOR_common_cat_unpack(data + *offset, | 88 | EXTRACTOR_common_cat_unpack (data + *offset, |
88 | APPLEFILE_HEADER_SPEC, | 89 | APPLEFILE_HEADER_SPEC, |
89 | APPLEFILE_HEADER_FIELDS(hdr)); | 90 | APPLEFILE_HEADER_FIELDS (hdr)); |
90 | *offset += APPLEFILE_HEADER_SIZE; | 91 | *offset += APPLEFILE_HEADER_SIZE; |
91 | return 0; | 92 | return 0; |
92 | } | 93 | } |
93 | 94 | ||
94 | static int readEntryDescriptor(const unsigned char *data, | 95 | |
95 | size_t *offset, | 96 | static int |
96 | size_t size, | 97 | readEntryDescriptor (const unsigned char *data, |
97 | ApplefileEntryDescriptor *dsc) | 98 | size_t *offset, |
99 | size_t size, | ||
100 | ApplefileEntryDescriptor *dsc) | ||
98 | { | 101 | { |
99 | if ((*offset + APPLEFILE_ENTRY_DESCRIPTOR_SIZE) > size) | 102 | if ((*offset + APPLEFILE_ENTRY_DESCRIPTOR_SIZE) > size) |
100 | return -1; | 103 | return -1; |
101 | 104 | ||
102 | EXTRACTOR_common_cat_unpack(data + *offset, | 105 | EXTRACTOR_common_cat_unpack (data + *offset, |
103 | APPLEFILE_ENTRY_DESCRIPTOR_SPEC, | 106 | APPLEFILE_ENTRY_DESCRIPTOR_SPEC, |
104 | APPLEFILE_ENTRY_DESCRIPTOR_FIELDS(dsc)); | 107 | APPLEFILE_ENTRY_DESCRIPTOR_FIELDS (dsc)); |
105 | *offset += APPLEFILE_ENTRY_DESCRIPTOR_SIZE; | 108 | *offset += APPLEFILE_ENTRY_DESCRIPTOR_SIZE; |
106 | return 0; | 109 | return 0; |
107 | } | 110 | } |
108 | 111 | ||
112 | |||
109 | /* mimetype = application/applefile */ | 113 | /* mimetype = application/applefile */ |
110 | int | 114 | int |
111 | EXTRACTOR_applefile_extract (const char *sdata, | 115 | EXTRACTOR_applefile_extract (const char *sdata, |
112 | size_t size, | 116 | size_t size, |
113 | EXTRACTOR_MetaDataProcessor proc, | 117 | EXTRACTOR_MetaDataProcessor proc, |
114 | void *proc_cls, | 118 | void *proc_cls, |
115 | const char *options) | 119 | const char *options) |
116 | { | 120 | { |
117 | const unsigned char *data = (const unsigned char*) sdata; | 121 | const unsigned char *data = (const unsigned char*) sdata; |
118 | size_t offset; | 122 | size_t offset; |
@@ -121,129 +125,134 @@ EXTRACTOR_applefile_extract (const char *sdata, | |||
121 | int i; | 125 | int i; |
122 | 126 | ||
123 | offset = 0; | 127 | offset = 0; |
124 | if (readApplefileHeader(data, &offset, size, &header) == -1) | 128 | if (readApplefileHeader (data, &offset, size, &header) == -1) |
125 | return 0; | 129 | return 0; |
126 | if ( (memcmp(header.magic, APPLESINGLE_SIGNATURE, 4) != 0) && | 130 | if ( (memcmp (header.magic, APPLESINGLE_SIGNATURE, 4) != 0) && |
127 | (memcmp(header.magic, APPLEDOUBLE_SIGNATURE, 4) != 0) ) | 131 | (memcmp (header.magic, APPLEDOUBLE_SIGNATURE, 4) != 0) ) |
128 | return 0; | 132 | return 0; |
129 | if (0 != proc (proc_cls, | 133 | if (0 != proc (proc_cls, |
130 | "applefile", | 134 | "applefile", |
131 | EXTRACTOR_METATYPE_MIMETYPE, | 135 | EXTRACTOR_METATYPE_MIMETYPE, |
132 | EXTRACTOR_METAFORMAT_UTF8, | 136 | EXTRACTOR_METAFORMAT_UTF8, |
133 | "text/plain", | 137 | "text/plain", |
134 | "application/applefile", | 138 | "application/applefile", |
135 | strlen ("application/applefile")+1)) | 139 | strlen ("application/applefile") + 1)) |
136 | return 1; | 140 | return 1; |
137 | #if DEBUG | 141 | #if DEBUG |
138 | fprintf(stderr, | 142 | fprintf (stderr, |
139 | "applefile header: %08x %d\n", header.version, header.entries); | 143 | "applefile header: %08x %d\n", header.version, header.entries); |
140 | #endif | 144 | #endif |
141 | if ( (header.version != 0x00010000) && | 145 | if ( (header.version != 0x00010000) && |
142 | (header.version != 0x00020000) ) | 146 | (header.version != 0x00020000) ) |
143 | return 0; | 147 | return 0; |
144 | 148 | ||
145 | for (i = 0; i < header.entries; i++) { | 149 | for (i = 0; i < header.entries; i++) |
146 | if (readEntryDescriptor(data, &offset, size, &dsc) == -1) | 150 | { |
151 | if (readEntryDescriptor (data, &offset, size, &dsc) == -1) | ||
147 | break; | 152 | break; |
148 | 153 | ||
149 | #if DEBUG | 154 | #if DEBUG |
150 | fprintf(stderr, | 155 | fprintf (stderr, |
151 | "applefile entry: %u %u %u\n", dsc.id, dsc.offset, dsc.length); | 156 | "applefile entry: %u %u %u\n", dsc.id, dsc.offset, dsc.length); |
152 | #endif | 157 | #endif |
153 | switch (dsc.id) | 158 | switch (dsc.id) |
159 | { | ||
160 | case AED_ID_DATA_FORK: | ||
154 | { | 161 | { |
155 | case AED_ID_DATA_FORK: | 162 | /* same as in filenameextractor.c */ |
156 | { | 163 | char s[14]; |
157 | /* same as in filenameextractor.c */ | ||
158 | char s[14]; | ||
159 | 164 | ||
160 | if (dsc.length >= 1000000000) | 165 | if (dsc.length >= 1000000000) |
161 | snprintf (s, 13, "%.2f %s", dsc.length / 1000000000.0, | 166 | snprintf (s, 13, "%.2f %s", dsc.length / 1000000000.0, |
162 | _("GB")); | 167 | _ ("GB")); |
163 | else if (dsc.length >= 1000000) | 168 | else if (dsc.length >= 1000000) |
164 | snprintf (s, 13, "%.2f %s", dsc.length / 1000000.0, _("MB")); | 169 | snprintf (s, 13, "%.2f %s", dsc.length / 1000000.0, _ ("MB")); |
165 | else if (dsc.length >= 1000) | 170 | else if (dsc.length >= 1000) |
166 | snprintf (s, 13, "%.2f %s", dsc.length / 1000.0, _("KB")); | 171 | snprintf (s, 13, "%.2f %s", dsc.length / 1000.0, _ ("KB")); |
167 | else | 172 | else |
168 | snprintf (s, 13, "%.2f %s", (double) dsc.length, _("Bytes")); | 173 | snprintf (s, 13, "%.2f %s", (double) dsc.length, _ ("Bytes")); |
169 | 174 | ||
170 | if (0 != proc (proc_cls, | 175 | if (0 != proc (proc_cls, |
171 | "applefile", | 176 | "applefile", |
172 | EXTRACTOR_METATYPE_EMBEDDED_FILE_SIZE, | 177 | EXTRACTOR_METATYPE_EMBEDDED_FILE_SIZE, |
173 | EXTRACTOR_METAFORMAT_UTF8, | 178 | EXTRACTOR_METAFORMAT_UTF8, |
174 | "text/plain", | 179 | "text/plain", |
175 | s, | 180 | s, |
176 | strlen (s) + 1)) | 181 | strlen (s) + 1)) |
177 | return 1; | 182 | return 1; |
178 | } | 183 | } |
179 | break; | 184 | break; |
180 | case AED_ID_REAL_NAME: | 185 | case AED_ID_REAL_NAME: |
181 | { | 186 | { |
182 | char s[2048]; | 187 | char s[2048]; |
183 | if ( (dsc.length < sizeof(s)) && | 188 | if ( (dsc.length < sizeof(s)) && |
184 | ((dsc.offset + dsc.length) < size) ) { | 189 | ((dsc.offset + dsc.length) < size) ) |
185 | memcpy(s, data + dsc.offset, dsc.length); | 190 | { |
186 | s[dsc.length] = '\0'; | 191 | memcpy (s, data + dsc.offset, dsc.length); |
187 | if (0 != proc (proc_cls, | 192 | s[dsc.length] = '\0'; |
188 | "applefile", | 193 | if (0 != proc (proc_cls, |
189 | EXTRACTOR_METATYPE_FILENAME, | 194 | "applefile", |
190 | EXTRACTOR_METAFORMAT_UTF8, | 195 | EXTRACTOR_METATYPE_FILENAME, |
191 | "text/plain", | 196 | EXTRACTOR_METAFORMAT_UTF8, |
192 | s, | 197 | "text/plain", |
193 | dsc.length + 1)) | 198 | s, |
194 | return 1; | 199 | dsc.length + 1)) |
195 | } | 200 | return 1; |
196 | } | 201 | } |
197 | break; | 202 | } |
198 | case AED_ID_COMMENT: | 203 | break; |
199 | if ( (dsc.length < 65536) && ((dsc.offset + dsc.length) < size) ) { | 204 | case AED_ID_COMMENT: |
200 | char *s = malloc(dsc.length + 1); | 205 | if ( (dsc.length < 65536) && ((dsc.offset + dsc.length) < size) ) |
201 | if (s != NULL) { | 206 | { |
202 | memcpy(s, data + dsc.offset, dsc.length); | 207 | char *s = malloc (dsc.length + 1); |
203 | s[dsc.length] = '\0'; | 208 | if (s != NULL) |
204 | if (0 != proc (proc_cls, | 209 | { |
205 | "applefile", | 210 | memcpy (s, data + dsc.offset, dsc.length); |
206 | EXTRACTOR_METATYPE_COMMENT, | 211 | s[dsc.length] = '\0'; |
207 | EXTRACTOR_METAFORMAT_UTF8, | 212 | if (0 != proc (proc_cls, |
208 | "text/plain", | 213 | "applefile", |
209 | s, | 214 | EXTRACTOR_METATYPE_COMMENT, |
210 | dsc.length + 1)) | 215 | EXTRACTOR_METAFORMAT_UTF8, |
211 | { | 216 | "text/plain", |
212 | free (s); | 217 | s, |
213 | return 1; | 218 | dsc.length + 1)) |
214 | } | 219 | { |
215 | free (s); | 220 | free (s); |
216 | } | 221 | return 1; |
217 | } | 222 | } |
218 | break; | 223 | free (s); |
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 | } | 224 | } |
244 | break; | 225 | } |
245 | default: | 226 | break; |
246 | break; | 227 | case AED_ID_FINDER_INFO: |
228 | if ((dsc.length >= 16) && ( (dsc.offset + dsc.length) < size) ) | ||
229 | { | ||
230 | char s[5]; | ||
231 | memcpy (s, data + dsc.offset, 4); | ||
232 | s[4] = '\0'; | ||
233 | if (0 != proc (proc_cls, | ||
234 | "applefile", | ||
235 | EXTRACTOR_METATYPE_FINDER_FILE_TYPE, | ||
236 | EXTRACTOR_METAFORMAT_C_STRING, | ||
237 | "text/plain", | ||
238 | s, | ||
239 | strlen (s) + 1)) | ||
240 | return 1; | ||
241 | |||
242 | memcpy (s, data + dsc.offset + 4, 4); | ||
243 | s[4] = '\0'; | ||
244 | if (0 != proc (proc_cls, | ||
245 | "applefile", | ||
246 | EXTRACTOR_METATYPE_FINDER_FILE_CREATOR, | ||
247 | EXTRACTOR_METAFORMAT_C_STRING, | ||
248 | "text/plain", | ||
249 | s, | ||
250 | strlen (s) + 1)) | ||
251 | return 1; | ||
252 | } | ||
253 | break; | ||
254 | default: | ||
255 | break; | ||
247 | } | 256 | } |
248 | } | 257 | } |
249 | return 0; | 258 | return 0; |