[Extractor-gtk-cvslog] SF.net SVN: extractor-gtk:[124] trunk/extractor
Extract files from unusual archive formats
Brought to you by:
someone-guy
From: <som...@us...> - 2012-08-19 20:35:58
|
Revision: 124 http://extractor-gtk.svn.sourceforge.net/extractor-gtk/?rev=124&view=rev Author: someone-guy Date: 2012-08-19 20:35:51 +0000 (Sun, 19 Aug 2012) Log Message: ----------- Add support for "installkit" files. They are used by installers created with InstallJammer. Modified Paths: -------------- trunk/extractor/Makefile trunk/extractor/extractor.c trunk/extractor/formats.h Added Paths: ----------- trunk/extractor/installkit.c Modified: trunk/extractor/Makefile =================================================================== --- trunk/extractor/Makefile 2011-08-21 10:08:02 UTC (rev 123) +++ trunk/extractor/Makefile 2012-08-19 20:35:51 UTC (rev 124) @@ -18,6 +18,7 @@ dsnpk.c \ generic.c \ homeworld2.c \ + installkit.c \ nwn.c \ pak.c \ solid.c \ Modified: trunk/extractor/extractor.c =================================================================== --- trunk/extractor/extractor.c 2011-08-21 10:08:02 UTC (rev 123) +++ trunk/extractor/extractor.c 2012-08-19 20:35:51 UTC (rev 124) @@ -22,6 +22,7 @@ &dsnpk_fmt, &generic_fmt, &homeworld2_fmt, + &installkit_fmt, &nwn_fmt, &pak_fmt, &solid_fmt, Modified: trunk/extractor/formats.h =================================================================== --- trunk/extractor/formats.h 2011-08-21 10:08:02 UTC (rev 123) +++ trunk/extractor/formats.h 2012-08-19 20:35:51 UTC (rev 124) @@ -30,6 +30,7 @@ extern const fmt_desc_t dsnpk_fmt; extern const fmt_desc_t generic_fmt; extern const fmt_desc_t homeworld2_fmt; +extern const fmt_desc_t installkit_fmt; extern const fmt_desc_t nwn_fmt; extern const fmt_desc_t pak_fmt; extern const fmt_desc_t solid_fmt; Added: trunk/extractor/installkit.c =================================================================== --- trunk/extractor/installkit.c (rev 0) +++ trunk/extractor/installkit.c 2012-08-19 20:35:51 UTC (rev 124) @@ -0,0 +1,113 @@ +/** + * \file installkit.c + * \brief routines for handling the installkit CRAP archive files + * + * Copyright (C) 2012 Reimar Döffinger + * License: GPL v2 (see LICENSE file) + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include "formats.h" +#include "helpers.h" + +//! check if this is a installkit archive file +static int check_file(FILE *in) { + char sig[7] = {0}; + fseek(in, -256, SEEK_END); + fread(sig, 6, 1, in); + return strcmp(sig, "CRAP02") == 0; +} + +static file_t *get_list(FILE *in) { + char header[257] = {0}; + char *end; + file_t *list = NULL; + uint32_t count = 0, tblpos; + fseek(in, -256, SEEK_END); + if (fread(header, 256, 1, in) != 1) + return NULL; + tblpos = strtoull(header + 6, &end, 0); + if (*end) + return NULL; + + fseek(in, tblpos, SEEK_SET); + while (fread(header, 256, 1, in) == 1) { + char *pos = header; + if (count >= MAX_FILES) break; + if (memcmp(header, "FILE", 4)) break; + add_entry_empty(&list, count); + pos += 6; + list[count].name = calloc(strlen(pos) + 11, 1); + strcpy(list[count].name, pos); + pos += 128; + list[count].len = strtoull(pos, &end, 0); + if (*end) continue; + pos += 12; + list[count].clen = strtoull(pos, &end, 0); + if (*end) continue; + pos += 12 + 12 + 2; // mtime, corefile and encryption (RC4) marker + list[count].start = strtoull(pos, &end, 0); + if (*end) continue; + pos += 12; + list[count].compressed = 1; + switch (TAG(0, 0, header[4], header[5])) { + case TAG(0, 0, 'L', 'Z'): + strcat(list[count].name, ".lzma"); + list[count].priv = (void *)(intptr_t)1; + break; + case TAG(0, 0, 'Z', 'L'): + strcat(list[count].name, ".gz"); + list[count].priv = (void *)(intptr_t)2; + break; + case TAG(0, 0, '0', '0'): + list[count].compressed = 0; + break; + default: + // HACK: until we can actually decompress + list[count].len = list[count].clen; + strcat(list[count].name, ".compr"); + break; + } + count++; + } + return list; +} + +static int extract_file(FILE *in, const file_t *file, FILE *out) { + uint64_t l = file->len; + uint8_t sizeb[8] = {l, l >>8, l >> 16, l >> 24, l >> 32, l >> 40, l >> 48, l >> 56}; + int len, len2; + if (!file->priv) return default_extract_file(in, file, out); + fseek(in, file->start, SEEK_SET); + if ((intptr_t)file->priv == 2) { + static const uint8_t gzhdr[] = {0x1f, 0x8b, 8, 0, 0, 0, 0, 0, 2, 0xff}; + static const uint8_t dummy_crc[4]; + if (fwrite(gzhdr, sizeof(gzhdr), 1, out) != 1) return -1; + len = fcopy(in, out, file->clen); + if (len <= 0) return len; + if (fwrite(dummy_crc, sizeof(dummy_crc), 1, out) != 1) return -1; + if (fwrite(sizeb, 4, 1, out) != 1) return -1; + return sizeof(gzhdr) + len + 8; + } + if (file->clen < 5) return -1; + len = fcopy(in, out, 5); + if (len <= 0) return len; + if (fwrite(sizeb, sizeof(sizeb), 1, out) != 1) return -1; + len2 = fcopy(in, out, file->clen - 5); + if (len2 <= 0) return len2; + return len + sizeof(sizeb) + len2; +} + +const fmt_desc_t installkit_fmt = { + "installkit", + "installkit (CRAP)", + "installkit (*.crap;*.bin)", + "*.crap;*.bin", + check_file, + get_list, + default_free_list, + extract_file, + default_extract_mem, +}; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |