libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

commit acc6fb889222ce91c2a89545dd82fc27fe9beb81
parent 156632118d2c358a687acc0e2f915cea5d02ab32
Author: Heikki Lindholm <holin@iki.fi>
Date:   Wed, 13 Feb 2008 08:24:18 +0000

add AppleSingle/AppleDouble plugin


Diffstat:
MAUTHORS | 1+
MChangeLog | 3+++
MNEWS | 3+++
Msrc/main/extractor.c | 1+
Msrc/plugins/Makefile.am | 8++++++++
Msrc/plugins/SYMBOLS | 1+
Asrc/plugins/applefileextractor.c | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/plugins/mimeextractor.c | 2++
8 files changed, 205 insertions(+), 0 deletions(-)

diff --git a/AUTHORS b/AUTHORS @@ -39,6 +39,7 @@ word - Ariya Hidayat <ariya@kde.org> and Sacha Fuentes <mandelman@iname nsf - Toni Ruottu <toni.ruottu@iki.fi> sid - Toni Ruottu <toni.ruottu@iki.fi> nsfe - Toni Ruottu <toni.ruottu@iki.fi> +applefile - Heikki Lindholm General contributors: Yuri N. Sedunov <aris@altlinux.ru> diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,6 @@ +Wed Feb 13 10:16:55 EET 2008 + Added a plugin for AppleSingle/AppleDouble files. + Mon Feb 11 22:58:48 MST 2008 Various minor code cleanups. diff --git a/NEWS b/NEWS @@ -1,3 +1,6 @@ +Wed Feb 13 10:16:55 EET 2008 + Added a plugin for AppleSingle/AppleDouble files. + Wed Dec 26 19:38:22 MST 2007 Added a FLAC (.flac) plugin. diff --git a/src/main/extractor.c b/src/main/extractor.c @@ -251,6 +251,7 @@ libextractor_tiff:\ libextractor_zip:\ libextractor_rpm:\ libextractor_riff:\ +libextractor_applefile:\ libextractor_elf:\ libextractor_oo:\ libextractor_asf:\ diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am @@ -73,6 +73,7 @@ oodir = oo endif plugin_LTLIBRARIES = $(pdfplugin) \ + libextractor_applefile.la \ libextractor_asf.la \ libextractor_deb.la \ libextractor_dvi.la \ @@ -221,6 +222,13 @@ libextractor_tiff_la_LDFLAGS = \ libextractor_tiff_la_LIBADD = \ libpack.la +libextractor_applefile_la_SOURCES = \ + applefileextractor.c +libextractor_applefile_la_LDFLAGS = \ + $(PLUGINFLAGS) $(retaincommand) +libextractor_applefile_la_LIBADD = \ + libpack.la + libextractor_elf_la_SOURCES = \ elfextractor.c libextractor_elf_la_LDFLAGS = \ diff --git a/src/plugins/SYMBOLS b/src/plugins/SYMBOLS @@ -1,3 +1,4 @@ +libextractor_applefile_extract libextractor_asf_extract libextractor_deb_extract libextractor_dvi_extract diff --git a/src/plugins/applefileextractor.c b/src/plugins/applefileextractor.c @@ -0,0 +1,186 @@ +/* + This file is part of libextractor. + Copyright (C) 2007 Heikki Lindholm + + libextractor is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + libextractor is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libextractor; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/* + * handles AppleSingle and AppleDouble header files + * see RFC 1740 + */ +#include "platform.h" +#include "extractor.h" +#include "pack.h" + +#define DEBUG 0 + +#define APPLESINGLE_SIGNATURE "\x00\x05\x16\x00" +#define APPLEDOUBLE_SIGNATURE "\x00\x05\x16\x07" + +static struct EXTRACTOR_Keywords * +addKeyword (EXTRACTOR_KeywordType type, + char *keyword, struct EXTRACTOR_Keywords *next) +{ + EXTRACTOR_KeywordList *result; + + if (keyword == NULL) + return next; + result = malloc (sizeof (EXTRACTOR_KeywordList)); + result->next = next; + result->keyword = keyword; + result->keywordType = type; + return result; +} + +typedef struct +{ + unsigned char magic[4]; + unsigned int version; + char homeFileSystem[16]; /* v1: in ASCII v2: zero filler */ + unsigned short entries; +} ApplefileHeader; + +#define APPLEFILE_HEADER_SIZE 26 +#define APPLEFILE_HEADER_SPEC "4bW16bH" +#define APPLEFILE_HEADER_FIELDS(p) \ + &(p)->magic, \ + &(p)->version, \ + &(p)->homeFileSystem, \ + &(p)->entries + +typedef struct +{ + unsigned int id; + unsigned int offset; + unsigned int length; +} ApplefileEntryDescriptor; + +#define APPLEFILE_ENTRY_DESCRIPTOR_SIZE 12 +#define APPLEFILE_ENTRY_DESCRIPTOR_SPEC "WWW" +#define APPLEFILE_ENTRY_DESCRIPTOR_FIELDS(p) \ + &(p)->id, \ + &(p)->offset, \ + &(p)->length + +#define AED_ID_DATA_FORK 1 +#define AED_ID_RESOURCE_FORK 2 +#define AED_ID_REAL_NAME 3 +#define AED_ID_COMMENT 4 +#define AED_ID_ICON_BW 5 +#define AED_ID_ICON_COLOUR 6 +#define AED_ID_FILE_DATES_INFO 8 +#define AED_ID_FINDER_INFO 9 +#define AED_ID_MACINTOSH_FILE_INFO 10 +#define AED_ID_PRODOS_FILE_INFO 11 +#define AED_ID_MSDOS_FILE_INFO 12 +#define AED_ID_SHORT_NAME 13 +#define AED_ID_AFP_FILE_INFO 14 +#define AED_ID_DIRECTORY_ID 15 + +static int readApplefileHeader(const unsigned char *data, + size_t *offset, + size_t size, + ApplefileHeader *hdr) +{ + if ((*offset + APPLEFILE_HEADER_SIZE) > size) + return -1; + + cat_unpack(data + *offset, + APPLEFILE_HEADER_SPEC, + APPLEFILE_HEADER_FIELDS(hdr)); + *offset += APPLEFILE_HEADER_SIZE; + return 0; +} + +static int readEntryDescriptor(const unsigned char *data, + size_t *offset, + size_t size, + ApplefileEntryDescriptor *dsc) +{ + if ((*offset + APPLEFILE_ENTRY_DESCRIPTOR_SIZE) > size) + return -1; + + cat_unpack(data + *offset, + APPLEFILE_ENTRY_DESCRIPTOR_SPEC, + APPLEFILE_ENTRY_DESCRIPTOR_FIELDS(dsc)); + *offset += APPLEFILE_ENTRY_DESCRIPTOR_SIZE; + return 0; +} + +struct EXTRACTOR_Keywords * +libextractor_applefile_extract (const char *filename, + const unsigned char *data, + const size_t size, struct EXTRACTOR_Keywords *prev) +{ + struct EXTRACTOR_Keywords *result; + size_t offset; + ApplefileHeader header; + ApplefileEntryDescriptor dsc; + int i; + + offset = 0; + + if (readApplefileHeader(data, &offset, size, &header) == -1) + return prev; + + if ((memcmp(header.magic, APPLESINGLE_SIGNATURE, 4) != 0) && + (memcmp(header.magic, APPLEDOUBLE_SIGNATURE, 4) != 0)) + return prev; + + result = prev; + result = addKeyword (EXTRACTOR_MIMETYPE, + strdup ("application/applefile"), + result); + +#if DEBUG + printf("applefile header: %08x %d\n", header.version, header.entries); +#endif + if (header.version != 0x00010000 && header.version != 0x00020000) + return result; + + for (i = 0; i < header.entries; i++) { + if (readEntryDescriptor(data, &offset, size, &dsc) == -1) + break; + + switch (dsc.id) { + case AED_ID_REAL_NAME: + if (dsc.length < 2048 && dsc.offset + dsc.length < size) { + char *s = malloc(dsc.length + 1); + if (s != NULL) { + memcpy(s, data + dsc.offset, dsc.length); + s[dsc.length] = '\0'; + result = addKeyword(EXTRACTOR_FILENAME, s, result); + } + } + break; + case AED_ID_COMMENT: + if (dsc.length < 65536 && dsc.offset + dsc.length < size) { + char *s = malloc(dsc.length + 1); + if (s != NULL) { + memcpy(s, data + dsc.offset, dsc.length); + s[dsc.length] = '\0'; + result = addKeyword(EXTRACTOR_COMMENT, s, result); + } + } + break; + default: + break; + } + } + + return result; +} diff --git a/src/plugins/mimeextractor.c b/src/plugins/mimeextractor.c @@ -222,6 +222,8 @@ static Pattern patterns[] = { {"CWS", 3, "application/x-shockwave-flash", DEFAULT}, {"\x2E\x52\x4d\x46", 4, "video/real", DEFAULT}, {"\x2e\x72\x61\xfd", 4, "audio/real", DEFAULT}, + {"\x00\x05\x16\x00", 4, "application/applefile", DEFAULT}, + {"\x00\x05\x16\x07", 4, "application/applefile", DEFAULT}, {"\177ELF", 4, "application/elf", DEFAULT}, /* FIXME: correct MIME-type for an ELF!? */ {"\xca\xfe\xba\xbe", 4, "application/java", DEFAULT},