]> git.seodisparate.com - SimpleArchiver/commitdiff
WIP --prefix: Impl --prefix for file v0 archiving
authorStephen Seo <seo.disparate@gmail.com>
Thu, 23 Jan 2025 07:36:09 +0000 (16:36 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Thu, 23 Jan 2025 07:36:09 +0000 (16:36 +0900)
TODO:
    - file v0 extraction "--prefix"
    - file v1, v2, and v3 archiving and extraction "--prefix"

src/archiver.c
src/archiver.h
src/helpers.c
src/helpers.h

index e182cbdc0854b79e8080b0fb4a6eeb661eb30279..8ef8dae6a9d07d902ce2961d8ed1998053028616 100644 (file)
@@ -133,7 +133,7 @@ void cleanup_overwrite_filename_delete_simple(char **filename) {
   }
 }
 
-int write_files_fn(void *data, void *ud) {
+int write_files_fn_file_v0(void *data, void *ud) {
   if (is_sig_int_occurred) {
     return 1;
   }
@@ -398,6 +398,9 @@ int write_files_fn(void *data, void *ud) {
       uint64_t u64;
 
       size_t temp_size = strlen(file_info->filename);
+      if (state->parsed->prefix) {
+        temp_size += strlen(state->parsed->prefix);
+      }
       if (temp_size > 0xFFFF) {
         fprintf(stderr, "ERROR: Filename size is too large to store!\n");
         return 1;
@@ -417,7 +420,16 @@ int write_files_fn(void *data, void *ud) {
       temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
       temp_to_write->buf = malloc(u16 + 1);
       temp_to_write->size = u16 + 1;
-      memcpy(temp_to_write->buf, file_info->filename, u16 + 1);
+      if (state->parsed->prefix) {
+        const unsigned long prefix_length = strlen(state->parsed->prefix);
+        const unsigned long filename_length = strlen(file_info->filename);
+        memcpy(temp_to_write->buf, state->parsed->prefix, prefix_length);
+        memcpy((uint8_t*)temp_to_write->buf + prefix_length,
+               file_info->filename,
+               filename_length + 1);
+      } else {
+        memcpy(temp_to_write->buf, file_info->filename, u16 + 1);
+      }
       simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
 
       // Write flags.
@@ -537,6 +549,9 @@ int write_files_fn(void *data, void *ud) {
       uint64_t u64;
 
       size_t temp_size = strlen(file_info->filename);
+      if (state->parsed->prefix) {
+        temp_size += strlen(state->parsed->prefix);
+      }
       if (temp_size > 0xFFFF) {
         fprintf(stderr, "ERROR: Filename is too large to store!\n");
         return 1;
@@ -556,7 +571,16 @@ int write_files_fn(void *data, void *ud) {
       temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
       temp_to_write->buf = malloc(u16 + 1);
       temp_to_write->size = u16 + 1;
-      memcpy(temp_to_write->buf, file_info->filename, u16 + 1);
+      if (state->parsed->prefix) {
+        const unsigned long prefix_length = strlen(state->parsed->prefix);
+        const unsigned long filename_length = strlen(file_info->filename);
+        memcpy(temp_to_write->buf, state->parsed->prefix, prefix_length);
+        memcpy((uint8_t*)temp_to_write->buf + prefix_length,
+               file_info->filename,
+               filename_length + 1);
+      } else {
+        memcpy(temp_to_write->buf, file_info->filename, u16 + 1);
+      }
       simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
 
       // Write flags.
@@ -691,6 +715,9 @@ int write_files_fn(void *data, void *ud) {
     uint16_t u16;
 
     size_t temp_size = strlen(file_info->filename);
+    if (state->parsed->prefix) {
+      temp_size += strlen(state->parsed->prefix);
+    }
     if (temp_size > 0xFFFF) {
       fprintf(stderr, "ERROR: Filename is too large to store!\n");
       return 1;
@@ -710,7 +737,16 @@ int write_files_fn(void *data, void *ud) {
     temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
     temp_to_write->buf = malloc(u16 + 1);
     temp_to_write->size = u16 + 1;
-    memcpy(temp_to_write->buf, file_info->filename, u16 + 1);
+    if (state->parsed->prefix) {
+      const unsigned long prefix_length = strlen(state->parsed->prefix);
+      const unsigned long filename_length = strlen(file_info->filename);
+      memcpy(temp_to_write->buf, state->parsed->prefix, prefix_length);
+      memcpy((uint8_t*)temp_to_write->buf + prefix_length,
+             file_info->filename,
+             filename_length + 1);
+    } else {
+      memcpy(temp_to_write->buf, file_info->filename, u16 + 1);
+    }
     simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
 
     // Write flags.
@@ -800,7 +836,7 @@ int write_files_fn(void *data, void *ud) {
         // First get absolute path of link.
         __attribute__((cleanup(
             simple_archiver_helper_cleanup_malloced))) void *link_abs_path =
-            simple_archiver_file_abs_path(file_info->filename);
+            simple_archiver_helper_real_path_to_name(file_info->filename);
         if (!link_abs_path) {
           fprintf(stderr, "WARNING: Failed to get absolute path of link!\n");
         } else {
@@ -900,6 +936,12 @@ int write_files_fn(void *data, void *ud) {
       memset(temp_to_write->buf, 0, 2);
       simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
     } else if ((state->parsed->flags & 0x20) == 0) {
+      if (state->parsed->prefix) {
+        char *abs_path_cached = abs_path;
+        abs_path = simple_archiver_helper_insert_prefix_in_link_path(
+          state->parsed->prefix, file_info->filename, abs_path_cached);
+        free(abs_path_cached);
+      }
       // Write absolute path length.
       size_t temp_size = strlen(abs_path);
       if (temp_size > 0xFFFF) {
@@ -934,6 +976,12 @@ int write_files_fn(void *data, void *ud) {
     }
 
     if (rel_path) {
+      if (state->parsed->prefix) {
+        char *rel_path_cached = rel_path;
+        rel_path = simple_archiver_helper_insert_prefix_in_link_path(
+          state->parsed->prefix, file_info->filename, rel_path_cached);
+        free(rel_path_cached);
+      }
       // Write relative path length.
       size_t temp_size = strlen(rel_path);
       if (temp_size > 0xFFFF) {
@@ -1011,7 +1059,8 @@ int filenames_to_abs_map_fn(void *data, void *ud) {
   }
 
   // Get combined full path to file.
-  char *fullpath = simple_archiver_file_abs_path(file_info->filename);
+  char *fullpath =
+    simple_archiver_helper_real_path_to_name(file_info->filename);
   if (!fullpath) {
     return 1;
   }
@@ -2309,7 +2358,7 @@ int simple_archiver_write_v0(FILE *out_f, SDArchiverState *state,
   snprintf(format_str, 64, FILE_COUNTS_OUTPUT_FORMAT_STR_1, state->digits,
            state->digits);
   fprintf(stderr, format_str, state->count, state->max);
-  if (simple_archiver_list_get(filenames, write_files_fn, state)) {
+  if (simple_archiver_list_get(filenames, write_files_fn_file_v0, state)) {
     if (is_sig_int_occurred) {
       return SDAS_SIGINT;
     }
@@ -2514,7 +2563,7 @@ int simple_archiver_write_v1(FILE *out_f, SDArchiverState *state,
         if (abs_path) {
           __attribute__((cleanup(
               simple_archiver_helper_cleanup_malloced))) void *link_abs_path =
-              simple_archiver_file_abs_path(node->data);
+              simple_archiver_helper_real_path_to_name(node->data);
           if (!link_abs_path) {
             fprintf(stderr, "WARNING: Failed to get absolute path to link!\n");
           } else {
@@ -3424,7 +3473,7 @@ int simple_archiver_write_v2(FILE *out_f, SDArchiverState *state,
         if (abs_path) {
           __attribute__((cleanup(
               simple_archiver_helper_cleanup_malloced))) void *link_abs_path =
-              simple_archiver_file_abs_path(node->data);
+              simple_archiver_helper_real_path_to_name(node->data);
           if (!link_abs_path) {
             fprintf(stderr, "WARNING: Failed to get absolute path to link!\n");
           } else {
@@ -4366,7 +4415,7 @@ int simple_archiver_write_v3(FILE *out_f, SDArchiverState *state,
         if (abs_path) {
           __attribute__((cleanup(
               simple_archiver_helper_cleanup_malloced))) void *link_abs_path =
-              simple_archiver_file_abs_path(node->data);
+              simple_archiver_helper_real_path_to_name(node->data);
           if (!link_abs_path) {
             fprintf(stderr, "WARNING: Failed to get absolute path to link!\n");
           } else {
@@ -9158,50 +9207,6 @@ char *simple_archiver_filenames_to_relative_path(const char *from_abs,
   return rel_path;
 }
 
-char *simple_archiver_file_abs_path(const char *filename) {
-#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
-    SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC ||          \
-    SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
-  __attribute__((cleanup(simple_archiver_helper_cleanup_malloced))) void *path =
-      malloc(strlen(filename) + 1);
-  strncpy(path, filename, strlen(filename) + 1);
-
-  char *path_dir = dirname(path);
-  if (!path_dir) {
-    return NULL;
-  }
-
-  __attribute__((
-      cleanup(simple_archiver_helper_cleanup_malloced))) void *dir_realpath =
-      realpath(path_dir, NULL);
-  if (!dir_realpath) {
-    return NULL;
-  }
-
-  // Recreate "path" since it may have been modified by dirname().
-  simple_archiver_helper_cleanup_malloced(&path);
-  path = malloc(strlen(filename) + 1);
-  strncpy(path, filename, strlen(filename) + 1);
-
-  char *filename_basename = basename(path);
-  if (!filename_basename) {
-    return NULL;
-  }
-
-  // Get combined full path to file.
-  const size_t realpath_size = strlen(dir_realpath) + 1;
-  const size_t basename_size = strlen(filename_basename) + 1;
-  const size_t fullpath_size = realpath_size + basename_size;
-  char *fullpath = malloc(fullpath_size);
-  strncpy(fullpath, dir_realpath, realpath_size);
-  fullpath[realpath_size - 1] = '/';
-  strcpy(fullpath + realpath_size, filename_basename);
-
-  return fullpath;
-#endif
-  return NULL;
-}
-
 int simple_archiver_validate_file_path(const char *filepath) {
   if (!filepath) {
     return 5;
index 44a782621cfda69af616b4802d193734b6f71741..ca526e189912308ff5d101767683c48d4941b8d0 100644 (file)
@@ -108,12 +108,6 @@ int simple_archiver_de_compress(int pipe_fd_in[2], int pipe_fd_out[2],
 char *simple_archiver_filenames_to_relative_path(const char *from_abs,
                                                  const char *to_abs);
 
-/// Gets the absolute path to a file given a path to a file.
-/// Should also work on symlinks such that the returned string is the path to
-/// the link itself, not what it points to.
-/// Non-NULL on success, and must be free'd if non-NULL.
-char *simple_archiver_file_abs_path(const char *filename);
-
 /// Used to validate a file in a ".simplearchive" file to avoid writing outside
 /// of current working directory.
 /// Returns zero if file is OK.
index ac465beebb8c077a1cd8963f1a9cc5fede3d5761..3ad166b3d542e75c99ebfd2f6338eacfc47940b7 100644 (file)
@@ -509,10 +509,16 @@ char *simple_archiver_helper_real_path_to_name(const char *filename) {
   __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
   char *filename_copy = strdup(filename);
   char *filename_dir = dirname(filename_copy);
+  if (!filename_dir) {
+    return NULL;
+  }
 
   __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
   char *filename_copy2 = strdup(filename);
   char *filename_base = basename(filename_copy2);
+  if (!filename_base) {
+    return NULL;
+  }
   const unsigned long basename_length = strlen(filename_base);
 
   // Get realpath to dirname.
index 7b0a4b29cc5802dc9e95f09aaf458e340d3bfd77..05fbb5cce37c85159f61146d7a91fdd1621cc98a 100644 (file)
@@ -85,7 +85,7 @@ char *simple_archiver_helper_insert_prefix_in_link_path(const char *prefix,
                                                         const char *path);
 
 // Ensures the path to the filename is resolved, even if "filename" is a
-// symbolic link.
+// symbolic link. Returned c-string must be free'd.
 char *simple_archiver_helper_real_path_to_name(const char *filename);
 
 void simple_archiver_helper_cleanup_FILE(FILE **fd);