From e9c327a62f1020aa1059581c416ff1bf6d906254 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Wed, 24 Jul 2024 13:32:39 +0900 Subject: [PATCH] Add "--no-abs-symlink" to not store absolute paths --- src/archiver.c | 201 ++++++++++++++++++++++++++----------------------- src/parser.c | 4 + src/parser.h | 1 + 3 files changed, 112 insertions(+), 94 deletions(-) diff --git a/src/archiver.c b/src/archiver.c index ea84868..ff7d201 100644 --- a/src/archiver.c +++ b/src/archiver.c @@ -673,107 +673,118 @@ int write_files_fn(void *data, void *ud) { // Get absolute path. __attribute__((cleanup(free_malloced_memory))) void *abs_path = realpath(file_info->filename, NULL); + __attribute__((cleanup(free_malloced_memory))) void *rel_path = NULL; if (!abs_path) { fprintf(stderr, "WARNING: Failed to get absolute path of link destination!\n"); - } - - // Get relative path. - __attribute__((cleanup(free_malloced_memory))) void *rel_path = NULL; - // First get absolute path of link. - // Get abs path to dirname of link. - unsigned int link_dir_path_len = strlen(file_info->filename) + 1; - __attribute__((cleanup(free_malloced_memory))) void *link_dir_path = - malloc(link_dir_path_len); - strncpy(link_dir_path, file_info->filename, link_dir_path_len); - char *link_dirname = dirname(link_dir_path); - __attribute__((cleanup(free_malloced_memory))) void *link_dir_abs_path = - realpath(link_dirname, NULL); - if (!link_dir_abs_path) { - fprintf(stderr, - "WARNING: Failed to get absolute path of link directory!\n"); - } else { - // Get basename of link to append. - __attribute__((cleanup(free_malloced_memory))) void *link_filename = - malloc(strlen(file_info->filename) + 1); - strncpy(link_filename, file_info->filename, - strlen(file_info->filename) + 1); - char *link_basename = basename(link_filename); - // Set up full path to link. - unsigned int link_path_len = strlen(link_dir_abs_path); - __attribute__((cleanup(free_malloced_memory))) void *combined_path = - malloc(link_path_len + 1 + strlen(link_basename) + 1); - strncpy(combined_path, link_dir_abs_path, link_path_len + 1); - ((char *)combined_path)[link_path_len] = '/'; - strncpy((char *)combined_path + link_path_len + 1, link_basename, - strlen(link_basename) + 1); - // fprintf(stderr, "DEBUG: abs_path: %s\nDEBUG: combined_path: %s\n", - // (char*)abs_path, (char*)combined_path); - // Compare paths to get relative path. - // Get first non-common char. - unsigned int idx; - unsigned int last_slash; - for (idx = 0, last_slash = 0; - idx < strlen(abs_path) && idx < strlen(combined_path); ++idx) { - if (((const char *)abs_path)[idx] != - ((const char *)combined_path)[idx]) { - break; - } else if (((const char *)abs_path)[idx] == '/') { - last_slash = idx + 1; - } - } - // Get substrings of both paths. - char *link_substr = (char *)combined_path + last_slash; - char *dest_substr = (char *)abs_path + last_slash; - rel_path = malloc(strlen(dest_substr) + 1); - strncpy(rel_path, dest_substr, strlen(dest_substr) + 1); - // fprintf(stderr, "DEBUG: link_substr: %s\nDEBUG: dest_substr: %s\n", - // link_substr, dest_substr); - // Generate the relative path. - int has_slash = 0; - idx = 0; - do { - for (; link_substr[idx] != '/' && link_substr[idx] != 0; ++idx); - if (link_substr[idx] == 0) { - has_slash = 0; - } else { - has_slash = 1; - char *new_rel_path = malloc(strlen(rel_path) + 1 + 3); - new_rel_path[0] = '.'; - new_rel_path[1] = '.'; - new_rel_path[2] = '/'; - strncpy(new_rel_path + 3, rel_path, strlen(rel_path) + 1); - free(rel_path); - rel_path = new_rel_path; - ++idx; - } - } while (has_slash); - } - - if (abs_path) { - // Write absolute path length. - u16 = strlen(abs_path); - simple_archiver_helper_16_bit_be(&u16); - - temp_to_write = malloc(sizeof(SDArchiverInternalToWrite)); - temp_to_write->buf = malloc(2); - temp_to_write->size = 2; - memcpy(temp_to_write->buf, &u16, 2); - simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write); - - // Write absolute path. - simple_archiver_helper_16_bit_be(&u16); - temp_to_write = malloc(sizeof(SDArchiverInternalToWrite)); - temp_to_write->buf = malloc(u16 + 1); - temp_to_write->size = u16 + 1; - strncpy(temp_to_write->buf, abs_path, u16 + 1); - simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write); - } else { temp_to_write = malloc(sizeof(SDArchiverInternalToWrite)); temp_to_write->buf = malloc(2); temp_to_write->size = 2; memset(temp_to_write->buf, 0, 2); simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write); + } else { + // Get relative path. + // First get absolute path of link. + // Get abs path to dirname of link. + unsigned int link_dir_path_len = strlen(file_info->filename) + 1; + __attribute__((cleanup(free_malloced_memory))) void *link_dir_path = + malloc(link_dir_path_len); + strncpy(link_dir_path, file_info->filename, link_dir_path_len); + char *link_dirname = dirname(link_dir_path); + __attribute__((cleanup(free_malloced_memory))) void *link_dir_abs_path = + realpath(link_dirname, NULL); + if (!link_dir_abs_path) { + fprintf(stderr, + "WARNING: Failed to get absolute path of link directory!\n"); + } else { + // Get basename of link to append. + __attribute__((cleanup(free_malloced_memory))) void *link_filename = + malloc(strlen(file_info->filename) + 1); + strncpy(link_filename, file_info->filename, + strlen(file_info->filename) + 1); + char *link_basename = basename(link_filename); + // Set up full path to link. + unsigned int link_path_len = strlen(link_dir_abs_path); + __attribute__((cleanup(free_malloced_memory))) void *combined_path = + malloc(link_path_len + 1 + strlen(link_basename) + 1); + strncpy(combined_path, link_dir_abs_path, link_path_len + 1); + ((char *)combined_path)[link_path_len] = '/'; + strncpy((char *)combined_path + link_path_len + 1, link_basename, + strlen(link_basename) + 1); + // fprintf(stderr, "DEBUG: abs_path: %s\nDEBUG: combined_path: %s\n", + // (char*)abs_path, (char*)combined_path); + // Compare paths to get relative path. + // Get first non-common char. + unsigned int idx; + unsigned int last_slash; + for (idx = 0, last_slash = 0; + idx < strlen(abs_path) && idx < strlen(combined_path); ++idx) { + if (((const char *)abs_path)[idx] != + ((const char *)combined_path)[idx]) { + break; + } else if (((const char *)abs_path)[idx] == '/') { + last_slash = idx + 1; + } + } + // Get substrings of both paths. + char *link_substr = (char *)combined_path + last_slash; + char *dest_substr = (char *)abs_path + last_slash; + rel_path = malloc(strlen(dest_substr) + 1); + strncpy(rel_path, dest_substr, strlen(dest_substr) + 1); + // fprintf(stderr, "DEBUG: link_substr: %s\nDEBUG: dest_substr: %s\n", + // link_substr, dest_substr); + // Generate the relative path. + int has_slash = 0; + idx = 0; + do { + for (; link_substr[idx] != '/' && link_substr[idx] != 0; ++idx); + if (link_substr[idx] == 0) { + has_slash = 0; + } else { + has_slash = 1; + char *new_rel_path = malloc(strlen(rel_path) + 1 + 3); + new_rel_path[0] = '.'; + new_rel_path[1] = '.'; + new_rel_path[2] = '/'; + strncpy(new_rel_path + 3, rel_path, strlen(rel_path) + 1); + free(rel_path); + rel_path = new_rel_path; + ++idx; + } + } while (has_slash); + } + + if ((state->parsed->flags & 0x20) == 0) { + // Write absolute path length. + u16 = strlen(abs_path); + simple_archiver_helper_16_bit_be(&u16); + + temp_to_write = malloc(sizeof(SDArchiverInternalToWrite)); + temp_to_write->buf = malloc(2); + temp_to_write->size = 2; + memcpy(temp_to_write->buf, &u16, 2); + simple_archiver_list_add(to_write, temp_to_write, + free_internal_to_write); + + // Write absolute path. + simple_archiver_helper_16_bit_be(&u16); + temp_to_write = malloc(sizeof(SDArchiverInternalToWrite)); + temp_to_write->buf = malloc(u16 + 1); + temp_to_write->size = u16 + 1; + strncpy(temp_to_write->buf, abs_path, u16 + 1); + simple_archiver_list_add(to_write, temp_to_write, + free_internal_to_write); + } else { + fprintf(stderr, + "NOTICE: Not saving absolute path since \"--no-abs-symlink\" " + "was specified.\n"); + temp_to_write = malloc(sizeof(SDArchiverInternalToWrite)); + temp_to_write->buf = malloc(2); + temp_to_write->size = 2; + memset(temp_to_write->buf, 0, 2); + simple_archiver_list_add(to_write, temp_to_write, + free_internal_to_write); + } } if (rel_path) { @@ -803,7 +814,9 @@ int write_files_fn(void *data, void *ud) { // Write all previously set data. fprintf(stderr, "Writing symlink info: %s\n", file_info->filename); - fprintf(stderr, " abs path: %s\n", (char *)abs_path); + if ((state->parsed->flags & 0x20) == 0) { + fprintf(stderr, " abs path: %s\n", (char *)abs_path); + } fprintf(stderr, " rel path: %s\n", (char *)rel_path); simple_archiver_list_get(to_write, write_list_datas_fn, state->out_f); simple_archiver_list_free(&to_write); diff --git a/src/parser.c b/src/parser.c index 9924909..228073f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -151,6 +151,8 @@ void simple_archiver_print_usage(void) { "file's stored decompressor\n"); fprintf(stderr, "--overwrite-create : allows overwriting an archive file\n"); fprintf(stderr, "--overwrite-extract : allows overwriting when extracting\n"); + fprintf(stderr, + "--no-abs-symlink : do not store absolute paths for symlinks\n"); fprintf(stderr, "-- : specifies remaining arguments are files to archive/extract\n"); fprintf( @@ -243,6 +245,8 @@ int simple_archiver_parse_args(int argc, const char **argv, out->flags |= 0x4; } else if (strcmp(argv[0], "--overwrite-extract") == 0) { out->flags |= 0x8; + } else if (strcmp(argv[0], "--no-abs-symlink") == 0) { + out->flags |= 0x20; } else if (argv[0][0] == '-' && argv[0][1] == '-' && argv[0][2] == 0) { is_remaining_args = 1; } else if (argv[0][0] != '-') { diff --git a/src/parser.h b/src/parser.h index 4e0e729..f5a8400 100644 --- a/src/parser.h +++ b/src/parser.h @@ -30,6 +30,7 @@ typedef struct SDArchiverParsed { /// 0b xxxx x1xx - Allow create archive overwrite. /// 0b xxxx 1xxx - Allow extract overwrite. /// 0b xxx1 xxxx - Create archive to stdout or read archive from stdin. + /// 0b xx1x xxxx - Do not save absolute paths for symlinks. unsigned int flags; /// Null-terminated string. char *filename;