From: Stephen Seo Date: Mon, 27 Jan 2025 05:11:27 +0000 (+0900) Subject: WIP --prefix: Impl --prefix for archive file ver 1 X-Git-Tag: 1.12^2~15 X-Git-Url: https://git.seodisparate.com/stephenseo/css/v4-font-face.min.css?a=commitdiff_plain;h=db2147b992f74c4d4ec9384908d373214cc863fd;p=SimpleArchiver WIP --prefix: Impl --prefix for archive file ver 1 TODO: --prefix for extracting file format version 1 --prefix for archiving/extracting file format versions 2 and 3 --- diff --git a/src/archiver.c b/src/archiver.c index e3a62c7..9576aa9 100644 --- a/src/archiver.c +++ b/src/archiver.c @@ -2523,6 +2523,9 @@ int simple_archiver_write_v1(FILE *out_f, SDArchiverState *state, #endif } + const size_t prefix_length = state->parsed->prefix + ? strlen(state->parsed->prefix) + : 0; { const SDArchiverLLNode *node = symlinks_list->head; for (u32 = 0; @@ -2671,7 +2674,11 @@ int simple_archiver_write_v1(FILE *out_f, SDArchiverState *state, return SDAS_FAILED_TO_WRITE; } - size_t len = strlen(node->data); + const size_t link_length = strlen(node->data); + size_t len = link_length; + if (state->parsed->prefix) { + len += prefix_length; + } if (len >= 0xFFFF) { fprintf(stderr, "ERROR: Link name is too long!\n"); return SDAS_INVALID_PARSED_STATE; @@ -2683,26 +2690,64 @@ int simple_archiver_write_v1(FILE *out_f, SDArchiverState *state, return SDAS_FAILED_TO_WRITE; } simple_archiver_helper_16_bit_be(&u16); - if (fwrite(node->data, 1, u16 + 1, out_f) != (size_t)u16 + 1) { + if (state->parsed->prefix) { + size_t fwrite_ret = fwrite(state->parsed->prefix, + 1, + prefix_length, + out_f); + fwrite_ret += fwrite(node->data, 1, link_length + 1, out_f); + if (fwrite_ret != (size_t)u16 + 1) { + return SDAS_FAILED_TO_WRITE; + } + } else if (fwrite(node->data, 1, u16 + 1, out_f) != (size_t)u16 + 1) { return SDAS_FAILED_TO_WRITE; } if (abs_path && (state->parsed->flags & 0x20) == 0 && !is_invalid) { - len = strlen(abs_path); - if (len >= 0xFFFF) { - fprintf(stderr, - "ERROR: Symlink destination absolute path is too long!\n"); - return SDAS_INVALID_PARSED_STATE; - } + if (state->parsed->prefix) { + __attribute__((cleanup(simple_archiver_helper_cleanup_c_string))) + char *abs_path_prefixed = + simple_archiver_helper_insert_prefix_in_link_path( + state->parsed->prefix, node->data, abs_path); + if (!abs_path_prefixed) { + fprintf(stderr, + "ERROR: Failed to add prefix to abs symlink!\n"); + return SDAS_INTERNAL_ERROR; + } + const size_t abs_path_pref_length = strlen(abs_path_prefixed); + if (abs_path_pref_length >= 0xFFFF) { + fprintf(stderr, + "ERROR: Symlink destination absolute path with prefix is " + "too long!\n"); + return SDAS_INVALID_PARSED_STATE; + } - u16 = (uint16_t)len; - simple_archiver_helper_16_bit_be(&u16); - if (fwrite(&u16, 2, 1, out_f) != 1) { - return SDAS_FAILED_TO_WRITE; - } - simple_archiver_helper_16_bit_be(&u16); - if (fwrite(abs_path, 1, u16 + 1, out_f) != (size_t)u16 + 1) { - return SDAS_FAILED_TO_WRITE; + u16 = (uint16_t)abs_path_pref_length; + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(&u16, 2, 1, out_f) != 1) { + return SDAS_FAILED_TO_WRITE; + } + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(abs_path_prefixed, 1, u16 + 1, out_f) != (size_t)u16 + 1) { + return SDAS_FAILED_TO_WRITE; + } + } else { + const size_t abs_path_length = strlen(abs_path); + if (abs_path_length >= 0xFFFF) { + fprintf(stderr, + "ERROR: Symlink destination absolute path is too long!\n"); + return SDAS_INVALID_PARSED_STATE; + } + + u16 = (uint16_t)abs_path_length; + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(&u16, 2, 1, out_f) != 1) { + return SDAS_FAILED_TO_WRITE; + } + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(abs_path, 1, u16 + 1, out_f) != (size_t)u16 + 1) { + return SDAS_FAILED_TO_WRITE; + } } } else { u16 = 0; @@ -2712,21 +2757,50 @@ int simple_archiver_write_v1(FILE *out_f, SDArchiverState *state, } if (rel_path && !is_invalid) { - len = strlen(rel_path); - if (len >= 0xFFFF) { - fprintf(stderr, - "ERROR: Symlink destination relative path is too long!\n"); - return SDAS_INVALID_PARSED_STATE; - } + if (state->parsed->prefix) { + __attribute__((cleanup(simple_archiver_helper_cleanup_c_string))) + char *rel_path_prefixed = + simple_archiver_helper_insert_prefix_in_link_path( + state->parsed->prefix, node->data, rel_path); + if (!rel_path_prefixed) { + fprintf(stderr, + "ERROR: Failed to add prefix to relative symlink!\n"); + return SDAS_INTERNAL_ERROR; + } + const size_t rel_path_pref_length = strlen(rel_path_prefixed); + if (rel_path_pref_length >= 0xFFFF) { + fprintf(stderr, + "ERROR: Symlink destination relative path with prefix is " + "too long!\n"); + return SDAS_INVALID_PARSED_STATE; + } - u16 = (uint16_t)len; - simple_archiver_helper_16_bit_be(&u16); - if (fwrite(&u16, 2, 1, out_f) != 1) { - return SDAS_FAILED_TO_WRITE; - } - simple_archiver_helper_16_bit_be(&u16); - if (fwrite(rel_path, 1, u16 + 1, out_f) != (size_t)u16 + 1) { - return SDAS_FAILED_TO_WRITE; + u16 = (uint16_t)rel_path_pref_length; + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(&u16, 2, 1, out_f) != 1) { + return SDAS_FAILED_TO_WRITE; + } + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(rel_path_prefixed, 1, u16 + 1, out_f) != (size_t)u16 + 1) { + return SDAS_FAILED_TO_WRITE; + } + } else { + len = strlen(rel_path); + if (len >= 0xFFFF) { + fprintf(stderr, + "ERROR: Symlink destination relative path is too long!\n"); + return SDAS_INVALID_PARSED_STATE; + } + + u16 = (uint16_t)len; + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(&u16, 2, 1, out_f) != 1) { + return SDAS_FAILED_TO_WRITE; + } + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(rel_path, 1, u16 + 1, out_f) != (size_t)u16 + 1) { + return SDAS_FAILED_TO_WRITE; + } } } else { u16 = 0; @@ -2843,23 +2917,50 @@ int simple_archiver_write_v1(FILE *out_f, SDArchiverState *state, if (non_c_chunk_size) { *non_c_chunk_size += file_info_struct->file_size; } - size_t len = strlen(file_info_struct->filename); - if (len >= 0xFFFF) { - fprintf(stderr, "ERROR: Filename is too large!\n"); - return SDAS_INVALID_FILE; - } - u16 = (uint16_t)len; - simple_archiver_helper_16_bit_be(&u16); - if (fwrite(&u16, 2, 1, out_f) != 1) { - return SDAS_FAILED_TO_WRITE; + const size_t filename_len = strlen(file_info_struct->filename); + if (state->parsed->prefix) { + const size_t total_length = filename_len + prefix_length; + if (total_length >= 0xFFFF) { + fprintf(stderr, "ERROR: Filename with prefix is too large!\n"); + return SDAS_INVALID_FILE; + } + u16 = (uint16_t)total_length; + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(&u16, 2, 1, out_f) != 1) { + return SDAS_FAILED_TO_WRITE; + } + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(state->parsed->prefix, 1, prefix_length, out_f) + != prefix_length) { + return SDAS_FAILED_TO_WRITE; + } else if (fwrite(file_info_struct->filename, + 1, + filename_len + 1, + out_f) + != filename_len + 1) { + return SDAS_FAILED_TO_WRITE; + } + } else { + if (filename_len >= 0xFFFF) { + fprintf(stderr, "ERROR: Filename is too large!\n"); + return SDAS_INVALID_FILE; + } + u16 = (uint16_t)filename_len; + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(&u16, 2, 1, out_f) != 1) { + return SDAS_FAILED_TO_WRITE; + } + simple_archiver_helper_16_bit_be(&u16); + if (fwrite(file_info_struct->filename, 1, u16 + 1, out_f) != + (size_t)u16 + 1) { + return SDAS_FAILED_TO_WRITE; + } } - simple_archiver_helper_16_bit_be(&u16); - if (fwrite(file_info_struct->filename, 1, u16 + 1, out_f) != - (size_t)u16 + 1) { - return SDAS_FAILED_TO_WRITE; - } else if (fwrite(file_info_struct->bit_flags, 1, 4, out_f) != 4) { + + if (fwrite(file_info_struct->bit_flags, 1, 4, out_f) != 4) { return SDAS_FAILED_TO_WRITE; } + // UID and GID. // Forced UID/GID is already handled by "symlinks_and_files_from_files".