summary refs log tree commit diff
path: root/mico-dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'mico-dump.c')
-rw-r--r--mico-dump.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/mico-dump.c b/mico-dump.c
index 75219d5..b4635af 100644
--- a/mico-dump.c
+++ b/mico-dump.c
@@ -1,3 +1,7 @@
+#define _XOPEN_SOURCE 700
+
+#include <sys/stat.h>
+
 #include <arpa/inet.h>
 #include <assert.h>
 #include <fnmatch.h>
@@ -157,11 +161,33 @@ main(int argc, char *argv[])
 		struct bitreader ts = { 0 };
 		struct bitreader vs = { 0 };
 
+		int ts_index = i;
+
+		zip_uint8_t opsys;
+		zip_uint32_t attr;
+		zip_file_get_external_attributes(zip, i, 0, &opsys, &attr);
+		if (opsys == ZIP_OPSYS_UNIX &&
+		    S_ISLNK(attr >> 16)) {
+			printf("symlink!\n");
+			struct zip_file *zf = zip_fopen_index(zip, i, 0);
+			char buf[1024];
+			ssize_t len = zip_fread(zf, buf, sizeof buf);
+			buf[len] = 0;
+			if (strncmp(buf, "../../", 6) == 0) {
+				ts_index = zip_name_locate(zip, buf + 6, 0);
+				fprintf(stderr, "%s -> %d\n", buf + 6, ts_index);
+				if (ts_index < 0) {
+					fprintf(stderr, "invalid symlink, skipping");
+					continue;
+				}
+			}
+		}
+
 		/* XXX verify assumptions on zip file order */
-		ts.input = zip_fopen_index(zip, i, 0);
+		ts.input = zip_fopen_index(zip, ts_index, 0);
 		vs.input = zip_fopen_index(zip, i+1, 0);
 
-		char *name = strdup(zip_get_name(zip, i, ZIP_FL_ENC_RAW));
+		char *name = strdup(zip_get_name(zip, i+1, ZIP_FL_ENC_RAW));
 		char *s = strchr(name, '/');
 		*s = '{';
 		s = strrchr(name, '/');