From: Stephen Seo Date: Thu, 23 Jan 2025 07:36:09 +0000 (+0900) Subject: WIP --prefix: Impl --prefix for file v0 archiving X-Git-Tag: 1.12^2~18 X-Git-Url: https://git.seodisparate.com/stephenseo/annotated.html?a=commitdiff_plain;h=fb89a0fc963ab110e7351be798fb1e2f5918e9f9;p=SimpleArchiver WIP --prefix: Impl --prefix for file v0 archiving TODO: - file v0 extraction "--prefix" - file v1, v2, and v3 archiving and extraction "--prefix" --- diff --git a/src/archiver.c b/src/archiver.c index e182cbd..8ef8dae 100644 --- a/src/archiver.c +++ b/src/archiver.c @@ -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; diff --git a/src/archiver.h b/src/archiver.h index 44a7826..ca526e1 100644 --- a/src/archiver.h +++ b/src/archiver.h @@ -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. diff --git a/src/helpers.c b/src/helpers.c index ac465be..3ad166b 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -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. diff --git a/src/helpers.h b/src/helpers.h index 7b0a4b2..05fbb5c 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -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);