summary refs log tree commit diff
path: root/mico-store.c
diff options
context:
space:
mode:
Diffstat (limited to 'mico-store.c')
-rw-r--r--mico-store.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/mico-store.c b/mico-store.c
index f92d592..0b21301 100644
--- a/mico-store.c
+++ b/mico-store.c
@@ -1,3 +1,5 @@
+#include <sys/stat.h>
+
 #include <arpa/inet.h>
 #include <assert.h>
 #include <stdint.h>
@@ -6,6 +8,7 @@
 #include <stdlib.h>
 
 #include <zip.h>
+#include <zlib.h>    // for crc32
 
 #define MICO_HEADER "\211MiC\r\n\032\n"
 
@@ -150,17 +153,50 @@ write_stream(char *name)
 	memcpy(ts.mem + 8, &nevents, sizeof nevents);
 	memcpy(vs.mem + 8, &nevents, sizeof nevents);
 
+	uint32_t crc = crc32(0L, Z_NULL, 0);
+	crc = crc32(crc, (unsigned char *)ts.mem, (long)ts.memlen);
+	printf("precomputed crc=%d\n", crc);
+
 	// time_t mtime = metrics[m].value[0].t / 1000;
 	snprintf(path, sizeof path, "%s/time.dd", prefix);
 
-	zip_source_t *buft = zip_source_buffer(zip,
-	    ts.mem, ts.memlen, 0);
-	int jj= zip_file_add(zip, path, buft, ZIP_FL_ENC_UTF_8);
-	printf("index of %s = %d\n", path, jj);
-	if (jj < 0) {
-		printf("error adding file: %s\n", zip_strerror(zip));
+	int found_ts = 0;
+	int jj;
+	for (int64_t kk = 0; kk < zip_get_num_entries(zip, 0); kk += 2) {
+		struct zip_stat stat;
+		zip_stat_index(zip, kk, 0, &stat);
+		if (stat.crc != crc)
+			continue;
+
+		/* XXX better validation the ts are identical than just crc */
+
+		zip_uint32_t attr = ((S_IFLNK | 0777) << 16L);
+
+		char target[1024];
+		snprintf(target, sizeof target, "../../%s", zip_get_name(zip, kk, ZIP_FL_ENC_RAW));
+		fprintf(stderr, "duplicate ts crc=%d, target=%s\n", stat.crc, target);
+
+		struct zip_source *link = zip_source_buffer(zip, strdup(target), strlen(target), 1);
+		jj = zip_file_add(zip, path, link, ZIP_FL_ENC_UTF_8);
+		if (jj < 0) {
+			printf("error adding file: %s\n", zip_strerror(zip));
+		}
+		zip_file_set_external_attributes(zip, jj, 0, ZIP_OPSYS_UNIX, attr);
+		printf("index of symlink %s -> %s = %d\n", path, target, jj);
+		found_ts = 1;
+		break;
+	}
+
+	if (!found_ts) {
+		zip_source_t *buft = zip_source_buffer(zip,
+		    ts.mem, ts.memlen, 0);
+		jj= zip_file_add(zip, path, buft, ZIP_FL_ENC_UTF_8);
+		printf("index of %s = %d\n", path, jj);
+		if (jj < 0) {
+			printf("error adding file: %s\n", zip_strerror(zip));
+		}
+		// zip_file_set_mtime(zip, jj, mtime, 0);
 	}
-	// zip_file_set_mtime(zip, jj, mtime, 0);
 
 	snprintf(path, sizeof path, "%s/data.d", prefix);
 
@@ -176,12 +212,16 @@ write_stream(char *name)
 	// note that data must be kept in memory until zip_close
 	// actually writes the archive.
 
+
 	// close and reopen the zip to force write and free all buffers
 	zip_close(zip);
 	zip = zip_open(filename, 0, 0);
 	if (!zip)
 		exit(-1);
 
+	struct zip_stat mystat;
+	zip_stat_index(zip, jj-1, 0, &mystat);   // XXX
+
 	free(ts.mem);
 	free(vs.mem);
 }