libextractor

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

commit 29afc1541aa39797fd9990c452b9f260f2ac91fa
parent 32f281a5d1ad6770e6dbffc3141d90cac6dcef34
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 14 Dec 2009 18:24:41 +0000

deb

Diffstat:
Msrc/include/extractor.h | 24++++++++++++++++++------
Msrc/main/extractor.c | 38++++++++++++++++++++++++++++++++++++--
Msrc/plugins/Makefile.am | 19++++++++-----------
Asrc/plugins/deb_extractor.c | 355+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/plugins/debextractor.c | 346-------------------------------------------------------------------------------
5 files changed, 417 insertions(+), 365 deletions(-)

diff --git a/src/include/extractor.h b/src/include/extractor.h @@ -182,19 +182,32 @@ enum EXTRACTOR_MetaType EXTRACTOR_METATYPE_EMBEDDED_FILE_SIZE = 66, EXTRACTOR_METATYPE_FINDER_FILE_TYPE = 67, EXTRACTOR_METATYPE_FINDER_FILE_CREATOR = 68, - /* FIXME... */ /* software package specifics (deb, rpm, tgz) */ - + EXTRACTOR_METATYPE_PACKAGE_NAME = 69, + EXTRACTOR_METATYPE_PACKAGE_VERSION = 70, + EXTRACTOR_METATYPE_PACKAGE_SECTION = 71, + EXTRACTOR_METATYPE_UPLOAD_PRIORITY = 72, + EXTRACTOR_METATYPE_PACKAGE_DEPENDENCY = 73, + EXTRACTOR_METATYPE_PACKAGE_CONFLICTS = 74, + EXTRACTOR_METATYPE_PACKAGE_REPLACES = 75, + EXTRACTOR_METATYPE_PACKAGE_PROVIDES = 76, + EXTRACTOR_METATYPE_PACKAGE_RECOMMENDS = 77, + EXTRACTOR_METATYPE_PACKAGE_SUGGESTS = 78, + EXTRACTOR_METATYPE_PACKAGE_MAINTAINER = 79, + EXTRACTOR_METATYPE_PACKAGE_INSTALLED_SIZE = 80, + EXTRACTOR_METATYPE_PACKAGE_SOURCE = 81, + EXTRACTOR_METATYPE_PACKAGE_ESSENTIAL = 82, + EXTRACTOR_METATYPE_TARGET_ARCHITECTURE = 83, + EXTRACTOR_METATYPE_PACKAGE_PRE_DEPENDENCY = 84, + + EXTRACTOR_METATYPE_PACKAGER = 45, EXTRACTOR_METATYPE_VENDOR = 46, EXTRACTOR_METATYPE_LICENSE = 47, EXTRACTOR_METATYPE_DISTRIBUTION = 48, EXTRACTOR_METATYPE_BUILDHOST = 49, EXTRACTOR_METATYPE_TARGET_OS = 50, - EXTRACTOR_METATYPE_DEPENDENCY = 51, - EXTRACTOR_METATYPE_CONFLICTS = 61, - EXTRACTOR_METATYPE_REPLACES = 62, EXTRACTOR_METATYPE_PROVIDES = 63, /* (text) document processing specifics */ @@ -268,7 +281,6 @@ enum EXTRACTOR_MetaType EXTRACTOR_METATYPE_DISCLAIMER = 27, EXTRACTOR_METATYPE_FULL_DATA = 137, - EXTRACTOR_METATYPE_VERSIONNUMBER = 14, EXTRACTOR_METATYPE_ORGANIZATION = 15, EXTRACTOR_METATYPE_CONTRIBUTOR = 19, diff --git a/src/main/extractor.c b/src/main/extractor.c @@ -226,8 +226,42 @@ static const struct MetaTypeDescription meta_type_descriptions[] = { gettext_noop ("standard Macintosh Finder file type information") }, { gettext_noop ("creator"), gettext_noop ("standard Macintosh Finder file creator information") }, - - + { gettext_noop ("package name"), + gettext_noop ("unique identifier for the package") }, + /* 70 */ + { gettext_noop ("package version"), + gettext_noop ("version of the software and its package") }, + { gettext_noop ("section"), + gettext_noop ("category the software package belongs to") }, + { gettext_noop ("upload priority"), + gettext_noop ("priority for promoting the release to production") }, + { gettext_noop ("dependencies"), + gettext_noop ("packages this package depends upon") }, + { gettext_noop ("conflicting packages"), + gettext_noop ("packages that cannot be installed with this package") }, + /* 75 */ + { gettext_noop ("replaced packages"), + gettext_noop ("packages made obsolete by this package") }, + { gettext_noop ("provides"), + gettext_noop ("functionality provided by this package") }, + { gettext_noop ("recommendations"), + gettext_noop ("packages recommended for installation in conjunction with this package") }, + { gettext_noop ("suggestions"), + gettext_noop ("packages suggested for installation in conjunction with this package") }, + { gettext_noop ("maintainer"), + gettext_noop ("name of the maintainer") }, + /* 80 */ + { gettext_noop ("installed size"), + gettext_noop ("space consumption after installation") }, + { gettext_noop ("source"), + gettext_noop ("original source code") }, + { gettext_noop ("is essential"), + gettext_noop ("package is marked as essential") }, + { gettext_noop ("target architecture"), + gettext_noop ("hardware architecture the package can be used for") }, + { gettext_noop ("pre-dependency"), + gettext_noop ("dependency that must be satisfied before installation") }, + /* 85 */ #if 0 gettext_noop("author"), diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am @@ -88,6 +88,7 @@ endif plugin_LTLIBRARIES = \ libextractor_applefile.la \ libextractor_asf.la \ + libextractor_deb.la \ libextractor_html.la \ libextractor_it.la \ libextractor_mime.la @@ -105,6 +106,13 @@ libextractor_asf_la_SOURCES = \ libextractor_asf_la_LDFLAGS = \ $(PLUGINFLAGS) +libextractor_deb_la_SOURCES = \ + deb_extractor.c +libextractor_deb_la_LDFLAGS = \ + $(PLUGINFLAGS) +libextractor_deb_la_LIBADD = \ + -lz + libextractor_html_la_SOURCES = \ html_extractor.c libextractor_html_la_LDFLAGS = \ @@ -127,7 +135,6 @@ libextractor_mime_la_LDFLAGS = \ OLD_LIBS = \ $(pdfplugin) \ - libextractor_deb.la \ libextractor_dvi.la \ libextractor_elf.la \ $(extraflac) \ @@ -316,16 +323,6 @@ libextractor_man_la_LIBADD = \ $(top_builddir)/src/main/libextractor.la \ $(LE_LIBINTL) -if HAVE_ZLIB -libextractor_deb_la_SOURCES = \ - debextractor.c -libextractor_deb_la_LDFLAGS = \ - $(PLUGINFLAGS) -libextractor_deb_la_LIBADD = \ - $(top_builddir)/src/main/libextractor.la \ - -lz -endif - libextractor_riff_la_SOURCES = \ riffextractor.c libextractor_riff_la_LDFLAGS = \ diff --git a/src/plugins/deb_extractor.c b/src/plugins/deb_extractor.c @@ -0,0 +1,355 @@ +/* + This file is part of libextractor. + (C) 2002, 2003, 2004 Vidyut Samanta and Christian Grothoff + + 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. + */ + +#include "platform.h" +#include "extractor.h" +#include <zlib.h> + +/* + * The .deb is an ar-chive file. It contains a tar.gz file + * named "control.tar.gz" which then contains a file 'control' + * that has the meta-data. And which variant of the various + * ar file formats is used is also not quite certain. Yuck. + * + * References: + * http://www.mkssoftware.com/docs/man4/tar.4.asp + * http://lists.debian.org/debian-policy/2003/12/msg00000.html + * http://www.opengroup.org/onlinepubs/009695399/utilities/ar.html + */ + + +static char * +stndup (const char *str, size_t n) +{ + char *tmp; + tmp = malloc (n + 1); + tmp[n] = '\0'; + memcpy (tmp, str, n); + return tmp; +} + + + +typedef struct +{ + const char *text; + enum EXTRACTOR_MetaType type; +} Matches; + +/* see also: "man 5 deb-control" */ +static Matches tmap[] = { + {"Package: ", EXTRACTOR_METATYPE_PACKAGE_NAME}, + {"Version: ", EXTRACTOR_METATYPE_PACKAGE_VERSION}, + {"Section: ", EXTRACTOR_METATYPE_PACKAGE_SECTION}, + {"Priority: ", EXTRACTOR_METATYPE_UPLOAD_PRIORITY}, + {"Architecture: ", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE}, + {"Depends: ", EXTRACTOR_METATYPE_PACKAGE_DEPENDENCY}, + {"Recommends: ", EXTRACTOR_METATYPE_PACKAGE_RECOMMENDS}, + {"Suggests: ", EXTRACTOR_METATYPE_PACKAGE_SUGGESTS}, + {"Installed-Size: ",EXTRACTOR_METATYPE_PACKAGE_INSTALLED_SIZE}, + {"Maintainer: ", EXTRACTOR_METATYPE_PACKAGE_MAINTAINER}, + {"Description: ", EXTRACTOR_METATYPE_DESCRIPTION}, + {"Source: ", EXTRACTOR_METATYPE_PACKAGE_SOURCE}, + {"Pre-Depends: ", EXTRACTOR_METATYPE_PACKAGE_PRE_DEPENDENCY}, + {"Conflicts: ", EXTRACTOR_METATYPE_PACKAGE_CONFLICTS}, + {"Replaces: ", EXTRACTOR_METATYPE_PACKAGE_REPLACES}, + {"Provides: ", EXTRACTOR_METATYPE_PACKAGE_PROVIDES}, + {"Essential: ", EXTRACTOR_METATYPE_PACKAGE_ESSENTIAL}, + {NULL, 0} +}; + + +/** + * Process the control file. + */ +static int +processControl (const char *data, + const size_t size, + EXTRACTOR_MetaDataProcessor proc, + void *proc_cls) +{ + size_t pos; + char *key; + char *val; + + pos = 0; + while (pos < size) + { + size_t colon; + size_t eol; + int i; + + colon = pos; + while (data[colon] != ':') + { + if ((colon > size) || (data[colon] == '\n')) + return 0; + colon++; + } + colon++; + while ((colon < size) && (isspace (data[colon]))) + colon++; + eol = colon; + while ((eol < size) && + ((data[eol] != '\n') || + ((eol + 1 < size) && (data[eol + 1] == ' ')))) + eol++; + if ((eol == colon) || (eol > size)) + return 0; + key = stndup (&data[pos], colon - pos); + i = 0; + while (tmap[i].text != NULL) + { + if (0 == strcmp (key, tmap[i].text)) + { + val = stndup (&data[colon], eol - colon); + if (0 != proc (proc_cls, + "deb", + tmap[i].type, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + val, + strlen(val) + 1)) + { + free (val); + return 1; + } + free (val); + break; + } + i++; + } + free (key); + pos = eol + 1; + } + return 0; +} + + +typedef struct +{ + char name[100]; + char mode[8]; + char userId[8]; + char groupId[8]; + char filesize[12]; + char lastModTime[12]; + char chksum[8]; + char link; + char linkName[100]; +} TarHeader; + +typedef struct +{ + TarHeader tar; + char magic[6]; + char version[2]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char prefix[155]; +} USTarHeader; + +/** + * Process the control.tar file. + */ +static int +processControlTar (const char *data, + const size_t size, + EXTRACTOR_MetaDataProcessor proc, + void *proc_cls) +{ + TarHeader *tar; + USTarHeader *ustar; + size_t pos; + + pos = 0; + while (pos + sizeof (TarHeader) < size) + { + unsigned long long fsize; + char buf[13]; + + tar = (TarHeader *) & data[pos]; + if (pos + sizeof (USTarHeader) < size) + { + ustar = (USTarHeader *) & data[pos]; + if (0 == strncmp ("ustar", &ustar->magic[0], strlen ("ustar"))) + pos += 512; /* sizeof(USTarHeader); */ + else + pos += 257; /* sizeof(TarHeader); minus gcc alignment... */ + } + else + { + pos += 257; /* sizeof(TarHeader); minus gcc alignment... */ + } + + memcpy (buf, &tar->filesize[0], 12); + buf[12] = '\0'; + if (1 != sscanf (buf, "%12llo", &fsize)) /* octal! Yuck yuck! */ + return 0; + if ((pos + fsize > size) || (fsize > size) || (pos + fsize < pos)) + return 0; + + if (0 == strncmp (&tar->name[0], "./control", strlen ("./control"))) + { + return processControl (&data[pos], fsize, proc, proc_cls); + } + if ((fsize & 511) != 0) + fsize = (fsize | 511) + 1; /* round up! */ + if (pos + fsize < pos) + return 0; + pos += fsize; + } + return 0; +} + +#define MAX_CONTROL_SIZE (1024 * 1024) + +static voidpf +Emalloc (voidpf opaque, uInt items, uInt size) +{ + return malloc (size * items); +} + +static void +Efree (voidpf opaque, voidpf ptr) +{ + free (ptr); +} + +/** + * Process the control.tar.gz file. + */ +static int +processControlTGZ (const unsigned char *data, + size_t size, + EXTRACTOR_MetaDataProcessor proc, + void *proc_cls) +{ + uint32_t bufSize; + char *buf; + z_stream strm; + int ret; + + bufSize = data[size - 4] + (data[size - 3] << 8) + (data[size - 2] << 16) + (data[size - 1] << 24); + if (bufSize > MAX_CONTROL_SIZE) + return 0; + memset (&strm, 0, sizeof (z_stream)); + strm.next_in = (Bytef *) data; + strm.avail_in = size; + strm.total_in = 0; + strm.zalloc = &Emalloc; + strm.zfree = &Efree; + strm.opaque = NULL; + + if (Z_OK == inflateInit2 (&strm, 15 + 32)) + { + buf = malloc (bufSize); + if (buf == NULL) + { + inflateEnd (&strm); + return 0; + } + strm.next_out = (Bytef *) buf; + strm.avail_out = bufSize; + inflate (&strm, Z_FINISH); + if (strm.total_out > 0) + { + ret = processControlTar (buf, strm.total_out, proc, proc_cls); + inflateEnd (&strm); + free (buf); + return ret; + } + free (buf); + inflateEnd (&strm); + } + return 0; +} + +typedef struct +{ + char name[16]; + char lastModTime[12]; + char userId[6]; + char groupId[6]; + char modeInOctal[8]; + char filesize[10]; + char trailer[2]; +} ObjectHeader; + + +int +EXTRACTOR_deb_extract (const char *data, + size_t size, + EXTRACTOR_MetaDataProcessor proc, + void *proc_cls, + const char *options) +{ + size_t pos; + int done = 0; + ObjectHeader *hdr; + unsigned long long fsize; + char buf[11]; + + if (size < 128) + return 0; + if (0 != strncmp ("!<arch>\n", data, strlen ("!<arch>\n"))) + return 0; + pos = strlen ("!<arch>\n"); + while (pos + sizeof (ObjectHeader) < size) + { + hdr = (ObjectHeader *) & data[pos]; + if (0 != strncmp (&hdr->trailer[0], "`\n", 2)) + return 0; + memcpy (buf, &hdr->filesize[0], 10); + buf[10] = '\0'; + if (1 != sscanf (buf, "%10llu", &fsize)) + return 0; + pos += sizeof (ObjectHeader); + if ((pos + fsize > size) || (fsize > size) || (pos + fsize < pos)) + return 0; + if (0 == strncmp (&hdr->name[0], + "control.tar.gz", strlen ("control.tar.gz"))) + { + if (0 != processControlTGZ ((const unsigned char *) &data[pos], + fsize, proc, proc_cls)) + return 1; + done++; + } + if (0 == strncmp (&hdr->name[0], + "debian-binary", strlen ("debian-binary"))) + { + if (0 != proc (proc_cls, + "deb", + EXTRACTOR_METATYPE_MIMETYPE, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", + "application/x-debian-package", + strlen ("application/x-debian-package"))) + return 1; + done++; + } + pos += fsize; + if (done == 2) + break; /* no need to process the rest of the archive */ + } + return 0; +} diff --git a/src/plugins/debextractor.c b/src/plugins/debextractor.c @@ -1,346 +0,0 @@ -/* - This file is part of libextractor. - (C) 2002, 2003, 2004 Vidyut Samanta and Christian Grothoff - - 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. - */ - -#include "platform.h" -#include "extractor.h" -#include <zlib.h> - -/* - * The .deb is an ar-chive file. It contains a tar.gz file - * named "control.tar.gz" which then contains a file 'control' - * that has the meta-data. And which variant of the various - * ar file formats is used is also not quite certain. Yuck. - * - * References: - * http://www.mkssoftware.com/docs/man4/tar.4.asp - * http://lists.debian.org/debian-policy/2003/12/msg00000.html - * http://www.opengroup.org/onlinepubs/009695399/utilities/ar.html - */ - -static EXTRACTOR_KeywordList * -addKeyword (EXTRACTOR_KeywordType type, - char *keyword, EXTRACTOR_KeywordList * 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; -} - -static char * -stndup (const char *str, size_t n) -{ - char *tmp; - tmp = malloc (n + 1); - tmp[n] = '\0'; - memcpy (tmp, str, n); - return tmp; -} - - - -typedef struct -{ - const char *text; - EXTRACTOR_KeywordType type; -} Matches; - -/* see also: "man 5 deb-control" */ -static Matches tmap[] = { - {"Package: ", EXTRACTOR_SOFTWARE}, - {"Version: ", EXTRACTOR_VERSIONNUMBER}, - {"Section: ", EXTRACTOR_GENRE}, - {"Priority: ", EXTRACTOR_PRIORITY}, - {"Architecture: ", EXTRACTOR_CREATED_FOR}, - {"Depends: ", EXTRACTOR_DEPENDENCY}, - {"Recommends: ", EXTRACTOR_RELATION}, - {"Suggests: ", EXTRACTOR_RELATION}, - {"Installed-Size: ", EXTRACTOR_SIZE}, - {"Maintainer: ", EXTRACTOR_PACKAGER}, - {"Description: ", EXTRACTOR_DESCRIPTION}, - {"Source: ", EXTRACTOR_SOURCE}, - {"Pre-Depends: ", EXTRACTOR_DEPENDENCY}, - {"Conflicts: ", EXTRACTOR_CONFLICTS}, - {"Replaces: ", EXTRACTOR_REPLACES}, - {"Provides: ", EXTRACTOR_PROVIDES}, - {NULL, 0}, - {"Essential: ", EXTRACTOR_UNKNOWN} -}; - - -/** - * Process the control file. - */ -static struct EXTRACTOR_Keywords * -processControl (const char *data, - const size_t size, struct EXTRACTOR_Keywords *prev) -{ - size_t pos; - char *key; - - pos = 0; - while (pos < size) - { - size_t colon; - size_t eol; - int i; - - colon = pos; - while (data[colon] != ':') - { - if ((colon > size) || (data[colon] == '\n')) - return prev; - colon++; - } - colon++; - while ((colon < size) && (isspace (data[colon]))) - colon++; - eol = colon; - while ((eol < size) && - ((data[eol] != '\n') || - ((eol + 1 < size) && (data[eol + 1] == ' ')))) - eol++; - if ((eol == colon) || (eol > size)) - return prev; - key = stndup (&data[pos], colon - pos); - i = 0; - while (tmap[i].text != NULL) - { - if (0 == strcmp (key, tmap[i].text)) - { - char *val; - - val = stndup (&data[colon], eol - colon); - prev = addKeyword (tmap[i].type, val, prev); - break; - } - i++; - } - free (key); - pos = eol + 1; - } - return prev; -} - - -typedef struct -{ - char name[100]; - char mode[8]; - char userId[8]; - char groupId[8]; - char filesize[12]; - char lastModTime[12]; - char chksum[8]; - char link; - char linkName[100]; -} TarHeader; - -typedef struct -{ - TarHeader tar; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char prefix[155]; -} USTarHeader; - -/** - * Process the control.tar file. - */ -static struct EXTRACTOR_Keywords * -processControlTar (const char *data, - const size_t size, struct EXTRACTOR_Keywords *prev) -{ - TarHeader *tar; - USTarHeader *ustar; - size_t pos; - - pos = 0; - while (pos + sizeof (TarHeader) < size) - { - unsigned long long fsize; - char buf[13]; - - tar = (TarHeader *) & data[pos]; - if (pos + sizeof (USTarHeader) < size) - { - ustar = (USTarHeader *) & data[pos]; - if (0 == strncmp ("ustar", &ustar->magic[0], strlen ("ustar"))) - pos += 512; /* sizeof(USTarHeader); */ - else - pos += 257; /* sizeof(TarHeader); minus gcc alignment... */ - } - else - { - pos += 257; /* sizeof(TarHeader); minus gcc alignment... */ - } - - memcpy (buf, &tar->filesize[0], 12); - buf[12] = '\0'; - if (1 != sscanf (buf, "%12llo", &fsize)) /* octal! Yuck yuck! */ - return prev; - if ((pos + fsize > size) || (fsize > size) || (pos + fsize < pos)) - return prev; - - if (0 == strncmp (&tar->name[0], "./control", strlen ("./control"))) - { - return processControl (&data[pos], fsize, prev); - } - if ((fsize & 511) != 0) - fsize = (fsize | 511) + 1; /* round up! */ - if (pos + fsize < pos) - return prev; - pos += fsize; - } - return prev; -} - -#define MAX_CONTROL_SIZE (1024 * 1024) - -static voidpf -Emalloc (voidpf opaque, uInt items, uInt size) -{ - return malloc (size * items); -} - -static void -Efree (voidpf opaque, voidpf ptr) -{ - free (ptr); -} - -/** - * Process the control.tar.gz file. - */ -static struct EXTRACTOR_Keywords * -processControlTGZ (const unsigned char *data, - size_t size, struct EXTRACTOR_Keywords *prev) -{ - uint32_t bufSize; - char *buf; - z_stream strm; - - bufSize = data[size - 4] + (data[size - 3] << 8) + (data[size - 2] << 16) + (data[size - 1] << 24); - if (bufSize > MAX_CONTROL_SIZE) - return prev; - - memset (&strm, 0, sizeof (z_stream)); - - strm.next_in = (Bytef *) data; - strm.avail_in = size; - strm.total_in = 0; - strm.zalloc = &Emalloc; - strm.zfree = &Efree; - strm.opaque = NULL; - - if (Z_OK == inflateInit2 (&strm, 15 + 32)) - { - buf = malloc (bufSize); - if (buf == NULL) - { - inflateEnd (&strm); - return prev; - } - strm.next_out = (Bytef *) buf; - strm.avail_out = bufSize; - inflate (&strm, Z_FINISH); - if (strm.total_out > 0) - { - prev = processControlTar (buf, strm.total_out, prev); - inflateEnd (&strm); - free (buf); - return prev; - } - free (buf); - inflateEnd (&strm); - } - return prev; -} - -typedef struct -{ - char name[16]; - char lastModTime[12]; - char userId[6]; - char groupId[6]; - char modeInOctal[8]; - char filesize[10]; - char trailer[2]; -} ObjectHeader; - -struct EXTRACTOR_Keywords * -libextractor_deb_extract (const char *filename, - const char *data, - const size_t size, struct EXTRACTOR_Keywords *prev) -{ - size_t pos; - int done = 0; - - if (size < 128) - return prev; - if (0 != strncmp ("!<arch>\n", data, strlen ("!<arch>\n"))) - return prev; - pos = strlen ("!<arch>\n"); - while (pos + sizeof (ObjectHeader) < size) - { - ObjectHeader *hdr; - unsigned long long fsize; - char buf[11]; - - hdr = (ObjectHeader *) & data[pos]; - if (0 != strncmp (&hdr->trailer[0], "`\n", 2)) - return prev; - - memcpy (buf, &hdr->filesize[0], 10); - buf[10] = '\0'; - if (1 != sscanf (buf, "%10llu", &fsize)) - return prev; - pos += sizeof (ObjectHeader); - if ((pos + fsize > size) || (fsize > size) || (pos + fsize < pos)) - return prev; - if (0 == strncmp (&hdr->name[0], - "control.tar.gz", strlen ("control.tar.gz"))) - { - prev = processControlTGZ ((const unsigned char *) &data[pos], - fsize, prev); - done++; - } - if (0 == strncmp (&hdr->name[0], - "debian-binary", strlen ("debian-binary"))) - { - prev = addKeyword (EXTRACTOR_MIMETYPE, - strdup ("application/x-debian-package"), prev); - done++; - } - pos += fsize; - if (done == 2) - break; /* no need to process the rest of the archive */ - } - return prev; -}