]> git.seodisparate.com - SimpleArchiver/commitdiff
Impl. extract "white-list"
authorStephen Seo <seo.disparate@gmail.com>
Thu, 18 Jul 2024 06:30:05 +0000 (15:30 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Thu, 18 Jul 2024 06:30:05 +0000 (15:30 +0900)
When extracting, the given positional args will determine a "white-list"
of files to extract. If no positional args are given, then all files in
the archive will be extracted.

src/archiver.c
src/data_structures/hash_map.h
src/parser.h

index c58e9d81979f661541c7b1a5c760f645e98d28c5..a223ec3f2c102bbb578caf551a57b868efd55b02 100644 (file)
@@ -22,6 +22,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "data_structures/linked_list.h"
+#include "parser.h"
 #include "platforms.h"
 #if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
     SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC ||          \
@@ -34,6 +36,7 @@
 #include <unistd.h>
 #endif
 
+#include "data_structures/hash_map.h"
 #include "helpers.h"
 
 #define TEMP_FILENAME_CMP "simple_archiver_compressed_%u.tmp"
@@ -503,6 +506,9 @@ int write_files_fn(void *data, void *ud) {
   return 0;
 }
 
+void cleanup_nop_fn(__attribute__((unused)) void *unused) {}
+void cleanup_free_fn(void *data) { free(data); }
+
 char *simple_archiver_error_to_string(enum SDArchiverStateReturns error) {
   switch (error) {
     case SDAS_SUCCESS:
@@ -730,6 +736,20 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
 
   uint32_t size = u32;
   int skip = 0;
+  __attribute__((cleanup(simple_archiver_hash_map_free)))
+  SDArchiverHashMap *hash_map = NULL;
+  if (state->parsed->working_files && state->parsed->working_files[0] != NULL) {
+    hash_map = simple_archiver_hash_map_init();
+    for (char **iter = state->parsed->working_files; *iter != NULL; ++iter) {
+      int len = strlen(*iter) + 1;
+      char *key = malloc(len);
+      memcpy(key, *iter, len);
+      key[len - 1] = 0;
+      simple_archiver_hash_map_insert(&hash_map, key, key, len, cleanup_nop_fn,
+                                      cleanup_free_fn);
+      fprintf(stderr, "\"%s\" put in map\n", key);
+    }
+  }
   for (uint32_t idx = 0; idx < size; ++idx) {
     fprintf(stderr, "\nFile %10u of %10u.\n", idx + 1, size);
     if (feof(in_f) || ferror(in_f)) {
@@ -762,8 +782,6 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
           skip = 0;
         }
         if (!skip) {
-          simple_archiver_helper_make_dirs((const char *)buf);
-          out_f = fopen((const char *)buf, "wb");
           out_f_name = malloc(strlen((const char *)buf) + 1);
           memcpy(out_f_name, buf, strlen((const char *)buf) + 1);
         }
@@ -793,8 +811,6 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
           skip = 0;
         }
         if (!skip) {
-          simple_archiver_helper_make_dirs((const char *)uc_heap_buf);
-          out_f = fopen((const char *)buf, "wb");
           out_f_name = malloc(strlen((const char *)buf) + 1);
           memcpy(out_f_name, buf, strlen((const char *)buf) + 1);
         }
@@ -852,9 +868,20 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
         fprintf(stderr, "  File size: %lu\n", u64);
       }
 
-      if (do_extract && !skip) {
+      int skip_due_to_map = 0;
+      if (hash_map != NULL && out_f_name) {
+        if (simple_archiver_hash_map_get(hash_map, out_f_name,
+                                         strlen(out_f_name) + 1) == NULL) {
+          skip_due_to_map = 1;
+          fprintf(stderr, "Skipping not specified in args...\n");
+        }
+      }
+
+      if (do_extract && !skip && !skip_due_to_map) {
         fprintf(stderr, "  Extracting...\n");
 
+        simple_archiver_helper_make_dirs((const char *)out_f_name);
+        out_f = fopen(out_f_name, "wb");
 #if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
     SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC ||          \
     SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
index 7a61794c22682db35bd60b1d369e45433bec31b1..0ca8864aa8b87d58b0ba8cf789e93203eec0512a 100644 (file)
@@ -37,6 +37,8 @@ void simple_archiver_hash_map_free(SDArchiverHashMap **hash_map);
 /// key must remain valid for the lifetime of its entry in the hash map.
 /// If value_cleanup_fn is NULL, then "free" is used instead.
 /// If key_cleanup_fn is NULL, then "free" is used instead.
+/// NOTICE: You must not pass NULL to value, otherwise all "get" checks will
+/// fail for the inserted key.
 int simple_archiver_hash_map_insert(SDArchiverHashMap **hash_map, void *value,
                                     void *key, unsigned int key_size,
                                     void (*value_cleanup_fn)(void *),
index 40e8774e731b421a863e9eeaf7295ee33b46ca91..218470443c46a83a11ec73da9848a63147ea54ae 100644 (file)
@@ -38,7 +38,7 @@ typedef struct SDArchiverParsed {
   char *decompressor;
   /// Null-terminated strings in array of strings.
   /// Last entry should be NULL.
-  /// Not used when extracting.
+  /// Determines a "white-list" of files to extract when extracting.
   char **working_files;
 } SDArchiverParsed;