[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.
|