From 6f7956a06fcf92a304fae93e393e8eaee34e92d5 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 13 Aug 2012 15:54:21 -0500 Subject: [PATCH] Various minor changes and fixes. - Automatic newline when calling DEBUG() or ERROR() - Use ERROR_WITH_ERRNO instead of "%m" conversion specifier - Security data cannot be NULL anymore; just allocate one with zero entries. - Cleaned up failure case code in some functions, also documented whether the WIMs are valid after wimlib_add_image(), wimlib_delete_image(), and wimlib_export_image() fails or not. --- programs/imagex.c | 132 +++++++------- src/decomp.c | 27 ++- src/decomp.h | 12 +- src/dentry.c | 152 ++++++++-------- src/dentry.h | 6 +- src/endianness.h | 6 +- src/extract.c | 49 +++-- src/header.c | 51 +++--- src/integrity.c | 117 ++++++------ src/join.c | 38 ++-- src/lookup_table.c | 70 ++++---- src/lookup_table.h | 9 +- src/lz.c | 11 +- src/lzx-comp.c | 21 ++- src/lzx-decomp.c | 122 +++++++------ src/modify.c | 236 +++++++++++++----------- src/mount.c | 110 ++++++------ src/resource.c | 406 ++++++++++++++++++++++-------------------- src/security.c | 187 +++++++++---------- src/sha1.c | 7 +- src/split.c | 23 +-- src/util.c | 52 ++++-- src/util.h | 23 ++- src/wim.c | 220 +++++++++++------------ src/wimlib.h | 15 +- src/wimlib_internal.h | 19 +- src/write.c | 105 +++++------ src/xml.c | 158 ++++++++-------- src/xpress-comp.c | 23 ++- src/xpress-decomp.c | 17 +- 30 files changed, 1246 insertions(+), 1178 deletions(-) diff --git a/programs/imagex.c b/programs/imagex.c index 2d664084..a1b9cea2 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -195,6 +195,19 @@ static void imagex_error(const char *format, ...) va_start(va, format); fputs("ERROR: ", stderr); vfprintf(stderr, format, va); + putc('\n', stderr); + va_end(va); +} + +/* Print formatted error message to stderr. */ +static void imagex_error_with_errno(const char *format, ...) +{ + int errno_save = errno; + va_list va; + va_start(va, format); + fputs("ERROR: ", stderr); + vfprintf(stderr, format, va); + fprintf(stderr, ": %s\n", strerror(errno_save)); va_end(va); } @@ -235,7 +248,7 @@ static void usage_all() static int verify_image_exists(int image) { if (image == WIM_NO_IMAGE) { - imagex_error("Not a valid image!\n"); + imagex_error("Not a valid image"); return WIMLIB_ERR_INVALID_IMAGE; } return 0; @@ -244,7 +257,7 @@ static int verify_image_exists(int image) static int verify_image_is_single(int image) { if (image == WIM_ALL_IMAGES) { - imagex_error("Cannot specify all images for this action!\n"); + imagex_error("Cannot specify all images for this action"); return WIMLIB_ERR_INVALID_IMAGE; } return 0; @@ -271,8 +284,7 @@ static int get_compression_type(const char *optarg) return WIM_COMPRESSION_TYPE_NONE; else { imagex_error("Invalid compression type `%s'! Must be " - "\"maximum\", \"fast\", or \"none\".\n", - optarg); + "\"maximum\", \"fast\", or \"none\".", optarg); return WIM_COMPRESSION_TYPE_INVALID; } } @@ -404,7 +416,7 @@ static int imagex_apply(int argc, const char **argv) num_images = wimlib_get_num_images(w); if (argc == 2 && num_images != 1) { imagex_error("`%s' contains %d images; Please select one " - "(or all).\n", wimfile, num_images); + "(or all)", wimfile, num_images); usage(APPLY); ret = -1; goto done; @@ -491,13 +503,13 @@ static int imagex_capture(int argc, const char **argv) ret = wimlib_add_image(w, dir, name, desc, flags_element, add_image_flags); if (ret != 0) { - imagex_error("Failed to add the image `%s'!\n", dir); + imagex_error("Failed to add the image `%s'", dir); goto done; } ret = wimlib_write(w, wimfile, WIM_ALL_IMAGES, write_flags); if (ret != 0) - imagex_error("Failed to write the WIM file `%s'!\n", wimfile); + imagex_error("Failed to write the WIM file `%s'", wimfile); done: wimlib_free(w); return ret; @@ -531,9 +543,9 @@ static int imagex_delete(int argc, const char **argv) if (argc != 2) { if (argc < 1) - imagex_error("Must specify a WIM file!\n"); + imagex_error("Must specify a WIM file"); if (argc < 2) - imagex_error("Must specify an image!\n"); + imagex_error("Must specify an image"); usage(DELETE); return -1; } @@ -552,15 +564,14 @@ static int imagex_delete(int argc, const char **argv) ret = wimlib_delete_image(w, image); if (ret != 0) { - imagex_error("Failed to delete image from `%s'!\n", - wimfile); + imagex_error("Failed to delete image from `%s'", wimfile); goto done; } ret = wimlib_overwrite(w, write_flags); if (ret != 0) { imagex_error("Failed to write the file `%s' with image " - "deleted!\n", wimfile); + "deleted", wimfile); } done: wimlib_free(w); @@ -578,12 +589,12 @@ static int imagex_dir(int argc, const char **argv) int part_number; if (argc < 2) { - imagex_error("Must specify a WIM file!\n"); + imagex_error("Must specify a WIM file"); usage(DIR); return -1; } if (argc > 3) { - imagex_error("Too many arguments!\n"); + imagex_error("Too many arguments"); usage(DIR); return -1; } @@ -595,9 +606,9 @@ static int imagex_dir(int argc, const char **argv) part_number = wimlib_get_part_number(w, NULL); if (part_number != 1) { - imagex_error("`%s' is part %d of a split WIM! Specify the first part " - "to see the files.\n", - wimfile, part_number); + imagex_error("`%s' is part %d of a split WIM! Specify the " + "first part to see the files", + wimfile, part_number); ret = WIMLIB_ERR_SPLIT_UNSUPPORTED; goto done; } @@ -613,7 +624,7 @@ static int imagex_dir(int argc, const char **argv) num_images = wimlib_get_num_images(w); if (num_images != 1) { imagex_error("The file `%s' contains %d images; Please " - "select one.\n", wimfile, num_images); + "select one.", wimfile, num_images); usage(DIR); ret = -1; goto done; @@ -691,7 +702,7 @@ static int imagex_export(int argc, const char **argv) wim_is_new = false; /* Destination file exists. */ if (!S_ISREG(stbuf.st_mode)) { - imagex_error("`%s' is not a regular file!\n", + imagex_error("`%s' is not a regular file", dest_wimfile); goto done; } @@ -702,8 +713,8 @@ static int imagex_export(int argc, const char **argv) if (compression_type_specified && compression_type != wimlib_get_compression_type(dest_w)) { imagex_error("Cannot specify a compression type that is " - "not the same as that used in the " - "destination WIM!\n"); + "not the same as that used in the " + "destination WIM"); goto done; } compression_type = wimlib_get_compression_type(dest_w); @@ -715,7 +726,7 @@ static int imagex_export(int argc, const char **argv) if (ret != 0) goto done; } else { - imagex_error("Cannot stat file `%s': %m\n", + imagex_error_with_errno("Cannot stat file `%s'", dest_wimfile); goto done; } @@ -838,12 +849,12 @@ static int imagex_info(int argc, const char **argv) image = wimlib_resolve_image(w, image_num_or_name); if (image == WIM_NO_IMAGE && strcmp(image_num_or_name, "0") != 0) { - imagex_error("The image `%s' does not exist!\n", + imagex_error("The image `%s' does not exist", image_num_or_name); if (boot) imagex_error("If you would like to set the boot " - "index to 0, specify image \"0\" with " - "the --boot flag.\n"); + "index to 0, specify image \"0\" with " + "the --boot flag."); ret = WIMLIB_ERR_INVALID_IMAGE; goto done; } @@ -851,15 +862,15 @@ static int imagex_info(int argc, const char **argv) if (image == WIM_ALL_IMAGES && wimlib_get_num_images(w) > 1) { if (boot) { imagex_error("Cannot specify the --boot flag " - "without specifying a specific " - "image in a multi-image WIM!\n"); + "without specifying a specific " + "image in a multi-image WIM"); ret = WIMLIB_ERR_INVALID_IMAGE; goto done; } if (new_name) { imagex_error("Cannot specify the NEW_NAME " - "without specifying a specific " - "image in a multi-image WIM!\n"); + "without specifying a specific " + "image in a multi-image WIM"); ret = WIMLIB_ERR_INVALID_IMAGE; goto done; } @@ -870,8 +881,8 @@ static int imagex_info(int argc, const char **argv) if (!new_name && !boot) { if (image == WIM_NO_IMAGE) { - imagex_error("`%s' is not a valid image!\n", - image_num_or_name); + imagex_error("`%s' is not a valid image", + image_num_or_name); ret = WIMLIB_ERR_INVALID_IMAGE; goto done; } @@ -885,8 +896,8 @@ static int imagex_info(int argc, const char **argv) if (lookup_table) { if (total_parts != 1) { printf("Warning: Only showing the lookup table " - "for part %d of a %d-part WIM.\n", - part_number, total_parts); + "for part %d of a %d-part WIM.\n", + part_number, total_parts); } wimlib_print_lookup_table(w); } @@ -900,15 +911,16 @@ static int imagex_info(int argc, const char **argv) if (xml_out_file) { fp = fopen(xml_out_file, "wb"); if (!fp) { - imagex_error("Failed to open the file `%s' for " - "writing: %m\n", xml_out_file); + imagex_error_with_errno("Failed to open the " + "file `%s' for " + "writing ", + xml_out_file); goto done; } ret = wimlib_extract_xml_data(w, fp); if (fclose(fp) != 0) { - imagex_error("Failed to close the " - "file `%s': %m\n", - xml_out_file); + imagex_error("Failed to close the file `%s'", + xml_out_file); goto done; } @@ -922,8 +934,8 @@ static int imagex_info(int argc, const char **argv) if (metadata) { if (total_parts != 1 && part_number != 1) { imagex_error("Select part 1 of this %d-part WIM " - "to see the image metadata.\n", - total_parts); + "to see the image metadata", + total_parts); return WIMLIB_ERR_SPLIT_UNSUPPORTED; } ret = wimlib_print_metadata(w, image); @@ -932,7 +944,7 @@ static int imagex_info(int argc, const char **argv) } } else { if (total_parts != 1) { - imagex_error("Modifying a split WIM is not supported.\n"); + imagex_error("Modifying a split WIM is not supported."); return -1; } if (image == WIM_ALL_IMAGES) @@ -940,18 +952,18 @@ static int imagex_info(int argc, const char **argv) if (image == WIM_NO_IMAGE && new_name) { imagex_error("Cannot specify new_name (`%s') when " - "using image 0!\n"); + "using image 0", new_name); return -1; } if (boot) { if (image == wimlib_get_boot_idx(w)) { printf("Image %d is already marked as " - "bootable.\n", image); + "bootable.\n", image); boot = false; } else { - printf("Marking image %d as bootable.\n", - image); + printf("Marking image %d as bootable.\n", + image); wimlib_set_boot_idx(w, image); } } @@ -959,11 +971,11 @@ static int imagex_info(int argc, const char **argv) if (strcmp(wimlib_get_image_name(w, image), new_name) == 0) { printf("Image %d is already named \"%s\".\n", - image, new_name); + image, new_name); new_name = NULL; } else { - printf("Changing the name of image %d to \"%s\".\n", - image, new_name); + printf("Changing the name of image %d to " + "\"%s\".\n", image, new_name); ret = wimlib_set_image_name(w, image, new_name); if (ret != 0) goto done; @@ -974,11 +986,11 @@ static int imagex_info(int argc, const char **argv) old_desc = wimlib_get_image_description(w, image); if (old_desc && strcmp(old_desc, new_desc) == 0) { printf("The description of image %d is already " - "\"%s\".\n", image, new_desc); + "\"%s\".\n", image, new_desc); new_desc = NULL; } else { printf("Changing the description of image %d " - "to \"%s\".\n", image, new_desc); + "to \"%s\".\n", image, new_desc); ret = wimlib_set_image_descripton(w, image, new_desc); if (ret != 0) @@ -1026,8 +1038,8 @@ static int imagex_join(int argc, const char **argv) argv += optind; if (argc < 2) { - imagex_error("Must specify at least one split WIM " - "(.swm) parts to join!\n"); + imagex_error("Must specify at least one split WIM (.swm) parts " + "to join"); goto err; } output_path = argv[0]; @@ -1085,7 +1097,7 @@ static int imagex_mount_rw_or_ro(int argc, const char **argv) num_images = wimlib_get_num_images(w); if (num_images != 1) { imagex_error("The file `%s' contains %d images; Please " - "select one.\n", wimfile, num_images); + "select one", wimfile, num_images); usage((mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) ? MOUNTRW : MOUNT); ret = WIMLIB_ERR_INVALID_IMAGE; @@ -1103,8 +1115,8 @@ static int imagex_mount_rw_or_ro(int argc, const char **argv) ret = wimlib_mount(w, image, dir, mount_flags); if (ret != 0) { - imagex_error("Failed to mount image %d from `%s' on `%s'!\n", - image, wimfile, dir); + imagex_error("Failed to mount image %d from `%s' on `%s'", + image, wimfile, dir); } done: @@ -1169,7 +1181,7 @@ static int imagex_unmount(int argc, const char **argv) ret = wimlib_unmount(argv[0], unmount_flags); if (ret != 0) - imagex_error("Failed to unmount `%s'!\n", argv[0]); + imagex_error("Failed to unmount `%s'", argv[0]); return ret; } @@ -1235,7 +1247,7 @@ int main(int argc, const char **argv) int ret; if (argc < 2) { - imagex_error("No command specified!\n"); + imagex_error("No command specified"); usage_all(); return 1; } @@ -1251,14 +1263,14 @@ int main(int argc, const char **argv) ret = cmd->func(argc, argv); if (ret > 0) { imagex_error("Exiting with error code %d:\n" - " %s.\n", ret, - wimlib_get_error_string(ret)); + " %s.", ret, + wimlib_get_error_string(ret)); } return ret; } } - imagex_error("Unrecognized command: `%s'\n", argv[0]); + imagex_error("Unrecognized command: `%s'", argv[0]); usage_all(); return 1; } diff --git a/src/decomp.c b/src/decomp.c index 998ffd56..c9e0398f 100644 --- a/src/decomp.c +++ b/src/decomp.c @@ -46,10 +46,9 @@ int bitstream_read_bytes(struct input_bitstream *stream, size_t n, void *dest) /* Get the rest directly from the pointer to the data. Of course, it's * necessary to check there are really n bytes available. */ if (n > stream->data_bytes_left) { - ERROR("Unexpected end of input when " - "reading %zu bytes from bitstream " - "(only have %u bytes left)\n", n, - stream->data_bytes_left); + ERROR("Unexpected end of input when reading %zu bytes from " + "bitstream (only have %u bytes left)", + n, stream->data_bytes_left); return 1; } memcpy(p, stream->data, n); @@ -88,7 +87,7 @@ int align_input_bitstream(struct input_bitstream *stream, ret = bitstream_ensure_bits(stream, 16); if (ret != 0) { ERROR("Unexpected end of input when " - "aligning bitstream!\n"); + "aligning bitstream"); return ret; } } @@ -194,9 +193,8 @@ int make_huffman_decode_table(u16 decode_table[], uint num_syms, * tree. */ if (decode_table_pos >= table_num_entries) { ERROR("Huffman decoding table overrun: " - "pos = %u, num_entries = %u\n", - decode_table_pos, - table_num_entries); + "pos = %u, num_entries = %u", + decode_table_pos, table_num_entries); return 1; } @@ -260,7 +258,7 @@ int make_huffman_decode_table(u16 decode_table[], uint num_syms, uint i = current_code >> (code_len - num_bits); if (i >= (1 << num_bits)) { - ERROR("Invalid canonical Huffman code!\n"); + ERROR("Invalid canonical Huffman code"); return 1; } @@ -318,11 +316,10 @@ int make_huffman_decode_table(u16 decode_table[], uint num_syms, for (uint i = 0; i < num_syms; i++) { if (lens[i] != 0) { - ERROR("Lengths do not form a valid " - "canonical Huffman tree " - "(only filled %u of %u decode " - "table slots)!\n", decode_table_pos, - table_num_entries); + ERROR("Lengths do not form a valid canonical " + "Huffman tree (only filled %u of %u " + "decode table slots)", + decode_table_pos, table_num_entries); return 1; } } @@ -360,7 +357,7 @@ static int read_huffsym_near_end_of_input(struct input_bitstream *istream, bitstream_remove_bits(istream, key_size); do { if (bitsleft == 0) { - ERROR("Input stream exhausted!\n"); + ERROR("Input stream exhausted"); return 1; } key_bits = sym + bitstream_peek_bits(istream, 1); diff --git a/src/decomp.h b/src/decomp.h index 7351e253..c039582c 100644 --- a/src/decomp.h +++ b/src/decomp.h @@ -19,16 +19,16 @@ struct input_bitstream { /* A variable of length at least 32 bits that is used to hold bits that * have been read from the stream. The bits are ordered from high-order * to low-order; the next bit is always the high-order bit. */ - input_bitbuf_t bitbuf; + input_bitbuf_t bitbuf; /* Pointer to the next byte to be retrieved from the input. */ - const u8 *data; + const u8 *data; /* Number of bits in @bitbuf that are valid. */ - uint bitsleft; + uint bitsleft; /* Number of words of data that are left. */ - uint data_bytes_left; + uint data_bytes_left; }; /* Initializes a bitstream to receive its input from @data. */ @@ -99,7 +99,7 @@ static inline int bitstream_read_bits(struct input_bitstream *istream, int ret; ret = bitstream_ensure_bits(istream, num_bits); if (ret != 0) { - ERROR("bitstream_read_bits(): Input buffer exhausted\n"); + ERROR("bitstream_read_bits(): Input buffer exhausted"); return ret; } *n = bitstream_peek_bits(istream, num_bits); @@ -120,7 +120,7 @@ static inline int bitstream_read_byte(struct input_bitstream *istream) wimlib_assert(istream->bitsleft < 32); if (istream->data_bytes_left == 0) { - ERROR("bitstream_read_byte(): Input buffer exhausted\n"); + ERROR("bitstream_read_byte(): Input buffer exhausted"); return -1; } istream->data_bytes_left--; diff --git a/src/dentry.c b/src/dentry.c index 4dd26ee0..5cdc002f 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -84,9 +84,9 @@ void dentry_to_stbuf(const struct dentry *dentry, struct stat *stbuf, void dentry_update_all_timestamps(struct dentry *dentry) { u64 now = get_timestamp(); - dentry->creation_time = now; - dentry->last_access_time = now; - dentry->last_write_time = now; + dentry->creation_time = now; + dentry->last_access_time = now; + dentry->last_write_time = now; } /* @@ -148,49 +148,48 @@ int for_dentry_in_tree_depth(struct dentry *root, */ int calculate_dentry_full_path(struct dentry *dentry, void *ignore) { - int parent_len; - int len; - char *parent_full_path; char *full_path; - - FREE(dentry->full_path_utf8); - + u32 full_path_len; if (dentry_is_root(dentry)) { - dentry->full_path_utf8 = MALLOC(2); - if (!dentry->full_path_utf8) { - ERROR("Out of memory!\n"); - return WIMLIB_ERR_NOMEM; - } - - dentry->full_path_utf8[0] = '/'; - dentry->full_path_utf8[1] = '\0'; - dentry->full_path_utf8_len = 1; - return 0; - } - - if (dentry_is_root(dentry->parent)) { - parent_len = 0; - parent_full_path = ""; + full_path = MALLOC(2); + if (!full_path) + goto oom; + full_path[0] = '/'; + full_path[1] = '\0'; + full_path_len = 1; } else { - parent_len = dentry->parent->full_path_utf8_len; - parent_full_path = dentry->parent->full_path_utf8; - } + char *parent_full_path; + u32 parent_full_path_len; + const struct dentry *parent = dentry->parent; - len = parent_len + 1 + dentry->file_name_utf8_len; - full_path = MALLOC(len + 1); - if (!full_path) { - ERROR("Out of memory!\n"); - return WIMLIB_ERR_NOMEM; - } + if (dentry_is_root(parent)) { + parent_full_path = ""; + parent_full_path_len = 0; + } else { + parent_full_path = parent->full_path_utf8; + parent_full_path_len = parent->full_path_utf8_len; + } - memcpy(full_path, parent_full_path, parent_len); - full_path[parent_len] = '/'; - memcpy(full_path + parent_len + 1, dentry->file_name_utf8, - dentry->file_name_utf8_len); - full_path[len] = '\0'; + full_path_len = parent_full_path_len + 1 + + dentry->file_name_utf8_len; + full_path = MALLOC(full_path_len + 1); + if (!full_path) + goto oom; + + memcpy(full_path, parent_full_path, parent_full_path_len); + full_path[parent_full_path_len] = '/'; + memcpy(full_path + parent_full_path_len + 1, + dentry->file_name_utf8, + dentry->file_name_utf8_len); + full_path[full_path_len] = '\0'; + } + FREE(dentry->full_path_utf8); dentry->full_path_utf8 = full_path; - dentry->full_path_utf8_len = len; + dentry->full_path_utf8_len = full_path_len; return 0; +oom: + ERROR("Out of memory while calculating dentry full path"); + return WIMLIB_ERR_NOMEM; } /* @@ -361,9 +360,6 @@ static inline void dentry_common_init(struct dentry *dentry) { memset(dentry, 0, sizeof(struct dentry)); dentry->refcnt = 1; -#ifdef ENABLE_SECURITY_DATA - dentry->security_id = -1; -#endif } /* @@ -406,7 +402,7 @@ void free_dentry(struct dentry *dentry) /* Arguments for do_free_dentry(). */ struct free_dentry_args { struct lookup_table *lookup_table; - bool decrement_refcnt; + bool lt_decrement_refcnt; }; /* @@ -417,7 +413,7 @@ static int do_free_dentry(struct dentry *dentry, void *__args) { struct free_dentry_args *args = (struct free_dentry_args*)__args; - if (args->decrement_refcnt && !dentry_is_directory(dentry)) { + if (args->lt_decrement_refcnt && !dentry_is_directory(dentry)) { lookup_table_decrement_refcnt(args->lookup_table, dentry->hash); } @@ -437,14 +433,14 @@ static int do_free_dentry(struct dentry *dentry, void *__args) * reference counts in the lookup table decremented. */ void free_dentry_tree(struct dentry *root, struct lookup_table *lookup_table, - bool decrement_refcnt) + bool lt_decrement_refcnt) { if (!root || !root->parent) return; struct free_dentry_args args; args.lookup_table = lookup_table; - args.decrement_refcnt = decrement_refcnt; + args.lt_decrement_refcnt = lt_decrement_refcnt; for_dentry_in_tree_depth(root, do_free_dentry, &args); } @@ -589,7 +585,7 @@ void calculate_dir_tree_statistics(struct dentry *root, struct lookup_table *tab * Reads a directory entry from the metadata resource. */ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, - u64 offset, struct dentry *dentry) + u64 offset, struct dentry *dentry) { const u8 *p; u64 calculated_size; @@ -605,8 +601,8 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, /*Make sure the dentry really fits into the metadata resource.*/ if (offset + 8 > metadata_resource_len) { ERROR("Directory entry starting at %"PRIu64" ends past the " - "end of the metadata resource (size %"PRIu64")!\n", - offset, metadata_resource_len); + "end of the metadata resource (size %"PRIu64")", + offset, metadata_resource_len); return WIMLIB_ERR_INVALID_DENTRY; } @@ -625,9 +621,9 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, if (offset + dentry->length >= metadata_resource_len) { ERROR("Directory entry at offset %"PRIu64" and with size " - "%"PRIu64" ends past the end of the metadata resource " - "(size %"PRIu64")!\n", offset, dentry->length, - metadata_resource_len); + "%"PRIu64" ends past the end of the metadata resource " + "(size %"PRIu64")", + offset, dentry->length, metadata_resource_len); return WIMLIB_ERR_INVALID_DENTRY; } @@ -635,8 +631,8 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, * Note: The root directory entry has no name, and its length does not * include the short name length field. */ if (dentry->length < WIM_DENTRY_DISK_SIZE) { - ERROR("Directory entry has invalid length of " - "%"PRIu64" bytes\n", dentry->length); + ERROR("Directory entry has invalid length of %"PRIu64" bytes", + dentry->length); return WIMLIB_ERR_INVALID_DENTRY; } @@ -675,18 +671,18 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, if (dentry->length < calculated_size) { ERROR("Unexpected end of directory entry! (Expected " - "%"PRIu64" bytes, got %"PRIu64" bytes. " - "short_name_len = %hu, file_name_len = %hu)\n", - calculated_size, dentry->length, - short_name_len, file_name_len); + "%"PRIu64" bytes, got %"PRIu64" bytes. " + "short_name_len = %hu, file_name_len = %hu)", + calculated_size, dentry->length, + short_name_len, file_name_len); return WIMLIB_ERR_INVALID_DENTRY; } /* Read the filename. */ file_name = MALLOC(file_name_len); if (!file_name) { - ERROR("Failed to allocate %hu bytes for dentry file name!\n", - file_name_len); + ERROR("Failed to allocate %hu bytes for dentry file name", + file_name_len); return WIMLIB_ERR_NOMEM; } p = get_bytes(p, file_name_len, file_name); @@ -696,22 +692,21 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, &file_name_utf8_len); if (!file_name_utf8) { - ERROR("Failed to allocate memory to convert UTF16 " - "filename (%hu bytes) to UTF8\n", - file_name_len); - goto err_nomem2; + ERROR("Failed to allocate memory to convert UTF-16 " + "filename (%hu bytes) to UTF-8", file_name_len); + goto out_free_file_name; } /* Undocumented padding between file name and short name. This probably - * is supposed to be a terminating NULL character. */ + * is supposed to be a terminating null character. */ p += 2; /* Read the short filename. */ short_name = MALLOC(short_name_len); if (!short_name) { - ERROR("Failed to allocate %hu bytes for short filename\n", - short_name_len); - goto err_nomem1; + ERROR("Failed to allocate %hu bytes for short filename", + short_name_len); + goto out_free_file_name_utf8; } get_bytes(p, short_name_len, short_name); @@ -723,9 +718,9 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, dentry->file_name_utf8_len = file_name_utf8_len; dentry->short_name_len = short_name_len; return 0; -err_nomem1: +out_free_file_name_utf8: FREE(dentry->file_name_utf8); -err_nomem2: +out_free_file_name: FREE(dentry->file_name); return WIMLIB_ERR_NOMEM; } @@ -814,13 +809,14 @@ u8 *write_dentry_tree(const struct dentry *tree, u8 *p) * metadata resource and into the dentry tree. * * @metadata_resource: An array that contains the uncompressed metadata - * resource for the WIM file. + * resource for the WIM file. * @metadata_resource_len: The length of @metadata_resource. - * @dentry: A pointer to a struct dentry that is the root of the directory tree - * and has already been read from the metadata resource. It does not - * need to be the real root, because this procedure is called - * recursively. - * @return: True on success, false on failure. + * @dentry: A pointer to a struct dentry that is the root of the directory + * tree and has already been read from the metadata resource. It + * does not need to be the real root because this procedure is + * called recursively. + * + * @return: Zero on success, nonzero on failure. */ int read_dentry_tree(const u8 metadata_resource[], u64 metadata_resource_len, struct dentry *dentry) @@ -856,8 +852,8 @@ int read_dentry_tree(const u8 metadata_resource[], u64 metadata_resource_len, * link it to the parent and previous child. */ child = MALLOC(sizeof(struct dentry)); if (!child) { - ERROR("Failed to allocate %zu bytes for new dentry!\n", - sizeof(struct dentry)); + ERROR("Failed to allocate %zu bytes for new dentry", + sizeof(struct dentry)); ret = WIMLIB_ERR_NOMEM; break; } diff --git a/src/dentry.h b/src/dentry.h index dc80a14b..cf36e225 100644 --- a/src/dentry.h +++ b/src/dentry.h @@ -160,9 +160,11 @@ extern void init_dentry(struct dentry *dentry, const char *name); extern struct dentry *new_dentry(const char *name); extern void free_dentry(struct dentry *dentry); -extern void free_dentry_tree(struct dentry *root, struct lookup_table *lookup_table, - bool decrement_refcnt); +extern void free_dentry_tree(struct dentry *root, + struct lookup_table *lookup_table, + bool lt_decrement_refcnt); extern int increment_dentry_refcnt(struct dentry *dentry, void *ignore); +extern int decrement_dentry_refcnt(struct dentry *dentry, void *ignore); extern void calculate_dir_tree_statistics(struct dentry *root, struct lookup_table *table, diff --git a/src/endianness.h b/src/endianness.h index 55a832de..ba66b27a 100644 --- a/src/endianness.h +++ b/src/endianness.h @@ -49,9 +49,9 @@ static inline uint64_t bswap64(uint64_t n) #define to_be64(n) (n) /* In place */ -#define TO_LE16(n) (n = to_le16(n)) -#define TO_LE32(n) (n = to_le32(n)) -#define TO_LE64(n) (n = to_le64(n)) +#define TO_LE16(n) ((n) = to_le16(n)) +#define TO_LE32(n) ((n) = to_le32(n)) +#define TO_LE64(n) ((n) = to_le64(n)) static inline void array_to_le16(uint16_t *p, uint64_t n) { diff --git a/src/extract.c b/src/extract.c index 8873683f..bd3ef929 100644 --- a/src/extract.c +++ b/src/extract.c @@ -78,8 +78,9 @@ static int extract_regular_file(WIMStruct *w, if (link_type == WIM_LINK_TYPE_HARD) { if (link(lte->file_on_disk, output_path) != 0) { - ERROR("Failed to hard link `%s' to `%s': %m\n", - output_path, lte->file_on_disk); + ERROR_WITH_ERRNO("Failed to hard link " + "`%s' to `%s'", + output_path, lte->file_on_disk); return WIMLIB_ERR_LINK; } } else { @@ -116,8 +117,9 @@ static int extract_regular_file(WIMStruct *w, p2 = path_next_part(p2, NULL); strcpy(p, p2); if (symlink(buf, output_path) != 0) { - ERROR("Failed to symlink `%s' to `%s': %m\n", - buf, lte->file_on_disk); + ERROR_WITH_ERRNO("Failed to symlink `%s' to " + "`%s'", + buf, lte->file_on_disk); return WIMLIB_ERR_LINK; } @@ -129,14 +131,14 @@ static int extract_regular_file(WIMStruct *w, out_fd = open(output_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (out_fd == -1) { - ERROR("Failed to open the file `%s' for writing: " - "%m\n", output_path); + ERROR_WITH_ERRNO("Failed to open the file `%s' for writing", + output_path); return WIMLIB_ERR_OPEN; } /* Extract empty file, with no lookup table entry... */ if (!lte) { - DEBUG("Empty file `%s'\n", output_path); + DEBUG("Empty file `%s'.", output_path); ret = 0; goto done; } @@ -147,7 +149,7 @@ static int extract_regular_file(WIMStruct *w, res_entry->original_size); if (ret != 0) { - ERROR("Failed to extract resource to `%s'!\n", output_path); + ERROR("Failed to extract resource to `%s'", output_path); goto done; } @@ -183,8 +185,8 @@ static int extract_directory(struct dentry *dentry, const char *output_path) itself. */ return 0; default: - ERROR("Cannot create directory `%s': %m\n", - output_path); + ERROR_WITH_ERRNO("Cannot create directory `%s'", + output_path); return WIMLIB_ERR_MKDIR; } } @@ -225,7 +227,7 @@ static int extract_regular_file_or_directory(struct dentry *dentry, void *arg) static int extract_single_image(WIMStruct *w, int image) { - DEBUG("Extracting image %d\n", image); + DEBUG("Extracting image %d", image); int ret; ret = wimlib_select_image(w, image); @@ -248,17 +250,15 @@ static int extract_all_images(WIMStruct *w) int image; const char *image_name; - DEBUG("Attempting to extract all images from `%s'\n", w->filename); + DEBUG("Attempting to extract all images from `%s'", w->filename); memcpy(buf, w->output_dir, output_path_len); buf[output_path_len] = '/'; for (image = 1; image <= w->hdr.image_count; image++) { - buf[output_path_len + 1] = '\0'; image_name = wimlib_get_image_name(w, image); if (*image_name) { - strncat(buf + output_path_len + 1, image_name, - image_name_max_len); + strcpy(buf + output_path_len + 1, image_name); } else { /* Image name is empty. Use image number instead */ sprintf(buf + output_path_len + 1, "%d", image); @@ -270,18 +270,17 @@ static int extract_all_images(WIMStruct *w) if (ret != 0) goto done; } - ret = 0; done: + /* Restore original output directory */ buf[output_path_len + 1] = '\0'; - wimlib_set_output_dir(w, buf); - return ret; + return wimlib_set_output_dir(w, buf); } /* Extracts a single image or all images from a WIM file. */ WIMLIBAPI int wimlib_extract_image(WIMStruct *w, int image) { if (!w->output_dir) { - ERROR("No output directory selected.\n"); + ERROR("No output directory selected."); return WIMLIB_ERR_NOTDIR; } if (image == WIM_ALL_IMAGES) { @@ -299,28 +298,28 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w, int image) WIMLIBAPI int wimlib_set_output_dir(WIMStruct *w, const char *dir) { char *p; - DEBUG("Setting output directory to `%s'\n", dir); + DEBUG("Setting output directory to `%s'", dir); if (!dir) { - ERROR("Must specify a directory!\n"); + ERROR("Must specify a directory!"); return WIMLIB_ERR_INVALID_PARAM; } p = STRDUP(dir); if (!p) { - ERROR("Out of memory!\n"); + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; } if (mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) { if (errno == EEXIST) { - DEBUG("`%s' already exists\n", dir); + DEBUG("`%s' already exists", dir); goto done; } - ERROR("Cannot create directory `%s': %m\n", dir); + ERROR_WITH_ERRNO("Cannot create directory `%s'", dir); FREE(p); return WIMLIB_ERR_MKDIR; } else { - DEBUG("Created directory `%s'\n", dir); + DEBUG("Created directory `%s'", dir); } done: FREE(w->output_dir); diff --git a/src/header.c b/src/header.c index 6d00ccb4..7cd25b11 100644 --- a/src/header.c +++ b/src/header.c @@ -43,7 +43,7 @@ int read_header(FILE *fp, struct wim_header *hdr, int split_ok) u32 wim_version; u32 chunk_size; - DEBUG("Reading WIM header.\n"); + DEBUG("Reading WIM header."); bytes_read = fread(buf, 1, WIM_MAGIC_LEN, fp); @@ -53,7 +53,7 @@ int read_header(FILE *fp, struct wim_header *hdr, int split_ok) /* Byte 8 */ if (memcmp(buf, wim_magic_chars, WIM_MAGIC_LEN) != 0) { - ERROR("Invalid magic characters in WIM header\n"); + ERROR("Invalid magic characters in WIM header"); return WIMLIB_ERR_NOT_A_WIM_FILE; } @@ -66,8 +66,8 @@ int read_header(FILE *fp, struct wim_header *hdr, int split_ok) /* Byte 12 */ if (hdr_size != WIM_HEADER_DISK_SIZE) { - DEBUG("ERROR: Header is size %u (expected %u)\n", - hdr_size, WIM_HEADER_DISK_SIZE); + DEBUG("ERROR: Header is size %u (expected %u)", + hdr_size, WIM_HEADER_DISK_SIZE); return WIMLIB_ERR_INVALID_HEADER_SIZE; } @@ -83,20 +83,21 @@ int read_header(FILE *fp, struct wim_header *hdr, int split_ok) p = get_u32(buf + WIM_MAGIC_LEN + sizeof(u32), &wim_version); if (wim_version != WIM_VERSION) { - ERROR("The WIM header says the WIM version is %u, but Wimlib " - "only knows about version %u.\n", wim_version, - WIM_VERSION); + ERROR("The WIM header says the WIM version is %u, but wimlib " + "only knows about version %u", + wim_version, WIM_VERSION); return WIMLIB_ERR_UNKNOWN_VERSION; } p = get_u32(p, &hdr->flags); p = get_u32(p, &chunk_size); if (chunk_size != WIM_CHUNK_SIZE && - (hdr->flags & WIM_HDR_FLAG_COMPRESSION)) { + (hdr->flags & WIM_HDR_FLAG_COMPRESSION)) { ERROR("Unexpected chunk size of %u! Ask the author to " - "implement support for other chunk sizes. " - "(Or it might just be that the WIM header is " - "invalid.)\n", chunk_size); + "implement support for other chunk sizes.", + chunk_size); + ERROR("(Or it might just be that the WIM header is " + "invalid.)", chunk_size); return WIMLIB_ERR_INVALID_CHUNK_SIZE; } @@ -105,15 +106,15 @@ int read_header(FILE *fp, struct wim_header *hdr, int split_ok) p = get_u16(p, &hdr->total_parts); if (!split_ok && (hdr->part_number != 1 || hdr->total_parts != 1)) { - ERROR("This WIM is part %u of a %u-part WIM.\n", - hdr->part_number, hdr->total_parts); + ERROR("This WIM is part %u of a %u-part WIM", + hdr->part_number, hdr->total_parts); return WIMLIB_ERR_SPLIT_UNSUPPORTED; } p = get_u32(p, &hdr->image_count); - DEBUG("part_number = %u, total_parts = %u, image_count = %u\n", - hdr->part_number, hdr->total_parts, hdr->image_count); + DEBUG("part_number = %u, total_parts = %u, image_count = %u", + hdr->part_number, hdr->total_parts, hdr->image_count); /* Byte 48 */ @@ -139,9 +140,9 @@ int read_header(FILE *fp, struct wim_header *hdr, int split_ok) err: if (feof(fp)) - ERROR("Unexpected EOF while reading WIM header!\n"); + ERROR("Unexpected EOF while reading WIM header"); else - ERROR("Error reading WIM header: %m\n"); + ERROR_WITH_ERRNO("Error reading WIM header"); return WIMLIB_ERR_READ; } @@ -151,13 +152,13 @@ err: * @hdr: A pointer to a struct wim_header structure that describes the header. * @out: The FILE* for the output file, positioned at the appropriate * place (the beginning of the file). - * @return: True on success, false on failure. + * @return: Zero on success, nonzero on failure. */ -int write_header(const struct wim_header *hdr, FILE *out) +int write_header(const struct wim_header *hdr, FILE *out_fp) { u8 buf[WIM_HEADER_DISK_SIZE]; u8 *p; - DEBUG("Writing WIM header.\n"); + DEBUG("Writing WIM header."); p = put_bytes(buf, WIM_MAGIC_LEN, wim_magic_chars); p = put_u32(p, WIM_HEADER_DISK_SIZE); @@ -180,8 +181,8 @@ int write_header(const struct wim_header *hdr, FILE *out) p = put_u32(p, hdr->boot_idx); p = put_resource_entry(p, &hdr->integrity); memset(p, 0, WIM_UNUSED_LEN); - if (fwrite(buf, 1, sizeof(buf), out) != sizeof(buf)) { - DEBUG("Failed to write WIM header: %m\n"); + if (fwrite(buf, 1, sizeof(buf), out_fp) != sizeof(buf)) { + ERROR_WITH_ERRNO("Failed to write WIM header"); return WIMLIB_ERR_WRITE; } return 0; @@ -199,14 +200,14 @@ int init_header(struct wim_header *hdr, int ctype) break; case WIM_COMPRESSION_TYPE_LZX: hdr->flags = WIM_HDR_FLAG_COMPRESSION | - WIM_HDR_FLAG_COMPRESS_LZX; + WIM_HDR_FLAG_COMPRESS_LZX; break; case WIM_COMPRESSION_TYPE_XPRESS: hdr->flags = WIM_HDR_FLAG_COMPRESSION | - WIM_HDR_FLAG_COMPRESS_XPRESS; + WIM_HDR_FLAG_COMPRESS_XPRESS; break; default: - ERROR("Invalid compression type specified (%d)!\n", ctype); + ERROR("Invalid compression type specified (%d)", ctype); return WIMLIB_ERR_INVALID_COMPRESSION_TYPE; } hdr->total_parts = 1; diff --git a/src/integrity.c b/src/integrity.c index ade79f48..49fe514c 100644 --- a/src/integrity.c +++ b/src/integrity.c @@ -58,8 +58,8 @@ static int verify_integrity(FILE *fp, u64 num_bytes, u32 chunk_size, chunk_buf = MALLOC(chunk_size); if (!chunk_buf) { - ERROR("Failed to allocate %u byte buffer for integrity " - "chunks\n", chunk_size); + ERROR("Failed to allocate %u byte buffer for integrity chunks", + chunk_size); return WIMLIB_ERR_NOMEM; } bytes_remaining = num_bytes; @@ -76,10 +76,10 @@ static int verify_integrity(FILE *fp, u64 num_bytes, u32 chunk_size, if (fread(chunk_buf, 1, bytes_to_read, fp) != bytes_to_read) { if (feof(fp)) { ERROR("Unexpected EOF while verifying " - "integrity of WIM!\n"); + "integrity of WIM"); } else { - ERROR("File stream error while verifying " - "integrity of WIM: %m\n"); + ERROR_WITH_ERRNO("File stream error while " + "verifying integrity of WIM"); } ret = WIMLIB_ERR_READ; goto verify_integrity_error; @@ -131,33 +131,34 @@ int check_wim_integrity(WIMStruct *w, int show_progress, int *status) res_entry = &w->hdr.integrity; if (res_entry->size == 0) { - DEBUG("No integrity information.\n"); + DEBUG("No integrity information."); *status = WIM_INTEGRITY_NONEXISTENT; return 0; } ctype = wim_resource_compression_type(w, res_entry); if (res_entry->original_size < 12) { - ERROR("Integrity table resource is too short!\n"); + ERROR("Integrity table is too short"); return WIMLIB_ERR_INVALID_INTEGRITY_TABLE; } /* Read the integrity table into memory. */ buf = MALLOC(res_entry->original_size); if (!buf) { - ERROR("Out of memory (needed %zu bytes for integrity table)!\n", - res_entry->original_size); + ERROR("Out of memory (needed %zu bytes for integrity table)", + res_entry->original_size); ret = WIMLIB_ERR_NOMEM; - goto check_integrity_error; + goto out; } - ret = read_full_resource(w->fp, res_entry->size, res_entry->original_size, + ret = read_full_resource(w->fp, res_entry->size, + res_entry->original_size, res_entry->offset, ctype, buf); if (ret != 0) { ERROR("Failed to read integrity table (size = %"PRIu64", " - "original_size = %"PRIu64", offset = " - "%"PRIu64", ctype = %d\n", - (u64)res_entry->size, res_entry->original_size, - res_entry->offset, ctype); - goto check_integrity_error; + "original_size = %"PRIu64", offset = " + "%"PRIu64", ctype = %d", + (u64)res_entry->size, res_entry->original_size, + res_entry->offset, ctype); + goto out; } p = get_u32(buf, &integrity_table_size); @@ -169,27 +170,31 @@ int check_wim_integrity(WIMStruct *w, int show_progress, int *status) /* Make sure the integrity table is the right size. */ if (integrity_table_size != res_entry->original_size) { ERROR("Inconsistent integrity table sizes: header says %u " - "bytes but resource entry says " - "%"PRIu64" bytes\n", integrity_table_size, - res_entry->original_size); - + "bytes but resource entry says " + "%"PRIu64" bytes", + integrity_table_size, res_entry->original_size); ret = WIMLIB_ERR_INVALID_INTEGRITY_TABLE; - goto check_integrity_error; + goto out; } - DEBUG("integrity_table_size = %u, num_entries = %u, chunk_size = %u\n", - integrity_table_size, num_entries, chunk_size); + DEBUG("integrity_table_size = %u, num_entries = %u, chunk_size = %u", + integrity_table_size, num_entries, chunk_size); expected_size = num_entries * WIM_HASH_SIZE + 12; if (integrity_table_size != expected_size) { ERROR("Integrity table is %u bytes, but expected %"PRIu64" " - "bytes to hold %u entries!\n", - integrity_table_size, - expected_size, num_entries); + "bytes to hold %u entries", + integrity_table_size, expected_size, num_entries); + ret = WIMLIB_ERR_INVALID_INTEGRITY_TABLE; + goto out; + } + + if (chunk_size == 0) { + ERROR("Cannot use integrity chunk size of 0"); ret = WIMLIB_ERR_INVALID_INTEGRITY_TABLE; - goto check_integrity_error; + goto out; } end_lookup_table_offset = w->hdr.lookup_table_res_entry.offset + @@ -197,34 +202,33 @@ int check_wim_integrity(WIMStruct *w, int show_progress, int *status) bytes_to_check = end_lookup_table_offset - WIM_HEADER_DISK_SIZE; - expected_num_entries = bytes_to_check / chunk_size + - (bytes_to_check % chunk_size != 0); + expected_num_entries = (bytes_to_check + chunk_size - 1) / chunk_size; if (num_entries != expected_num_entries) { - ERROR("%"PRIu64 " entries would be required to checksum " - "the %"PRIu64" bytes from the end of the header to the\n" - "end of the lookup table with a chunk size of %u, but " - "there were only %u entries!\n", - expected_num_entries, bytes_to_check, chunk_size, - num_entries); + ERROR("%"PRIu64" entries would be required to checksum " + "the %"PRIu64" bytes from the end of the header to the", + expected_num_entries, bytes_to_check); + ERROR("end of the lookup table with a chunk size of %u, but " + "there were only %u entries", expected_num_entries, + bytes_to_check, chunk_size, num_entries); ret = WIMLIB_ERR_INVALID_INTEGRITY_TABLE; - goto check_integrity_error; + goto out; } /* The integrity checking starts after the header, so seek to the offset * in the WIM after the header. */ if (fseeko(w->fp, WIM_HEADER_DISK_SIZE, SEEK_SET) != 0) { - ERROR("Failed to seek to byte %u of WIM to check " - "integrity: %m\n", WIM_HEADER_DISK_SIZE); + ERROR_WITH_ERRNO("Failed to seek to byte %u of WIM to check " + "integrity", WIM_HEADER_DISK_SIZE); ret = WIMLIB_ERR_READ; - goto check_integrity_error; + goto out; } /* call verify_integrity(), which does the actual checking of the SHA1 * message digests. */ ret = verify_integrity(w->fp, bytes_to_check, chunk_size, p, show_progress, status); -check_integrity_error: +out: FREE(buf); return ret; } @@ -251,11 +255,10 @@ int write_integrity_table(FILE *out, u64 end_header_offset, u32 integrity_table_size; int ret; - DEBUG("Writing integrity table\n"); + DEBUG("Writing integrity table"); if (fseeko(out, end_header_offset, SEEK_SET) != 0) { - ERROR("Failed to seek to byte %"PRIu64" of WIM " - "to calculate integrity data: %m\n", - end_header_offset); + ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" of WIM to " + "calculate integrity data", end_header_offset); return WIMLIB_ERR_WRITE; } @@ -264,13 +267,13 @@ int write_integrity_table(FILE *out, u64 end_header_offset, (bytes_to_check % INTEGRITY_CHUNK_SIZE != 0); integrity_table_size = num_entries * WIM_HASH_SIZE + 3 * sizeof(u32); - DEBUG("integrity table size = %u\n", integrity_table_size); + DEBUG("integrity table size = %u", integrity_table_size); buf = MALLOC(integrity_table_size); if (!buf) { - ERROR("Failed to allocate %u bytes for integrity table!\n", - integrity_table_size); + ERROR("Failed to allocate %u bytes for integrity table", + integrity_table_size); return WIMLIB_ERR_NOMEM; } @@ -280,15 +283,15 @@ int write_integrity_table(FILE *out, u64 end_header_offset, chunk_buf = MALLOC(INTEGRITY_CHUNK_SIZE); if (!chunk_buf) { - ERROR("Failed to allocate %u bytes for integrity chunk " - "buffer!\n", INTEGRITY_CHUNK_SIZE); + ERROR("Failed to allocate %u bytes for integrity chunk buffer", + INTEGRITY_CHUNK_SIZE); ret = WIMLIB_ERR_NOMEM; goto err2; } bytes_remaining = bytes_to_check; - DEBUG("Bytes to check = %"PRIu64"\n", bytes_to_check); + DEBUG("Bytes to check = %"PRIu64, bytes_to_check); while (bytes_remaining != 0) { @@ -309,10 +312,11 @@ int write_integrity_table(FILE *out, u64 end_header_offset, if (bytes_read != bytes_to_read) { if (feof(out)) { ERROR("Unexpected EOF while calculating " - "integrity checksums!\n"); + "integrity checksums"); } else { - ERROR("File stream error while calculating " - "integrity checksums: %m\n"); + ERROR_WITH_ERRNO("File stream error while " + "calculating integrity " + "checksums"); } ret = WIMLIB_ERR_READ; goto err2; @@ -327,14 +331,15 @@ int write_integrity_table(FILE *out, u64 end_header_offset, " "); if (fseeko(out, 0, SEEK_END) != 0) { - ERROR("Failed to seek to end of WIM to write integrity " - "table: %m\n"); + ERROR_WITH_ERRNO("Failed to seek to end of WIM to write " + "integrity table"); ret = WIMLIB_ERR_WRITE; goto err1; } if (fwrite(buf, 1, integrity_table_size, out) != integrity_table_size) { - ERROR("Failed to write integrity table to end of WIM: %m\n"); + ERROR_WITH_ERRNO("Failed to write integrity table to end of " + "WIM"); ret = WIMLIB_ERR_WRITE; goto err1; } diff --git a/src/join.c b/src/join.c index 3b96695f..c6fbc82a 100644 --- a/src/join.c +++ b/src/join.c @@ -40,14 +40,14 @@ static int join_wims(WIMStruct **swms, uint num_swms, WIMStruct *joined_wim, if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS) { off_t cur_offset = ftello(out_fp); printf("Writing resources from part %u of %u " - "(%"PRIu64" of %"PRIu64" bytes, %.0f%% done)\n", - i + 1, num_swms, - cur_offset, total_bytes, - (double)cur_offset / total_bytes * 100.0); + "(%"PRIu64" of %"PRIu64" bytes, %.0f%% done)\n", + i + 1, num_swms, cur_offset, total_bytes, + (double)cur_offset / total_bytes * 100.0); } swms[i]->fp = fopen(swms[i]->filename, "rb"); if (!swms[i]->fp) { - ERROR("Failed to reopen `%s': %m\n", swms[i]->filename); + ERROR_WITH_ERRNO("Failed to reopen `%s'", + swms[i]->filename); return WIMLIB_ERR_OPEN; } swms[i]->out_fp = out_fp; @@ -67,7 +67,7 @@ static int join_wims(WIMStruct **swms, uint num_swms, WIMStruct *joined_wim, swms[0]->hdr.image_count); for (i = 0; i < swms[0]->hdr.image_count; i++) { - ret = copy_resource(swms[0]->image_metadata[i].lookup_table_entry, + ret = copy_resource(swms[0]->image_metadata[i].metadata_lte, swms[0]); if (ret != 0) return ret; @@ -88,7 +88,7 @@ static int join_wims(WIMStruct **swms, uint num_swms, WIMStruct *joined_wim, off_t xml_data_offset = ftello(out_fp); if (lookup_table_offset == -1 || xml_data_offset == -1) { - ERROR("Failed to get file offset: %m\n"); + ERROR_WITH_ERRNO("Failed to get file offset"); return WIMLIB_ERR_WRITE; } swms[0]->hdr.lookup_table_res_entry.offset = lookup_table_offset; @@ -139,37 +139,37 @@ WIMLIBAPI int wimlib_join(const char **swm_names, int num_swms, } else { if (wimlib_get_compression_type(w) != ctype) { ERROR("The split WIMs do not all have the same " - "compression type!\n"); + "compression type"); ret = WIMLIB_ERR_SPLIT_INVALID; goto err; } if (memcmp(guid, w->hdr.guid, WIM_GID_LEN) != 0) { - ERROR("The split WIMs do not all have the " - "same GUID!\n"); + ERROR("The split WIMs do not all have the same " + "GUID"); ret = WIMLIB_ERR_SPLIT_INVALID; goto err; } } if (w->hdr.total_parts != num_swms) { ERROR("`%s' (part %d) says there are %d total parts, " - "but %d parts were specified!\n", - swm_names[i], w->hdr.part_number, - w->hdr.total_parts, num_swms); + "but %d parts were specified", + swm_names[i], w->hdr.part_number, + w->hdr.total_parts, num_swms); ret = WIMLIB_ERR_SPLIT_INVALID; goto err; } if (w->hdr.part_number == 0 || w->hdr.part_number > num_swms) { - ERROR("`%s' says it is part %d, but expected a number\n" - "between 1 and %d!\n", - swm_names[i], w->hdr.part_number, num_swms); + ERROR("`%s' says it is part %d, but expected a number " + "between 1 and %d", + swm_names[i], w->hdr.part_number, num_swms); ret = WIMLIB_ERR_SPLIT_INVALID; goto err; } part_idx = w->hdr.part_number - 1; if (swms[part_idx] != NULL) { - ERROR("`%s' and `%s' both say they are part %d of %d!\n", - swm_names[i], swms[part_idx]->filename, - w->hdr.part_number, num_swms); + ERROR("`%s' and `%s' both say they are part %d of %d", + swm_names[i], swms[part_idx]->filename, + w->hdr.part_number, num_swms); ret = WIMLIB_ERR_SPLIT_INVALID; goto err; } diff --git a/src/lookup_table.c b/src/lookup_table.c index 1f6384cf..a24b02eb 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -33,7 +33,7 @@ struct lookup_table *new_lookup_table(size_t capacity) struct lookup_table *table; struct lookup_table_entry **array; - table = CALLOC(1, sizeof(struct lookup_table)); + table = MALLOC(sizeof(struct lookup_table)); if (!table) goto err; array = CALLOC(capacity, sizeof(array[0])); @@ -46,8 +46,8 @@ struct lookup_table *new_lookup_table(size_t capacity) table->array = array; return table; err: - ERROR("Failed to allocate memory for lookup table with capacity " - "%zu\n", capacity); + ERROR("Failed to allocate memory for lookup table with capacity %zu", + capacity); return NULL; } @@ -58,14 +58,14 @@ struct lookup_table_entry *new_lookup_table_entry() lte = MALLOC(sizeof(struct lookup_table_entry)); if (!lte) { ERROR("Out of memory (tried to allocate %zu bytes for " - "lookup table entry)\n", - sizeof(struct lookup_table_entry)); + "lookup table entry)", + sizeof(struct lookup_table_entry)); return NULL; } + lte->next = NULL; lte->file_on_disk = NULL; lte->other_wim_fp = NULL; - lte->next = NULL; lte->part_number = 1; lte->refcnt = 1; lte->staging_num_times_opened = 0; @@ -149,7 +149,7 @@ void lookup_table_decrement_refcnt(struct lookup_table* table, const u8 hash[]) * Looks up an entry in the lookup table. */ struct lookup_table_entry *lookup_resource(const struct lookup_table *lookup_table, - const u8 hash[]) + const u8 hash[]) { size_t pos; struct lookup_table_entry *lte; @@ -169,7 +169,8 @@ struct lookup_table_entry *lookup_resource(const struct lookup_table *lookup_tab * return nonzero if any call to the function returns nonzero. */ int for_lookup_table_entry(struct lookup_table *table, - int (*visitor)(struct lookup_table_entry *, void *), void *arg) + int (*visitor)(struct lookup_table_entry *, void *), + void *arg) { struct lookup_table_entry *entry, *next; size_t i; @@ -209,12 +210,12 @@ int read_lookup_table(FILE *fp, u64 offset, u64 size, const u8 *p; struct lookup_table_entry *cur_entry; - DEBUG("Reading lookup table: offset %"PRIu64", size %"PRIu64"\n", - offset, size); + DEBUG("Reading lookup table: offset %"PRIu64", size %"PRIu64"", + offset, size); if (fseeko(fp, offset, SEEK_SET) != 0) { - ERROR("Failed to seek to byte %"PRIu64" to read lookup table: " - "%m\n", offset); + ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" to read " + "lookup table", offset); return WIMLIB_ERR_READ; } @@ -226,30 +227,30 @@ int read_lookup_table(FILE *fp, u64 offset, u64 size, while (num_entries--) { if (fread(buf, 1, sizeof(buf), fp) != sizeof(buf)) { if (feof(fp)) { - ERROR("Unexpected EOF in lookup table!\n"); + ERROR("Unexpected EOF in WIM lookup table!"); } else { - ERROR("Stream read error while reading " - "lookup table!\n"); + ERROR_WITH_ERRNO("Error reading WIM lookup " + "table"); } ret = WIMLIB_ERR_READ; - goto err; + goto out; } cur_entry = new_lookup_table_entry(); if (!cur_entry) { ret = WIMLIB_ERR_NOMEM; - goto err; + goto out; } p = get_resource_entry(buf, &cur_entry->resource_entry); p = get_u16(p, &cur_entry->part_number); p = get_u32(p, &cur_entry->refcnt); - p = get_bytes(p, sizeof(cur_entry->hash), cur_entry->hash); + p = get_bytes(p, WIM_HASH_SIZE, cur_entry->hash); lookup_table_insert(table, cur_entry); } - DEBUG("Done reading lookup table.\n"); + DEBUG("Done reading lookup table."); *table_ret = table; return 0; -err: +out: free_lookup_table(table); return ret; } @@ -276,20 +277,21 @@ int write_lookup_table_entry(struct lookup_table_entry *lte, void *__out) return 0; if (lte->output_resource_entry.flags & WIM_RESHDR_FLAG_METADATA) - DEBUG("Writing metadata entry at %lu\n", ftello(out)); + DEBUG("Writing metadata entry at %lu", ftello(out)); p = put_resource_entry(buf, <e->output_resource_entry); p = put_u16(p, lte->part_number); p = put_u32(p, lte->out_refcnt); p = put_bytes(p, WIM_HASH_SIZE, lte->hash); if (fwrite(buf, 1, sizeof(buf), out) != sizeof(buf)) { - ERROR("Failed to write lookup table entry: %m\n"); + ERROR_WITH_ERRNO("Failed to write lookup table entry"); return WIMLIB_ERR_WRITE; } return 0; } -static int do_free_lookup_table_entry(struct lookup_table_entry *entry, void *ignore) +static int do_free_lookup_table_entry(struct lookup_table_entry *entry, + void *ignore) { free_lookup_table_entry(entry); return 0; @@ -297,15 +299,13 @@ static int do_free_lookup_table_entry(struct lookup_table_entry *entry, void *ig void free_lookup_table(struct lookup_table *table) { - if (table) { - if (table->array) { - for_lookup_table_entry(table, - do_free_lookup_table_entry, - NULL); - FREE(table->array); - } - FREE(table); + if (!table) + return; + if (table->array) { + for_lookup_table_entry(table, do_free_lookup_table_entry, NULL); + FREE(table->array); } + FREE(table); } int zero_out_refcnts(struct lookup_table_entry *entry, void *ignore) @@ -317,11 +317,11 @@ int zero_out_refcnts(struct lookup_table_entry *entry, void *ignore) int print_lookup_table_entry(struct lookup_table_entry *entry, void *ignore) { printf("Offset = %"PRIu64" bytes\n", - entry->resource_entry.offset); + entry->resource_entry.offset); printf("Size = %"PRIu64" bytes\n", - (u64)entry->resource_entry.size); + (u64)entry->resource_entry.size); printf("Original size = %"PRIu64" bytes\n", - entry->resource_entry.original_size); + entry->resource_entry.original_size); printf("Part Number = %hu\n", entry->part_number); printf("Reference Count = %u\n", entry->refcnt); printf("Hash = "); @@ -339,7 +339,7 @@ int print_lookup_table_entry(struct lookup_table_entry *entry, void *ignore) fputs("WIM_RESHDR_FLAG_SPANNED, ", stdout); putchar('\n'); if (entry->file_on_disk) - printf("File on Disk = \"%s\"\n", entry->file_on_disk); + printf("File on Disk = `%s'\n", entry->file_on_disk); putchar('\n'); return 0; } diff --git a/src/lookup_table.h b/src/lookup_table.h index 91684c43..6deb86fc 100644 --- a/src/lookup_table.h +++ b/src/lookup_table.h @@ -99,7 +99,10 @@ struct lookup_table_entry { * * output_resource_entry is the struct resource_entry for the position of the * file resource when written to the output file. */ - u32 out_refcnt; + union { + u32 out_refcnt; + bool refcnt_is_incremented; + }; struct resource_entry output_resource_entry; }; @@ -165,8 +168,8 @@ static inline void lookup_table_remove(struct lookup_table *table, static inline struct resource_entry* wim_metadata_resource_entry(WIMStruct *w) { - return &w->image_metadata[w->current_image - 1]. - lookup_table_entry->resource_entry; + return &w->image_metadata[ + w->current_image - 1].metadata_lte->resource_entry; } #endif diff --git a/src/lz.c b/src/lz.c index 94cfc696..f079fc8e 100644 --- a/src/lz.c +++ b/src/lz.c @@ -62,8 +62,7 @@ static inline uint update_hash(uint hash, u8 c) * indicating the end of the hash chain. */ static inline uint insert_string(u16 hash_tab[], u16 prev_tab[], - const u8 window[], uint str_pos, - uint hash) + const u8 window[], uint str_pos, uint hash) { hash = update_hash(hash, window[str_pos + 2]); prev_tab[str_pos] = hash_tab[hash]; @@ -206,10 +205,10 @@ static uint longest_match(const u8 window[], uint bytes_remaining, * intermediate representation of a match or literal byte. */ uint lz_analyze_block(const u8 uncompressed_data[], uint uncompressed_len, - u32 match_tab[], lz_record_match_t record_match, - lz_record_literal_t record_literal, void *record_match_arg1, - void *record_match_arg2, void *record_literal_arg, - const struct lz_params *params) + u32 match_tab[], lz_record_match_t record_match, + lz_record_literal_t record_literal, void *record_match_arg1, + void *record_match_arg2, void *record_literal_arg, + const struct lz_params *params) { uint cur_match_pos = 0; uint cur_input_pos = 0; diff --git a/src/lzx-comp.c b/src/lzx-comp.c index 0f120791..601513dd 100644 --- a/src/lzx-comp.c +++ b/src/lzx-comp.c @@ -639,7 +639,7 @@ int lzx_compress(const void *__uncompressed_data, uint uncompressed_len, uint i; int ret; - LZX_DEBUG("uncompressed_len = %u\n", uncompressed_len); + LZX_DEBUG("uncompressed_len = %u", uncompressed_len); if (uncompressed_len < 100) return 1; @@ -667,8 +667,7 @@ int lzx_compress(const void *__uncompressed_data, uint uncompressed_len, &queue, freq_tabs.main_freq_table, &lzx_lz_params); - LZX_DEBUG("using %u matches\n", num_matches); - + LZX_DEBUG("using %u matches", num_matches); lzx_make_huffman_codes(&freq_tabs, &codes); @@ -729,31 +728,31 @@ int lzx_compress(const void *__uncompressed_data, uint uncompressed_len, compressed_len = ostream.bit_output - (u8*)compressed_data; - LZX_DEBUG("Compressed %u => %u bytes\n", - uncompressed_len, compressed_len); + LZX_DEBUG("Compressed %u => %u bytes", + uncompressed_len, compressed_len); *compressed_len_ret = compressed_len; #ifdef ENABLE_VERIFY_COMPRESSION /* Verify that we really get the same thing back when decompressing. */ + LZX_DEBUG("Verifying the compressed data."); u8 buf[uncompressed_len]; ret = lzx_decompress(compressed_data, compressed_len, buf, uncompressed_len); if (ret != 0) { - ERROR("ERROR: Failed to decompress data we compressed!\n"); - exit(0); + ERROR("lzx_compress(): Failed to decompress data we compressed"); abort(); } for (i = 0; i < uncompressed_len; i++) { if (buf[i] != *((u8*)__uncompressed_data + i)) { - ERROR("Data we compressed didn't decompress to " - "the original data (difference at byte %u of " - "%u)\n", i + 1, uncompressed_len); + ERROR("lzx_compress(): Data we compressed didn't " + "decompress to the original data (difference at " + "byte %u of %u)", i + 1, uncompressed_len); abort(); } } - LZX_DEBUG("Compression verified to be correct.\n"); + LZX_DEBUG("Compression verified to be correct."); #endif return 0; diff --git a/src/lzx-decomp.c b/src/lzx-decomp.c index 267320ab..9b5ea988 100644 --- a/src/lzx-decomp.c +++ b/src/lzx-decomp.c @@ -323,7 +323,7 @@ static int lzx_read_block_header(struct input_bitstream *istream, ret = bitstream_ensure_bits(istream, 4); if (ret != 0) { - ERROR("Input stream overrun!\n"); + ERROR("LZX input stream overrun"); return ret; } @@ -347,7 +347,6 @@ static int lzx_read_block_header(struct input_bitstream *istream, switch (block_type) { case LZX_BLOCKTYPE_ALIGNED: - /* Read the path lengths for the elements of the aligned tree, * then build it. */ @@ -360,14 +359,15 @@ static int lzx_read_block_header(struct input_bitstream *istream, tables->alignedtree_lens[i] = len; } - LZX_DEBUG("Building the aligned tree.\n"); + LZX_DEBUG("Building the aligned tree."); ret = make_huffman_decode_table(tables->alignedtree_decode_table, - LZX_ALIGNEDTREE_NUM_SYMBOLS, - LZX_ALIGNEDTREE_TABLEBITS, - tables->alignedtree_lens, 8); + LZX_ALIGNEDTREE_NUM_SYMBOLS, + LZX_ALIGNEDTREE_TABLEBITS, + tables->alignedtree_lens, + 8); if (ret != 0) { - ERROR("Failed to make the decode table for " - "the aligned offset tree!\n"); + ERROR("lzx_decompress(): Failed to make the decode " + "table for the aligned offset tree"); return ret; } @@ -376,36 +376,37 @@ static int lzx_read_block_header(struct input_bitstream *istream, case LZX_BLOCKTYPE_VERBATIM: if (block_type == LZX_BLOCKTYPE_VERBATIM) - LZX_DEBUG("Found verbatim block\n"); + LZX_DEBUG("Found verbatim block."); - LZX_DEBUG("Reading path lengths for main tree.\n"); + LZX_DEBUG("Reading path lengths for main tree."); /* Read the path lengths for the first 256 elements of the main * tree. */ ret = lzx_read_code_lens(istream, tables->maintree_lens, LZX_NUM_CHARS); if (ret != 0) { - ERROR("Failed to read the code lengths for " - "the first 256 elements of the main " - "tree!\n"); + ERROR("lzx_decompress(): Failed to read the code " + "lengths for the first 256 elements of the " + "main tree"); return ret; } /* Read the path lengths for the remaining elements of the main * tree. */ LZX_DEBUG("Reading path lengths for remaining elements of " - "main tree (%d elements).\n", - LZX_MAINTREE_NUM_SYMBOLS - LZX_NUM_CHARS); + "main tree (%d elements).", + LZX_MAINTREE_NUM_SYMBOLS - LZX_NUM_CHARS); ret = lzx_read_code_lens(istream, tables->maintree_lens + LZX_NUM_CHARS, LZX_MAINTREE_NUM_SYMBOLS - LZX_NUM_CHARS); if (ret != 0) { - ERROR("Failed to read the path lengths for " - "the remaining elements of the main " - "tree!\n"); + ERROR("lzx_decompress(): Failed to read the path " + "lengths for the remaining elements of the main " + "tree"); return ret; } - LZX_DEBUG("Building the Huffman decoding table for the main tree.\n"); + LZX_DEBUG("Building the Huffman decoding " + "table for the main tree."); ret = make_huffman_decode_table(tables->maintree_decode_table, LZX_MAINTREE_NUM_SYMBOLS, @@ -413,36 +414,36 @@ static int lzx_read_block_header(struct input_bitstream *istream, tables->maintree_lens, LZX_MAX_CODEWORD_LEN); if (ret != 0) { - ERROR("Failed to make the decode table for " - "the main tree!\n"); + ERROR("lzx_decompress(): Failed to make the decode " + "table for the main tree"); return ret; } - LZX_DEBUG("Reading path lengths for the length tree.\n"); + LZX_DEBUG("Reading path lengths for the length tree."); ret = lzx_read_code_lens(istream, tables->lentree_lens, LZX_LENTREE_NUM_SYMBOLS); if (ret != 0) { - ERROR("Failed to read the path lengths " - "for the length tree!\n"); + ERROR("lzx_decompress(): Failed to read the path " + "lengths for the length tree"); return ret; } - LZX_DEBUG("Building the length tree.\n"); + LZX_DEBUG("Building the length tree."); ret = make_huffman_decode_table(tables->lentree_decode_table, LZX_LENTREE_NUM_SYMBOLS, LZX_LENTREE_TABLEBITS, tables->lentree_lens, LZX_MAX_CODEWORD_LEN); if (ret != 0) { - ERROR("Failed to build the length Huffman " - "tree!\n"); + ERROR("lzx_decompress(): Failed to build the length " + "Huffman tree"); return ret; } break; case LZX_BLOCKTYPE_UNCOMPRESSED: - LZX_DEBUG("Found uncompressed block\n"); + LZX_DEBUG("Found uncompressed block."); ret = align_input_bitstream(istream, true); if (ret != 0) return ret; @@ -455,7 +456,7 @@ static int lzx_read_block_header(struct input_bitstream *istream, queue->R2 = R[2]; break; default: - LZX_DEBUG("Found invalid block\n"); + LZX_DEBUG("Found invalid block."); return 1; } *block_type_ret = block_type; @@ -613,16 +614,15 @@ static int lzx_decode_match(int main_element, int block_type, match_src = match_dest - match_offset; if (match_len > bytes_remaining) { - ERROR("Match of length %d bytes overflows uncompressed " - "block size!\n", match_len); + ERROR("lzx_decode_match(): Match of length %d bytes overflows " + "uncompressed block size", match_len); return -1; } if (match_src < window) { - ERROR("Match of length %d bytes references data " - "before window (match_offset = %d, " - "window_pos = %d)\n", match_len, - match_offset, window_pos); + ERROR("lzx_decode_match(): Match of length %d bytes references " + "data before window (match_offset = %d, window_pos = %d)", + match_len, match_offset, window_pos); return -1; } @@ -751,9 +751,9 @@ int lzx_decompress(const void *compressed_data, uint compressed_len, int block_type; LZX_DEBUG("lzx_decompress (compressed_data = %p, compressed_len = %d, " - "uncompressed_data = %p, uncompressed_len = %d)\n", - compressed_data, compressed_len, uncompressed_data, - uncompressed_len); + "uncompressed_data = %p, uncompressed_len = %d).", + compressed_data, compressed_len, + uncompressed_data, uncompressed_len); wimlib_assert(uncompressed_len <= 32768); @@ -773,37 +773,41 @@ int lzx_decompress(const void *compressed_data, uint compressed_len, while (bytes_remaining != 0) { - LZX_DEBUG("Reading block header.\n"); + LZX_DEBUG("Reading block header."); ret = lzx_read_block_header(&istream, &block_size, &block_type, &tables, &queue); if (ret != 0) return ret; - LZX_DEBUG("block_size = %d, bytes_remaining = %d\n", - block_size, bytes_remaining); + LZX_DEBUG("block_size = %d, bytes_remaining = %d.", + block_size, bytes_remaining); if (block_size > bytes_remaining) { - ERROR("Expected a block size of at most %d " - "bytes (found %d bytes)!\n", - bytes_remaining, block_size); + ERROR("lzx_decompress(): Expected a block size of at " + "most %d bytes (found %d bytes)", + bytes_remaining, block_size); return 1; } - if (block_type == LZX_BLOCKTYPE_VERBATIM || - block_type == LZX_BLOCKTYPE_ALIGNED) { + switch (block_type) { + case LZX_BLOCKTYPE_VERBATIM: + case LZX_BLOCKTYPE_ALIGNED: if (block_type == LZX_BLOCKTYPE_VERBATIM) - LZX_DEBUG("LZX_BLOCKTYPE_VERBATIM\n"); + LZX_DEBUG("LZX_BLOCKTYPE_VERBATIM"); else - LZX_DEBUG("LZX_BLOCKTYPE_ALIGNED\n"); + LZX_DEBUG("LZX_BLOCKTYPE_ALIGNED"); ret = lzx_decompress_block(block_type, - block_size, uncompressed_data, - uncompressed_len - bytes_remaining, - &tables, &queue, &istream); + block_size, + uncompressed_data, + uncompressed_len - + bytes_remaining, + &tables, &queue, &istream); if (ret != 0) return ret; - } else if (block_type == LZX_BLOCKTYPE_UNCOMPRESSED) { - LZX_DEBUG("LZX_BLOCKTYPE_UNCOMPRESSED\n"); + break; + case LZX_BLOCKTYPE_UNCOMPRESSED: + LZX_DEBUG("LZX_BLOCKTYPE_UNCOMPRESSED"); ret = bitstream_read_bytes(&istream, block_size, uncompressed_data + uncompressed_len - @@ -812,20 +816,22 @@ int lzx_decompress(const void *compressed_data, uint compressed_len, return ret; if (block_size & 1) align_input_bitstream(&istream, false); - } else { - ERROR("Unrecognized block type!\n"); - return 1; + break; + default: + wimlib_assert(0); + break; } bytes_remaining -= block_size; if (bytes_remaining != 0) - LZX_DEBUG("%d bytes remaining\n", bytes_remaining); + LZX_DEBUG("%d bytes remaining.", bytes_remaining); } if (uncompressed_len >= 10) - undo_call_insn_preprocessing(uncompressed_data, uncompressed_len); + undo_call_insn_preprocessing(uncompressed_data, + uncompressed_len); return 0; } diff --git a/src/modify.c b/src/modify.c index ce362d69..4a28e0a4 100644 --- a/src/modify.c +++ b/src/modify.c @@ -37,15 +37,28 @@ #include #include +static void destroy_image_metadata(struct image_metadata *imd, + struct lookup_table *lt) +{ + free_dentry_tree(imd->root_dentry, lt, true); +#ifdef ENABLE_SECURITY_DATA + free_security_data(imd->security_data); +#endif + + /* Get rid of the lookup table entry for this image's metadata resource + * */ + lookup_table_remove(lt, imd->metadata_lte); +} + /* * Recursively builds a dentry tree from a directory tree on disk, outside the * WIM file. * * @root: A dentry that has already been created for the root of the dentry - * tree. + * tree. * @source_path: The path to the root of the tree on disk. * @root_stat: A pointer to a `struct stat' that contains the metadata for the - * root of the tree on disk. + * root of the tree on disk. * @lookup_table: The lookup table for the WIM file. For each file added to the * dentry tree being built, an entry is added to the lookup table, * unless an identical file is already in the lookup table. These @@ -58,7 +71,8 @@ * the regular files in the tree into the WIM as file resources. */ static int build_dentry_tree(struct dentry *root, const char *source_path, - struct stat *root_stat, struct lookup_table* lookup_table) + struct stat *root_stat, + struct lookup_table* lookup_table) { int ret = 0; @@ -72,8 +86,8 @@ static int build_dentry_tree(struct dentry *root, const char *source_path, dir = opendir(source_path); if (!dir) { - ERROR("Failed to open the directory `%s': %m\n", - source_path); + ERROR_WITH_ERRNO("Failed to open the directory `%s'", + source_path); return WIMLIB_ERR_OPEN; } @@ -82,26 +96,29 @@ static int build_dentry_tree(struct dentry *root, const char *source_path, char name[len + 1 + FILENAME_MAX + 1]; memcpy(name, source_path, len); name[len] = '/'; - errno = 0; /* Create a dentry for each entry in the directory on disk, and recurse * to any subdirectories. */ while ((p = readdir(dir)) != NULL) { if (p->d_name[0] == '.' && (p->d_name[1] == '\0' - || (p->d_name[1] == '.' && p->d_name[2] == '\0'))) + || (p->d_name[1] == '.' && p->d_name[2] == '\0'))) continue; strcpy(name + len + 1, p->d_name); if (stat(name, &child_stat) != 0) { - ERROR("cannot stat `%s': %m\n", name); + ERROR_WITH_ERRNO("Cannot stat `%s'", name); ret = WIMLIB_ERR_STAT; break; } child = new_dentry(p->d_name); + if (!child) { + ERROR("No memory to allocate new dentry"); + return WIMLIB_ERR_NOMEM; + } ret = build_dentry_tree(child, name, &child_stat, lookup_table); + link_dentry(child, root); if (ret != 0) break; - link_dentry(child, root); } closedir(dir); } else { @@ -112,11 +129,8 @@ static int build_dentry_tree(struct dentry *root, const char *source_path, * refcnt; otherwise, we create a new lookup table entry and * insert it. */ ret = sha1sum(source_path, root->hash); - if (ret != 0) { - ERROR("Failed to calculate sha1sum for file `%s'\n", - source_path); + if (ret != 0) return ret; - } lte = lookup_resource(lookup_table, root->hash); if (lte) { @@ -124,14 +138,11 @@ static int build_dentry_tree(struct dentry *root, const char *source_path, } else { char *file_on_disk = STRDUP(source_path); if (!file_on_disk) { - ERROR("Failed to allocate memory for file " - "path!\n"); + ERROR("Failed to allocate memory for file path"); return WIMLIB_ERR_NOMEM; } lte = new_lookup_table_entry(); if (!lte) { - ERROR("Failed to allocate memory for new " - "lookup table entry!\n"); FREE(file_on_disk); return WIMLIB_ERR_NOMEM; } @@ -182,10 +193,8 @@ static int add_lookup_table_entry_to_dest_wim(struct dentry *dentry, void *arg) dest_table_entry->refcnt++; } else { dest_table_entry = new_lookup_table_entry(); - if (!dest_table_entry) { - ERROR("Could not allocate lookup table entry!\n"); + if (!dest_table_entry) return WIMLIB_ERR_NOMEM; - } dest_table_entry->other_wim_fp = src_wim->fp; dest_table_entry->other_wim_ctype = wimlib_get_compression_type(src_wim); @@ -211,44 +220,60 @@ static int add_lookup_table_entry_to_dest_wim(struct dentry *dentry, void *arg) */ static int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry) { - struct lookup_table_entry *imd_lookup_entry; + struct lookup_table_entry *metadata_lte; struct image_metadata *imd; struct image_metadata *new_imd; +#ifdef ENABLE_SECURITY_DATA + struct wim_security_data *sd; +#endif - DEBUG("Reallocing image metadata array for image_count = %u\n", - w->hdr.image_count + 1); + DEBUG("Reallocating image metadata array for image_count = %u", + w->hdr.image_count + 1); imd = CALLOC((w->hdr.image_count + 1), sizeof(struct image_metadata)); if (!imd) { - ERROR("Failed to allocate memory for new image metadata " - "array!\n"); + ERROR("Failed to allocate memory for new image metadata array"); return WIMLIB_ERR_NOMEM; } memcpy(imd, w->image_metadata, w->hdr.image_count * sizeof(struct image_metadata)); - imd_lookup_entry = new_lookup_table_entry(); - if (!imd_lookup_entry) { - ERROR("Failed to allocate new lookup table entry!\n"); - FREE(imd); - return WIMLIB_ERR_NOMEM; - } + metadata_lte = new_lookup_table_entry(); + if (!metadata_lte) + goto out_free_imd; +#ifdef ENABLE_SECURITY_DATA + sd = CALLOC(1, sizeof(struct wim_security_data)); + if (!sd) + goto out_free_metadata_lte; + sd->refcnt = 1; + sd->total_length = 8; +#endif - imd_lookup_entry->resource_entry.flags = WIM_RESHDR_FLAG_METADATA; - randomize_byte_array(imd_lookup_entry->hash, WIM_HASH_SIZE); - lookup_table_insert(w->lookup_table, imd_lookup_entry); + metadata_lte->resource_entry.flags = WIM_RESHDR_FLAG_METADATA; + randomize_byte_array(metadata_lte->hash, WIM_HASH_SIZE); + lookup_table_insert(w->lookup_table, metadata_lte); w->hdr.image_count++; - new_imd = &imd[w->hdr.image_count - 1]; - new_imd->lookup_table_entry = imd_lookup_entry; - new_imd->modified = true; - new_imd->root_dentry = root_dentry; - w->image_metadata = imd; + new_imd = &imd[w->hdr.image_count - 1]; + new_imd->metadata_lte = metadata_lte; + new_imd->modified = true; + new_imd->root_dentry = root_dentry; +#ifdef ENABLE_SECURITY_DATA + new_imd->security_data = sd; +#endif + FREE(w->image_metadata); + w->image_metadata = imd; /* Change the current image to the new one. */ return wimlib_select_image(w, w->hdr.image_count); +out_free_metadata_lte: + FREE(metadata_lte); +out_free_imd: + FREE(imd); + return WIMLIB_ERR_NOMEM; + } /* @@ -272,7 +297,7 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, /* multi-image export. */ if ((flags & WIMLIB_EXPORT_FLAG_BOOT) && - (src_wim->hdr.boot_idx == 0)) + (src_wim->hdr.boot_idx == 0)) { /* Specifying the boot flag on a multi-image * source WIM makes the boot index default to @@ -281,13 +306,13 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, * */ ERROR("Cannot specify `boot' flag when " "exporting multiple images from a WIM " - "with no bootable images!\n"); + "with no bootable images"); return WIMLIB_ERR_INVALID_PARAM; } if (dest_name || dest_description) { ERROR("Image name or image description was " "specified, but we are exporting " - "multiple images!\n"); + "multiple images"); return WIMLIB_ERR_INVALID_PARAM; } for (i = 1; i <= src_wim->hdr.image_count; i++) { @@ -297,8 +322,9 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, export_flags &= ~WIMLIB_EXPORT_FLAG_BOOT; ret = wimlib_export_image(src_wim, i, dest_wim, - NULL, dest_description, - export_flags); + NULL, + dest_description, + export_flags); if (ret != 0) return ret; } @@ -311,48 +337,58 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, ret = wimlib_select_image(src_wim, src_image); if (ret != 0) { ERROR("Could not select image %d from the WIM `%s' " - "to export it!\n", src_image, src_wim->filename); + "to export it", src_image, src_wim->filename); return ret; } if (!dest_name) { dest_name = wimlib_get_image_name(src_wim, src_image); - DEBUG("Using name `%s' for source image %d\n", - dest_name, src_image); + DEBUG("Using name `%s' for source image %d", + dest_name, src_image); } - DEBUG("Exporting image %d from `%s'\n", src_image, src_wim->filename); + DEBUG("Exporting image %d from `%s'", src_image, src_wim->filename); if (wimlib_image_name_in_use(dest_wim, dest_name)) { - ERROR("There is already an image named `%s' " - "in the destination WIM!\n", dest_name); + ERROR("There is already an image named `%s' in the " + "destination WIM", dest_name); return WIMLIB_ERR_IMAGE_NAME_COLLISION; } + /* Cleaning up here on failure would be hard. For example, we could + * fail to allocate memory in add_lookup_table_entry_to_dest_wim(), + * leaving the lookup table entries in the destination WIM in an + * inconsistent state. Until these issues can be resolved, + * wimlib_export_image() is documented as leaving dest_wim is an + * indeterminate state. */ root = wim_root_dentry(src_wim); for_dentry_in_tree(root, increment_dentry_refcnt, NULL); wims.src_wim = src_wim; wims.dest_wim = dest_wim; - for_dentry_in_tree(root, add_lookup_table_entry_to_dest_wim, &wims); + ret = for_dentry_in_tree(root, add_lookup_table_entry_to_dest_wim, &wims); + if (ret != 0) + return ret; ret = add_new_dentry_tree(dest_wim, root); + if (ret != 0) + return ret; #ifdef ENABLE_SECURITY_DATA + /* Bring over old security data */ struct wim_security_data *sd = wim_security_data(src_wim); struct image_metadata *new_imd = wim_get_current_image_metadata(dest_wim); + wimlib_assert(sd); + free_security_data(new_imd->security_data); new_imd->security_data = sd; - if (sd) - sd->refcnt++; + sd->refcnt++; #endif - if (ret != 0) - return ret; if (flags & WIMLIB_EXPORT_FLAG_BOOT) { - DEBUG("Setting boot_idx to %d\n", dest_wim->hdr.image_count); + DEBUG("Setting boot_idx to %d", dest_wim->hdr.image_count); dest_wim->hdr.boot_idx = dest_wim->hdr.image_count; } return xml_export_image(src_wim->wim_info, src_image, &dest_wim->wim_info, - dest_name, dest_description); + dest_name, dest_description); } /* @@ -377,7 +413,7 @@ WIMLIBAPI int wimlib_delete_image(WIMStruct *w, int image) return 0; } - DEBUG("Deleting image %d\n", image); + DEBUG("Deleting image %d", image); /* Even if the dentry tree is not allocated, we must select it (and * therefore allocate it) so that we can decrement the reference counts @@ -388,24 +424,15 @@ WIMLIBAPI int wimlib_delete_image(WIMStruct *w, int image) /* Free the dentry tree, any lookup table entries that have their * refcnt decremented to 0, and the security data. */ - imd = wim_get_current_image_metadata(w); - free_dentry_tree(imd->root_dentry, w->lookup_table, true); -#ifdef ENABLE_SECURITY_DATA - free_security_data(imd->security_data); -#endif - - /* Get rid of the lookup table entry for this image's metadata resource - * */ - lookup_table_remove(w->lookup_table, imd->lookup_table_entry); + destroy_image_metadata(wim_get_current_image_metadata(w), + w->lookup_table); /* Get rid of the empty slot in the image metadata array. */ - for (i = image - 1; i < w->hdr.image_count - 1; i++) - memcpy(&w->image_metadata[i], &w->image_metadata[i + 1], - sizeof(struct image_metadata)); + memmove(&w->image_metadata[image - 1], &w->image_metadata[image], + (w->hdr.image_count - image) * sizeof(struct image_metadata)); /* Decrement the image count. */ - w->hdr.image_count--; - if (w->hdr.image_count == 0) { + if (--w->hdr.image_count == 0) { FREE(w->image_metadata); w->image_metadata = NULL; } @@ -432,76 +459,79 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *dir, { struct dentry *root_dentry; struct stat root_stat; + struct image_metadata *imd; int ret; - DEBUG("Adding dentry tree from dir `%s'\n", dir); + DEBUG("Adding dentry tree from dir `%s'.", dir); if (!name || !*name) { - ERROR("Must specify a non-empty string for the image name!\n"); + ERROR("Must specify a non-empty string for the image name"); return WIMLIB_ERR_INVALID_PARAM; } if (!dir) { - ERROR("Must specify the name of a directory!\n"); + ERROR("Must specify the name of a directory"); return WIMLIB_ERR_INVALID_PARAM; } if (wimlib_image_name_in_use(w, name)) { - ERROR("There is already an image named `%s' in %s!\n", - name, w->filename); + ERROR("There is already an image named \"%s\" in `%s'", + name, w->filename); return WIMLIB_ERR_IMAGE_NAME_COLLISION; } - DEBUG("Creating root dentry.\n"); + DEBUG("Creating root dentry."); root_dentry = new_dentry(""); + if (!root_dentry) + return WIMLIB_ERR_NOMEM; ret = calculate_dentry_full_path(root_dentry, NULL); + if (ret != 0) - return ret; + goto out_free_dentry_tree; + root_dentry->attributes |= WIM_FILE_ATTRIBUTE_DIRECTORY; /* Construct the dentry tree from the outside filesystem. */ if (stat(dir, &root_stat) != 0) { - ERROR("Failed to stat `%s': %m\n", dir); - return WIMLIB_ERR_STAT; + ERROR_WITH_ERRNO("Failed to stat `%s'", dir); + ret = WIMLIB_ERR_STAT; + goto out_free_dentry_tree; } if (!S_ISDIR(root_stat.st_mode)) { - ERROR("`%s' is not a directory!\n", dir); - return WIMLIB_ERR_NOTDIR; + ERROR("`%s' is not a directory", dir); + ret = WIMLIB_ERR_NOTDIR; + goto out_free_dentry_tree; } - DEBUG("Building dentry tree.\n"); - ret = build_dentry_tree(root_dentry, dir, &root_stat, - w->lookup_table); + DEBUG("Building dentry tree."); + ret = build_dentry_tree(root_dentry, dir, &root_stat, w->lookup_table); if (ret != 0) { - ERROR("Failed to build dentry tree for `%s'!\n", dir); - goto err1; + ERROR("Failed to build dentry tree for `%s'", dir); + goto out_free_dentry_tree; } - DEBUG("Recalculating full paths of dentries.\n"); - ret = for_dentry_in_tree(root_dentry, - calculate_dentry_full_path, NULL); - if (ret != 0) { - ERROR("Failed to calculate full paths of dentry tree.\n"); - goto err1; - } + DEBUG("Recalculating full paths of dentries."); + ret = for_dentry_in_tree(root_dentry, calculate_dentry_full_path, NULL); + if (ret != 0) + goto out_free_dentry_tree; ret = add_new_dentry_tree(w, root_dentry); if (ret != 0) - goto err1; + goto out_free_dentry_tree; - if (flags & WIMLIB_ADD_IMAGE_FLAG_BOOT) { - /* Call wimlib_set_boot_idx rather than set boot_idx directly so - * that the boot metadata resource entry in the header gets - * updated. */ + if (flags & WIMLIB_ADD_IMAGE_FLAG_BOOT) wimlib_set_boot_idx(w, w->hdr.image_count); - } ret = xml_add_image(w, root_dentry, name, description, flags_element); if (ret != 0) - goto err1; + goto out_destroy_imd; return 0; -err1: +out_destroy_imd: + destroy_image_metadata(&w->image_metadata[w->hdr.image_count - 1], + w->lookup_table); + return ret; +out_free_dentry_tree: free_dentry_tree(root_dentry, w->lookup_table, true); return ret; } diff --git a/src/mount.c b/src/mount.c index 3cb61ee6..53a7f364 100644 --- a/src/mount.c +++ b/src/mount.c @@ -84,7 +84,7 @@ static void make_staging_dir() staging_dir_name = MALLOC(staging_dir_name_len + 1); if (!staging_dir_name) { - ERROR("Out of memory!\n"); + ERROR("Out of memory"); return; } @@ -96,8 +96,8 @@ static void make_staging_dir() staging_dir_name[staging_dir_name_len] = '\0'; if (mkdir(staging_dir_name, 0700) != 0) { - ERROR("Failed to create temporary directory `%s': %m\n", - staging_dir_name); + ERROR_WITH_ERRNO("Failed to create temporary directory `%s'", + staging_dir_name); FREE(staging_dir_name); staging_dir_name = NULL; } @@ -194,13 +194,13 @@ static int open_message_queues(bool daemon) unmount_to_daemon_mq_name = strcat_dup(slash, mount_dir_basename, prefix, u2d_suffix); if (!unmount_to_daemon_mq_name) { - ERROR("Out of memory!\n"); + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; } daemon_to_unmount_mq_name = strcat_dup(slash, mount_dir_basename, prefix, d2u_suffix); if (!daemon_to_unmount_mq_name) { - ERROR("Out of memory!\n"); + ERROR("Out of memory"); ret = WIMLIB_ERR_NOMEM; goto err1; } @@ -219,7 +219,7 @@ static int open_message_queues(bool daemon) 0700, NULL); if (unmount_to_daemon_mq == -1) { - ERROR("mq_open(): %m\n"); + ERROR_WITH_ERRNO("mq_open()"); ret = WIMLIB_ERR_MQUEUE; goto err2; } @@ -233,7 +233,7 @@ static int open_message_queues(bool daemon) 0700, NULL); if (daemon_to_unmount_mq == -1) { - ERROR("mq_open(): %m\n"); + ERROR_WITH_ERRNO("mq_open()"); ret = WIMLIB_ERR_MQUEUE; goto err3; } @@ -258,19 +258,19 @@ static int mq_get_msgsize(mqd_t mq) if (mq_getattr(unmount_to_daemon_mq, &attr) == 0) { msgsize = attr.mq_msgsize; } else { - ERROR("mq_getattr(): %m\n"); - ERROR("Attempting to read %s\n", msgsize_max_file); + ERROR_WITH_ERRNO("mq_getattr()"); + ERROR("Attempting to read %s", msgsize_max_file); fp = fopen(msgsize_max_file, "rb"); if (fp) { if (fscanf(fp, "%d", &msgsize) != 1) { - ERROR("Assuming message size of 8192\n"); + ERROR("Assuming message size of 8192"); msgsize = 8192; } fclose(fp); } else { - ERROR("Failed to open file %s: %m\n", - msgsize_max_file); - ERROR("Assuming message size of 8192\n"); + ERROR_WITH_ERRNO("Failed to open the file `%s'", + msgsize_max_file); + ERROR("Assuming message size of 8192"); msgsize = 8192; } } @@ -298,8 +298,8 @@ static int close_staging_file(struct lookup_table_entry *lte, void *ignore) { if (lte->staging_file_name && lte->staging_num_times_opened) { if (close(lte->staging_fd) != 0) { - ERROR("Failed close file `%s': %m\n", - lte->staging_file_name); + ERROR_WITH_ERRNO("Failed close file `%s'", + lte->staging_file_name); return WIMLIB_ERR_WRITE; } } @@ -323,7 +323,8 @@ static int calculate_sha1sum_for_staging_file(struct dentry *dentry, void *looku if (lte && lte->staging_file_name) { - DEBUG("Calculating SHA1 hash for file `%s'\n", dentry->file_name_utf8); + DEBUG("Calculating SHA1 hash for file `%s'", + dentry->file_name_utf8); ret = sha1sum(lte->staging_file_name, dentry->hash); if (ret != 0) return ret; @@ -332,8 +333,8 @@ static int calculate_sha1sum_for_staging_file(struct dentry *dentry, void *looku memcpy(lte->hash, dentry->hash, WIM_HASH_SIZE); existing = lookup_resource(table, dentry->hash); if (existing) { - DEBUG("Merging duplicate lookup table entries for " - "file `%s'\n", dentry->file_name_utf8); + DEBUG("Merging duplicate lookup table entries for file " + "`%s'", dentry->file_name_utf8); free_lookup_table_entry(lte); existing->refcnt++; } else { @@ -351,22 +352,21 @@ static int rebuild_wim(WIMStruct *w, bool check_integrity) root = wim_root_dentry(w); - DEBUG("Closing all staging file descriptors.\n"); + DEBUG("Closing all staging file descriptors."); /* Close all the staging file descriptors. */ - ret = for_lookup_table_entry(w->lookup_table, - close_staging_file, NULL); + ret = for_lookup_table_entry(w->lookup_table, close_staging_file, NULL); if (ret != 0) { - ERROR("Failed to close all staging files!\n"); + ERROR("Failed to close all staging files"); return ret; } - DEBUG("Calculating SHA1 checksums for all new staging files.\n"); + DEBUG("Calculating SHA1 checksums for all new staging files."); /* Calculate SHA1 checksums for all staging files, and merge unnecessary * lookup table entries. */ ret = for_dentry_in_tree(root, calculate_sha1sum_for_staging_file, w->lookup_table); if (ret != 0) { - ERROR("Failed to calculate new SHA1 checksums!\n"); + ERROR("Failed to calculate new SHA1 checksums"); return ret; } @@ -374,7 +374,7 @@ static int rebuild_wim(WIMStruct *w, bool check_integrity) ret = wimlib_overwrite(w, check_integrity); if (ret != 0) { - ERROR("Failed to commit changes\n"); + ERROR("Failed to commit changes"); return ret; } return ret; @@ -412,8 +412,8 @@ static void wimfs_destroy(void *p) gettimeofday(&now, NULL); timeout.tv_sec = now.tv_sec + 3; timeout.tv_nsec = now.tv_usec * 1000; - DEBUG("Waiting for message telling us whether to commit or not, " - "and whether to include integrity checks.\n"); + DEBUG("Waiting for message telling us whether to commit or not, and " + "whether to include integrity checks."); bytes_received = mq_timedreceive(unmount_to_daemon_mq, msg, msgsize, NULL, &timeout); @@ -421,13 +421,13 @@ static void wimfs_destroy(void *p) check_integrity = msg[1]; if (bytes_received == -1) { if (errno == ETIMEDOUT) { - ERROR("Timed out.\n"); + ERROR("Timed out."); } else { - ERROR("mq_timedreceive(): %m\n"); + ERROR_WITH_ERRNO("mq_timedreceive()"); } - ERROR("Not committing.\n"); + ERROR("Not committing."); } else { - DEBUG("Received message: [%d %d]\n", msg[0], msg[1]); + DEBUG("Received message: [%d %d]", msg[0], msg[1]); } status = 0; @@ -435,7 +435,7 @@ static void wimfs_destroy(void *p) if (commit) { status = chdir(working_directory); if (status != 0) { - ERROR("chdir(): %m\n"); + ERROR_WITH_ERRNO("chdir()"); status = WIMLIB_ERR_NOTDIR; goto done; } @@ -443,7 +443,8 @@ static void wimfs_destroy(void *p) } ret = delete_staging_dir(); if (ret != 0) { - ERROR("Failed to delete the staging directory: %m\n"); + ERROR_WITH_ERRNO("Failed to delete the staging " + "directory"); if (status == 0) status = ret; } @@ -451,7 +452,7 @@ static void wimfs_destroy(void *p) done: ret = mq_send(daemon_to_unmount_mq, &status, 1, 1); if (ret == -1) - ERROR("Failed to send status to unmount process: %m\n"); + ERROR_WITH_ERRNO("Failed to send status to unmount process"); close_message_queues(); } @@ -537,7 +538,7 @@ static int create_staging_file(char **name_ret) /* doesn't exist--- ok */ } - DEBUG("Creating staging file '%s'\n", name); + DEBUG("Creating staging file '%s'", name); fd = creat(name, 0600); if (fd == -1) { @@ -1083,7 +1084,7 @@ WIMLIBAPI int wimlib_mount(WIMStruct *wim, int image, const char *dir, mount_dir = dir; working_directory = getcwd(NULL, 0); if (!working_directory) { - ERROR("Could not determine current directory: %m\n"); + ERROR_WITH_ERRNO("Could not determine current directory"); return WIMLIB_ERR_NOTDIR; } @@ -1162,24 +1163,24 @@ WIMLIBAPI int wimlib_unmount(const char *dir, int flags) mount_dir = dir; pid = fork(); if (pid == -1) { - ERROR("Failed to fork(): %m\n"); + ERROR_WITH_ERRNO("Failed to fork()"); return WIMLIB_ERR_FORK; } if (pid == 0) { execlp("fusermount", "fusermount", "-u", dir, NULL); - ERROR("Failed to execute `fusermount': %m\n"); + ERROR_WITH_ERRNO("Failed to execute `fusermount'"); return WIMLIB_ERR_FUSERMOUNT; } ret = waitpid(pid, &status, 0); if (ret == -1) { - ERROR("Failed to wait for fusermount process to " - "terminate: %m\n"); + ERROR_WITH_ERRNO("Failed to wait for fusermount process to " + "terminate"); return WIMLIB_ERR_FUSERMOUNT; } if (status != 0) { - ERROR("fusermount exited with status %d!\n", status); + ERROR("fusermount exited with status %d", status); return WIMLIB_ERR_FUSERMOUNT; } @@ -1194,13 +1195,13 @@ WIMLIBAPI int wimlib_unmount(const char *dir, int flags) msg[0] = (flags & WIMLIB_UNMOUNT_FLAG_COMMIT) ? 1 : 0; msg[1] = (flags & WIMLIB_UNMOUNT_FLAG_CHECK_INTEGRITY) ? 1 : 0; - DEBUG("Sending message: %s, %s\n", + DEBUG("Sending message: %s, %s", (msg[0] == 0) ? "don't commit" : "commit", (msg[1] == 0) ? "don't check" : "check"); ret = mq_send(unmount_to_daemon_mq, msg, 2, 1); if (ret == -1) { - ERROR("Failed to notify filesystem daemon whether " - "we want to commit changes or not!\n"); + ERROR("Failed to notify filesystem daemon whether we want to " + "commit changes or not"); close_message_queues(); return WIMLIB_ERR_MQUEUE; } @@ -1225,28 +1226,27 @@ WIMLIBAPI int wimlib_unmount(const char *dir, int flags) mailbox[0] = 0; DEBUG("Waiting for message telling us whether the unmount was " - "successful or not.\n"); + "successful or not."); ret = mq_timedreceive(daemon_to_unmount_mq, mailbox, msgsize, NULL, &timeout); errno_save = errno; close_message_queues(); if (ret == -1) { if (errno_save == ETIMEDOUT) { - ERROR("Timed out- probably the filesystem " - "daemon crashed and the WIM was not " - "written successfully.\n"); + ERROR("Timed out- probably the filesystem daemon " + "crashed and the WIM was not written " + "successfully."); return WIMLIB_ERR_TIMEOUT; } else { - ERROR("mq_receive(): %s\n", - strerror(errno_save)); + ERROR("mq_receive(): %s", strerror(errno_save)); return WIMLIB_ERR_MQUEUE; } } - DEBUG("Received message: %s\n", (mailbox[0] == 0) ? - "Unmount OK" : "Unmount Failed"); + DEBUG("Received message: %s", + (mailbox[0] == 0) ? "Unmount OK" : "Unmount Failed"); if (mailbox[0] != 0) - ERROR("Unmount failed\n"); + ERROR("Unmount failed"); return mailbox[0]; } @@ -1255,8 +1255,8 @@ WIMLIBAPI int wimlib_unmount(const char *dir, int flags) static inline int mount_unsupported_error() { - ERROR("WIMLIB was compiled with --without-fuse, which " - "disables support for mounting WIMs.\n"); + ERROR("WIMLIB was compiled with --without-fuse, which disables support " + "for mounting WIMs."); return WIMLIB_ERR_UNSUPPORTED; } diff --git a/src/resource.c b/src/resource.c index a5f0e4d7..9349c3ba 100644 --- a/src/resource.c +++ b/src/resource.c @@ -31,6 +31,7 @@ #include "xpress.h" #include "sha1.h" #include "dentry.h" +#include "config.h" #include #include @@ -59,15 +60,13 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size, u64 len, u64 offset, u8 contents_ret[]) { - DEBUG2("comp size = %"PRIu64", " - "uncomp size = %"PRIu64", " - "res offset = %"PRIu64"\n", - resource_compressed_size, - resource_uncompressed_size, - resource_offset); - DEBUG2("resource_ctype = %s, len = %"PRIu64", offset = %"PRIu64"\n", - wimlib_get_compression_type_string(resource_ctype), - len, offset); + DEBUG2("comp size = %"PRIu64", uncomp size = %"PRIu64", " + "res offset = %"PRIu64"", + resource_compressed_size, + resource_uncompressed_size, + resource_offset); + DEBUG2("resource_ctype = %s, len = %"PRIu64", offset = %"PRIu64"", + wimlib_get_compression_type_string(resource_ctype), len, offset); /* Trivial case */ if (len == 0) return 0; @@ -157,10 +156,9 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size, u64 file_offset_of_needed_chunk_entries = resource_offset + start_table_idx * chunk_entry_size; if (fseeko(fp, file_offset_of_needed_chunk_entries, SEEK_SET) != 0) { - ERROR("Failed to seek to byte %"PRIu64" " - "to read chunk table of compressed " - "resource: %m\n", - file_offset_of_needed_chunk_entries); + ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" to read " + "chunk table of compressed resource", + file_offset_of_needed_chunk_entries); return WIMLIB_ERR_READ; } @@ -195,10 +193,9 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size, u64 file_offset_of_first_needed_chunk = resource_offset + chunk_table_size + chunk_offsets[0]; if (fseeko(fp, file_offset_of_first_needed_chunk, SEEK_SET) != 0) { - ERROR("Failed to seek to byte %"PRIu64" " - "to read first chunk of compressed " - "resource: %m\n", - file_offset_of_first_needed_chunk); + ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" to read " + "first chunk of compressed resource", + file_offset_of_first_needed_chunk); return WIMLIB_ERR_READ; } @@ -218,8 +215,8 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size, /* Decompress all the chunks. */ for (u64 i = start_chunk; i <= end_chunk; i++) { - DEBUG2("Chunk %"PRIu64" (start %"PRIu64", end %"PRIu64")\n", - i, start_chunk, end_chunk); + DEBUG2("Chunk %"PRIu64" (start %"PRIu64", end %"PRIu64").", + i, start_chunk, end_chunk); /* Calculate the sizes of the compressed chunk and of the * uncompressed chunk. */ @@ -254,8 +251,9 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size, uncompressed_chunk_size = WIM_CHUNK_SIZE; } - DEBUG2("compressed_chunk_size = %u, uncompressed_chunk_size = %u\n", - compressed_chunk_size, uncompressed_chunk_size); + DEBUG2("compressed_chunk_size = %u, " + "uncompressed_chunk_size = %u", + compressed_chunk_size, uncompressed_chunk_size); /* Figure out how much of this chunk we actually need to read */ @@ -274,9 +272,9 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size, bool is_partial_chunk = (partial_chunk_size != uncompressed_chunk_size); - DEBUG2("start_offset = %u, end_offset = %u\n", start_offset, + DEBUG2("start_offset = %u, end_offset = %u", start_offset, end_offset); - DEBUG2("partial_chunk_size = %u\n", partial_chunk_size); + DEBUG2("partial_chunk_size = %u", partial_chunk_size); /* This is undocumented, but chunks can be uncompressed. This * appears to always be the case when the compressed chunk size @@ -286,8 +284,8 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size, if (start_offset != 0) { if (fseeko(fp, start_offset, SEEK_CUR) != 0) { - ERROR("Uncompressed partial chunk " - "fseek() error: %m\n"); + ERROR_WITH_ERRNO("Uncompressed partial " + "chunk fseek() error"); return WIMLIB_ERR_READ; } } @@ -317,7 +315,6 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size, memcpy(out_p, uncompressed_buf + start_offset, partial_chunk_size); } else { - DEBUG2("out_p = %p\n"); ret = decompress(compressed_buf, compressed_chunk_size, out_p, @@ -336,9 +333,9 @@ static int read_compressed_resource(FILE *fp, u64 resource_compressed_size, err: if (feof(fp)) - ERROR("Unexpected EOF in compressed file resource\n"); + ERROR("Unexpected EOF in compressed file resource"); else - ERROR("Error reading compressed file resource: %m\n"); + ERROR_WITH_ERRNO("Error reading compressed file resource"); return WIMLIB_ERR_READ; } @@ -350,17 +347,17 @@ int read_uncompressed_resource(FILE *fp, u64 offset, u64 len, { if (fseeko(fp, offset, SEEK_SET) != 0) { ERROR("Failed to seek to byte %"PRIu64" of input file " - "to read uncompressed resource " - "(len = %"PRIu64")!\n", offset, len); + "to read uncompressed resource (len = %"PRIu64")", + offset, len); return WIMLIB_ERR_READ; } if (fread(contents_ret, 1, len, fp) != len) { if (feof(fp)) { - ERROR("Unexpected EOF in uncompressed file resource!\n"); + ERROR("Unexpected EOF in uncompressed file resource"); } else { ERROR("Failed to read %"PRIu64" bytes from " - "uncompressed resource at offset " - "%"PRIu64"\n", len, offset); + "uncompressed resource at offset %"PRIu64, + len, offset); } return WIMLIB_ERR_READ; } @@ -402,12 +399,9 @@ int read_resource(FILE *fp, u64 resource_size, u64 resource_original_size, { if (resource_ctype == WIM_COMPRESSION_TYPE_NONE) { if (resource_size != resource_original_size) { - ERROR("Resource with original size %"PRIu64" " - "bytes is marked as uncompressed, \n", - resource_original_size); - ERROR(" but its actual size is %"PRIu64" " - "bytes!\n", - resource_size); + ERROR("Resource with original size %"PRIu64" bytes is " + "marked as uncompressed, but its actual size is " + "%"PRIu64" bytes", resource_size); return WIMLIB_ERR_INVALID_RESOURCE_SIZE; } return read_uncompressed_resource(fp, @@ -542,14 +536,11 @@ u8 *put_resource_entry(u8 *p, const struct resource_entry *entry) * a resource entry, returns the compression type for that resource entry. */ int resource_compression_type(int wim_ctype, int reshdr_flags) { - if (wim_ctype == WIM_COMPRESSION_TYPE_NONE) { + if (wim_ctype != WIM_COMPRESSION_TYPE_NONE && + (reshdr_flags & WIM_RESHDR_FLAG_COMPRESSED)) + return wim_ctype; + else return WIM_COMPRESSION_TYPE_NONE; - } else { - if (reshdr_flags & WIM_RESHDR_FLAG_COMPRESSED) - return wim_ctype; - else - return WIM_COMPRESSION_TYPE_NONE; - } } @@ -557,35 +548,36 @@ int resource_compression_type(int wim_ctype, int reshdr_flags) /* * Copies bytes between two file streams. * - * Copies @len bytes from @in to @out, at the current position in @out, and at - * an offset of @in_offset in @in. + * Copies @len bytes from @in_fp to @out_fp, at the current position in @out_fp, + * and at an offset of @in_offset in @in_fp. */ -int copy_between_files(FILE *in, off_t in_offset, FILE *out, size_t len) +int copy_between_files(FILE *in_fp, off_t in_offset, FILE *out_fp, size_t len) { u8 buf[BUFFER_SIZE]; size_t n; - if (fseeko(in, in_offset, SEEK_SET) != 0) { - ERROR("Failed to seek to byte %"PRIu64" of input file: %m\n", - in_offset); + if (fseeko(in_fp, in_offset, SEEK_SET) != 0) { + ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" of " + "input file", in_offset); return WIMLIB_ERR_READ; } /* To reduce memory usage and improve speed, read and write BUFFER_SIZE * bytes at a time. */ while (len != 0) { n = min(len, BUFFER_SIZE); - if (fread(buf, 1, n, in) != n) { - if (feof(in)) { + if (fread(buf, 1, n, in_fp) != n) { + if (feof(in_fp)) { ERROR("Unexpected EOF when copying data " - "between files\n"); + "between files"); } else { - ERROR("Error copying data between files: %m\n"); + ERROR_WITH_ERRNO("Error copying data between " + "files"); } return WIMLIB_ERR_READ; } - if (fwrite(buf, 1, n, out) != n) { - ERROR("Error copying data between files: %m\n"); + if (fwrite(buf, 1, n, out_fp) != n) { + ERROR_WITH_ERRNO("Error copying data between files"); return WIMLIB_ERR_WRITE; } len -= n; @@ -597,15 +589,15 @@ int copy_between_files(FILE *in, off_t in_offset, FILE *out, size_t len) /* * Uncompresses a WIM file resource and writes it uncompressed to a file stream. * - * @in: The file stream that contains the file resource. + * @in_fp: The file stream that contains the file resource. * @size: The size of the resource in the input file. * @original_size: The original (uncompressed) size of the resource. * @offset: The offset of the start of the resource in @in. * @input_ctype: The compression type of the resource in @in. - * @out: The file stream to write the file resource to. + * @out_fp: The file stream to write the file resource to. */ -static int uncompress_resource(FILE *in, u64 size, u64 original_size, - off_t offset, int input_ctype, FILE *out) +static int uncompress_resource(FILE *in_fp, u64 size, u64 original_size, + off_t offset, int input_ctype, FILE *out_fp) { int ret; u8 buf[WIM_CHUNK_SIZE]; @@ -620,18 +612,19 @@ static int uncompress_resource(FILE *in, u64 size, u64 original_size, for (i = 0; i < num_chunks; i++) { uncompressed_offset = i * WIM_CHUNK_SIZE; - uncompressed_chunk_size = min(WIM_CHUNK_SIZE, - original_size - uncompressed_offset); + uncompressed_chunk_size = min(WIM_CHUNK_SIZE, original_size - + uncompressed_offset); - ret = read_resource(in, size, original_size, offset, input_ctype, - uncompressed_chunk_size, - uncompressed_offset, buf); + ret = read_resource(in_fp, size, original_size, offset, + input_ctype, uncompressed_chunk_size, + uncompressed_offset, buf); if (ret != 0) return ret; - if (fwrite(buf, 1, uncompressed_chunk_size, out) != - uncompressed_chunk_size) { - ERROR("Failed to write file resource: %m\n"); + if (fwrite(buf, 1, uncompressed_chunk_size, out_fp) != + uncompressed_chunk_size) + { + ERROR_WITH_ERRNO("Failed to write file resource"); return WIMLIB_ERR_WRITE; } } @@ -644,7 +637,7 @@ static int uncompress_resource(FILE *in, u64 size, u64 original_size, * Alternatively, the input resource may be in-memory, but it must be * uncompressed. * - * @in: The file stream that contains the file resource. Ignored + * @in_fp: The file stream that contains the file resource. Ignored * if uncompressed_resource != NULL. * @uncompressed_resource: If this pointer is not NULL, it points to an * array of @original_size bytes that are @@ -655,16 +648,16 @@ static int uncompress_resource(FILE *in, u64 size, u64 original_size, * if uncompressed_resource != NULL. * @input_ctype: The compression type of the resource in @in. Ignored if * uncompressed_resource != NULL. - * @out: The file stream to write the file resource to. + * @out_fp: The file stream to write the file resource to. * @output_type: The compression type to use when writing the resource to * @out. * @new_size_ret: A location into which the new compressed size of the file * resource in returned. */ -static int recompress_resource(FILE *in, const u8 *uncompressed_resource, - u64 size, u64 original_size, - off_t offset, int input_ctype, FILE *out, - int output_ctype, u64 *new_size_ret) +static int recompress_resource(FILE *in_fp, const u8 *uncompressed_resource, + u64 size, u64 original_size, + off_t offset, int input_ctype, FILE *out_fp, + int output_ctype, u64 *new_size_ret) { int ret; int (*compress)(const void *, uint, void *, uint *); @@ -684,20 +677,27 @@ static int recompress_resource(FILE *in, const u8 *uncompressed_resource, /* Size of the chunk entries--- 8 bytes for files over 4GB, otherwise 4 * bytes */ - uint chunk_entry_size = (original_size >= (u64)1 << 32) ? 8 : 4; + uint chunk_entry_size = (original_size >= (u64)1 << 32) ? 8 : 4; /* Array in which to construct the chunk offset table. */ u64 chunk_offsets[num_chunk_entries]; /* Offset of the start of the chunk table in the output file. */ - off_t chunk_tab_offset = ftello(out); + off_t chunk_tab_offset = ftello(out_fp); + + if (chunk_tab_offset == -1) { + ERROR_WITH_ERRNO("Failed to get offset of output file"); + return WIMLIB_ERR_WRITE; + } /* Total size of the chunk table (as written to the file) */ u64 chunk_tab_size = chunk_entry_size * num_chunk_entries; /* Reserve space for the chunk table. */ - if (fwrite(chunk_offsets, 1, chunk_tab_size, out) != chunk_tab_size) { - ERROR("Failed to write chunk offset table: %m\n"); + if (fwrite(chunk_offsets, 1, chunk_tab_size, out_fp) != + chunk_tab_size) + { + ERROR_WITH_ERRNO("Failed to write chunk offset table"); return WIMLIB_ERR_WRITE; } @@ -713,14 +713,15 @@ static int recompress_resource(FILE *in, const u8 *uncompressed_resource, const u8 *uncompressed_p; if (uncompressed_resource != NULL) { uncompressed_p = uncompressed_resource + - uncompressed_offset; + uncompressed_offset; } else { /* Read chunk i of the file into uncompressed_buf. */ - ret = read_resource(in, size, original_size, offset, input_ctype, - uncompressed_chunk_size, - uncompressed_offset, - uncompressed_buf); + ret = read_resource(in_fp, size, original_size, offset, + input_ctype, + uncompressed_chunk_size, + uncompressed_offset, + uncompressed_buf); if (ret != 0) return ret; uncompressed_p = uncompressed_buf; @@ -748,8 +749,11 @@ static int recompress_resource(FILE *in, const u8 *uncompressed_resource, len_to_write = uncompressed_chunk_size; } - if (fwrite(buf_to_write, 1, len_to_write, out) != len_to_write) { - ERROR("Failed to write compressed file resource: %m\n"); + if (fwrite(buf_to_write, 1, len_to_write, out_fp) != + len_to_write) + { + ERROR_WITH_ERRNO("Failed to write compressed " + "file resource"); return WIMLIB_ERR_WRITE; } cur_chunk_offset += len_to_write; @@ -762,32 +766,25 @@ static int recompress_resource(FILE *in, const u8 *uncompressed_resource, /* Now that all entries of the chunk table are determined, rewind the * stream to where the chunk table was, and write it back out. */ - if (fseeko(out, chunk_tab_offset, SEEK_SET) != 0) { - ERROR("Failed to seek to beginning of chunk table: %m\n"); + if (fseeko(out_fp, chunk_tab_offset, SEEK_SET) != 0) { + ERROR_WITH_ERRNO("Failed to seek to beginning of chunk table"); return WIMLIB_ERR_READ; } if (chunk_entry_size == 8) { array_to_le64(chunk_offsets, num_chunk_entries); - - if (fwrite(chunk_offsets, 1, chunk_tab_size, out) != - chunk_tab_size) { - ERROR("Failed to write chunk table: %m\n"); - return WIMLIB_ERR_WRITE; - } } else { - u32 chunk_entries_small[num_chunk_entries]; for (u64 i = 0; i < num_chunk_entries; i++) - chunk_entries_small[i] = to_le32(chunk_offsets[i]); - if (fwrite(chunk_entries_small, 1, chunk_tab_size, out) != - chunk_tab_size) { - ERROR("Failed to write chunk table: %m\n"); - return WIMLIB_ERR_WRITE; - } + ((u32*)chunk_offsets)[i] = to_le32(chunk_offsets[i]); + } + if (fwrite(chunk_offsets, 1, chunk_tab_size, out_fp) != chunk_tab_size) + { + ERROR_WITH_ERRNO("Failed to write chunk table"); + return WIMLIB_ERR_WRITE; } - if (fseeko(out, 0, SEEK_END) != 0) { - ERROR("Failed to seek to end of output file: %m\n"); + if (fseeko(out_fp, 0, SEEK_END) != 0) { + ERROR_WITH_ERRNO("Failed to seek to end of output file"); return WIMLIB_ERR_WRITE; } @@ -795,23 +792,24 @@ static int recompress_resource(FILE *in, const u8 *uncompressed_resource, } int write_resource_from_memory(const u8 resource[], int out_ctype, - u64 resource_original_size, FILE *out, + u64 resource_original_size, FILE *out_fp, u64 *resource_size_ret) { if (out_ctype == WIM_COMPRESSION_TYPE_NONE) { - if (fwrite(resource, 1, resource_original_size, out) != - resource_original_size) { - ERROR("Failed to write resource of length " - "%"PRIu64": %m\n", - resource_original_size); + if (fwrite(resource, 1, resource_original_size, out_fp) != + resource_original_size) + { + ERROR_WITH_ERRNO("Failed to write resource of length " + "%"PRIu64, resource_original_size); return WIMLIB_ERR_WRITE; } *resource_size_ret = resource_original_size; return 0; } else { - return recompress_resource(NULL, resource, resource_original_size, - resource_original_size, 0, 0, out, out_ctype, - resource_size_ret); + return recompress_resource(NULL, resource, + resource_original_size, + resource_original_size, 0, 0, out_fp, + out_ctype, resource_size_ret); } } @@ -820,13 +818,13 @@ int write_resource_from_memory(const u8 resource[], int out_ctype, * Transfers a file resource from a FILE* opened for reading to a FILE* opened * for writing, possibly changing the compression type. * - * @in: The FILE* that contains the file resource. + * @in_fp: The FILE* that contains the file resource. * @size: The (compressed) size of the file resource. * @original_size: The uncompressed size of the file resource. * @offset: The offset of the file resource in the input file. * @input_ctype: The compression type of the file resource in the input * file. - * @out: The FILE* for the output file. The file resource is + * @out_fp: The FILE* for the output file. The file resource is * written at the current position of @out. * @output_ctype: The compression type to which the file resource will be * converted. @@ -836,9 +834,9 @@ int write_resource_from_memory(const u8 resource[], int out_ctype, * in for the file resource written to the output * file. */ -static int transfer_file_resource(FILE *in, u64 size, u64 original_size, - off_t offset, int input_ctype, FILE *out, - int output_ctype, +static int transfer_file_resource(FILE *in_fp, u64 size, u64 original_size, + off_t offset, int input_ctype, FILE *out_fp, + int output_ctype, struct resource_entry *output_res_entry) { int ret; @@ -850,16 +848,17 @@ static int transfer_file_resource(FILE *in, u64 size, u64 original_size, } /* Get current offset in the output file. */ - output_res_entry->offset = ftello(out); - if (output_res_entry->offset == -1) { - ERROR("Failed to get output position: %m\n"); + off_t out_offset = ftello(out_fp); + if (out_offset == -1) { + ERROR_WITH_ERRNO("Failed to get output position"); return WIMLIB_ERR_WRITE; } + output_res_entry->offset = (u64)out_offset; if (output_ctype == input_ctype) { /* The same compression types; simply copy the resource. */ - ret = copy_between_files(in, offset, out, size); + ret = copy_between_files(in_fp, offset, out_fp, size); if (ret != 0) return ret; output_res_entry->size = size; @@ -868,9 +867,9 @@ static int transfer_file_resource(FILE *in, u64 size, u64 original_size, if (output_ctype == WIM_COMPRESSION_TYPE_NONE) { /* Uncompress a compressed file resource */ - ret = uncompress_resource(in, size, - original_size, offset, - input_ctype, out); + ret = uncompress_resource(in_fp, size, + original_size, offset, + input_ctype, out_fp); if (ret != 0) return ret; output_res_entry->size = original_size; @@ -879,9 +878,10 @@ static int transfer_file_resource(FILE *in, u64 size, u64 original_size, /* Compress an uncompressed file resource, or compress a * compressed file resource using a different * compression type */ - ret = recompress_resource(in, NULL, size, original_size, - offset, input_ctype, out, - output_ctype, &new_size); + ret = recompress_resource(in_fp, NULL, size, + original_size, + offset, input_ctype, out_fp, + output_ctype, &new_size); if (ret != 0) return ret; output_res_entry->size = new_size; @@ -907,29 +907,34 @@ static int transfer_file_resource(FILE *in, u64 size, u64 original_size, * length 8, because that's how long the 'length' field is. * * @fp: The FILE* for the input WIM file. - * @res_entry: The resource entry for the metadata resource (a.k.a the metadata - * for the metadata) * @wim_ctype: The compression type of the WIM file. - * @root_dentry_p: A pointer to a pointer to a struct dentry structure into which the - * root dentry is allocated and returned. + * @imd: Pointer to the image metadata structure. Its + * `lookup_table_entry' member specifies the lookup table entry for + * the metadata resource. The rest of the image metadata entry + * will be filled in by this function. * - * @return: True on success, false on failure. + * @return: Zero on success, nonzero on failure. */ -int read_metadata_resource(FILE *fp, const struct resource_entry *res_entry, - int wim_ctype, struct image_metadata *image_metadata) +int read_metadata_resource(FILE *fp, int wim_ctype, struct image_metadata *imd) { u8 *buf; int ctype; u32 dentry_offset; int ret; - struct dentry *dentry = NULL; + const struct resource_entry *res_entry; + struct dentry *dentry; +#ifdef ENABLE_SECURITY_DATA + struct wim_security_data *sd; +#endif + + res_entry = &imd->metadata_lte->resource_entry; - DEBUG("Reading metadata resource: length = %lu, offset = %lu\n", - res_entry->original_size, res_entry->offset); + DEBUG("Reading metadata resource: length = %"PRIu64", " + "offset = %"PRIu64"", + res_entry->original_size, res_entry->offset); if (res_entry->original_size < 8) { - ERROR("Expected at least 8 bytes for the metadata " - "resource!\n"); + ERROR("Expected at least 8 bytes for the metadata resource"); return WIMLIB_ERR_INVALID_RESOURCE_SIZE; } @@ -938,8 +943,7 @@ int read_metadata_resource(FILE *fp, const struct resource_entry *res_entry, if (!buf) { ERROR("Failed to allocate %"PRIu64" bytes for uncompressed " - "metadata resource!\n", - res_entry->original_size); + "metadata resource", res_entry->original_size); return WIMLIB_ERR_NOMEM; } @@ -951,62 +955,66 @@ int read_metadata_resource(FILE *fp, const struct resource_entry *res_entry, res_entry->original_size, res_entry->offset, ctype, buf); if (ret != 0) - goto err1; - - DEBUG("Finished reading metadata resource into memory.\n"); + goto out_free_buf; + DEBUG("Finished reading metadata resource into memory."); - dentry = MALLOC(sizeof(struct dentry)); - if (!dentry) { - ERROR("Failed to allocate %zu bytes for root dentry!\n", - sizeof(struct dentry)); - ret = WIMLIB_ERR_NOMEM; - goto err1; - } - - /* Read the root directory entry starts after security data, on an - * 8-byte aligned address. + /* The root directory entry starts after security data, on an 8-byte + * aligned address. * * The security data starts with a 4-byte integer giving its total * length. */ - /* Read the security data into a WIMSecurityData structure. */ #ifdef ENABLE_SECURITY_DATA - ret = read_security_data(buf, res_entry->original_size, - &image_metadata->security_data); + /* Read the security data into a wim_security_data structure. */ + ret = read_security_data(buf, res_entry->original_size, &sd); if (ret != 0) - goto err1; + goto out_free_buf; #endif + + dentry = MALLOC(sizeof(struct dentry)); + if (!dentry) { + ERROR("Failed to allocate %zu bytes for root dentry", + sizeof(struct dentry)); + ret = WIMLIB_ERR_NOMEM; + goto out_free_security_data; + } + get_u32(buf, &dentry_offset); if (dentry_offset == 0) dentry_offset = 8; - dentry_offset += (8 - dentry_offset % 8) % 8; + dentry_offset = (dentry_offset + 7) & ~7; ret = read_dentry(buf, res_entry->original_size, dentry_offset, dentry); - if (ret != 0) - goto err1; - /* This is the root dentry, so set its pointers correctly. */ dentry->parent = dentry; dentry->next = dentry; dentry->prev = dentry; + if (ret != 0) + goto out_free_dentry_tree; /* Now read the entire directory entry tree. */ ret = read_dentry_tree(buf, res_entry->original_size, dentry); if (ret != 0) - goto err2; + goto out_free_dentry_tree; /* Calculate the full paths in the dentry tree. */ ret = for_dentry_in_tree(dentry, calculate_dentry_full_path, NULL); if (ret != 0) - goto err2; + goto out_free_dentry_tree; - image_metadata->root_dentry = dentry; - FREE(buf); - return ret; -err2: +#ifdef ENABLE_SECURITY_DATA + imd->security_data = sd; +#endif + imd->root_dentry = dentry; + goto out_free_buf; +out_free_security_data: +#ifdef ENABLE_SECURITY_DATA + free_security_data(sd); +#endif +out_free_dentry_tree: free_dentry_tree(dentry, NULL, false); -err1: +out_free_buf: FREE(buf); return ret; } @@ -1028,7 +1036,7 @@ int write_metadata_resource(WIMStruct *w) int metadata_ctype; u8 hash[WIM_HASH_SIZE]; - DEBUG("Writing metadata resource for image %u\n", w->current_image); + DEBUG("Writing metadata resource for image %d", w->current_image); out = w->out_fp; root = wim_root_dentry(w); @@ -1049,7 +1057,7 @@ int write_metadata_resource(WIMStruct *w) buf = MALLOC(metadata_original_size); if (!buf) { ERROR("Failed to allocate %"PRIu64" bytes for " - "metadata resource\n", metadata_original_size); + "metadata resource", metadata_original_size); return WIMLIB_ERR_NOMEM; } #ifdef ENABLE_SECURITY_DATA @@ -1060,7 +1068,7 @@ int write_metadata_resource(WIMStruct *w) p = put_u32(p, 0); /* Number of security data entries. */ #endif - DEBUG("Writing dentry tree.\n"); + DEBUG("Writing dentry tree."); p = write_dentry_tree(root, p); /* Like file resources, the lookup table entry for a metadata resource @@ -1100,15 +1108,17 @@ int write_metadata_resource(WIMStruct *w) * Writes a file resource to the output file. * * @dentry: The dentry for the file resource. - * @wim_p: A pointer to the WIMStruct. The fields of interest to this - * function are the input and output file streams and the lookup table. + * @wim_p: A pointer to the WIMStruct. The fields of interest to this + * function are the input and output file streams and the lookup + * table. + * * @return zero on success, nonzero on failure. */ int write_file_resource(struct dentry *dentry, void *wim_p) { WIMStruct *w; - FILE *out; - FILE *in; + FILE *out_fp; + FILE *in_fp; struct lookup_table_entry *lte; int in_wim_ctype; int out_wim_ctype; @@ -1117,7 +1127,7 @@ int write_file_resource(struct dentry *dentry, void *wim_p) int ret; w = wim_p; - out = w->out_fp; + out_fp = w->out_fp; /* Directories don't need file resources. */ if (dentry_is_directory(dentry)) @@ -1148,20 +1158,20 @@ int write_file_resource(struct dentry *dentry, void *wim_p) len = lte->resource_entry.original_size; - in = fopen(lte->file_on_disk, "rb"); - if (!in) { - ERROR("Failed to open the file `%s': %m\n", - lte->file_on_disk); + in_fp = fopen(lte->file_on_disk, "rb"); + if (!in_fp) { + ERROR_WITH_ERRNO("Failed to open the file `%s'", + lte->file_on_disk); return WIMLIB_ERR_OPEN; } if (w->verbose) puts(lte->file_on_disk); - ret = transfer_file_resource(in, len, len, 0, - WIM_COMPRESSION_TYPE_NONE, out, + ret = transfer_file_resource(in_fp, len, len, 0, + WIM_COMPRESSION_TYPE_NONE, out_fp, out_wim_ctype, output_res_entry); - fclose(in); + fclose(in_fp); } else { /* Read from input WIM (possibly compressed) */ @@ -1170,25 +1180,25 @@ int write_file_resource(struct dentry *dentry, void *wim_p) * exporting images from one WIM file to another */ if (lte->other_wim_fp) { /* Different WIM file. */ - in = lte->other_wim_fp; + in_fp = lte->other_wim_fp; in_wim_ctype = lte->other_wim_ctype; } else { /* Same WIM file. */ - in = w->fp; + in_fp = w->fp; in_wim_ctype = out_wim_ctype; } int input_res_ctype = resource_compression_type( - in_wim_ctype, - lte->resource_entry.flags); - - ret = transfer_file_resource(in, - lte->resource_entry.size, - lte->resource_entry.original_size, - lte->resource_entry.offset, - input_res_ctype, - out, - out_wim_ctype, - output_res_entry); + in_wim_ctype, + lte->resource_entry.flags); + + ret = transfer_file_resource(in_fp, + lte->resource_entry.size, + lte->resource_entry.original_size, + lte->resource_entry.offset, + input_res_ctype, + out_fp, + out_wim_ctype, + output_res_entry); } return ret; } diff --git a/src/security.c b/src/security.c index 65d8555c..9707bd31 100644 --- a/src/security.c +++ b/src/security.c @@ -35,63 +35,74 @@ * * @metadata_resource: An array that contains the uncompressed metadata * resource for the WIM file. - * @metadata_resource_len: The length of @metadata_resource. - * @sd_p: A pointer to a pointer wim_security_data structure that will be filled - * in with a pointer to a new wim_security_data structure on success. + * @metadata_resource_len: The length of @metadata_resource. It MUST be at + * least 8 bytes. + * @sd_p: A pointer to a pointer to a wim_security_data structure that + * will be filled in with a pointer to a new wim_security_data + * structure on success. * * Note: There is no `offset' argument because the security data is located at * the beginning of the metadata resource. */ -int read_security_data(const u8 metadata_resource[], - u64 metadata_resource_len, struct wim_security_data **sd_p) +int read_security_data(const u8 metadata_resource[], u64 metadata_resource_len, + struct wim_security_data **sd_p) { struct wim_security_data *sd; const u8 *p; - u64 sizes_size; + int ret; + u64 total_len; - if (metadata_resource_len < 8) { - ERROR("Not enough space in %"PRIu64"-byte file resource for " - "security data!\n", metadata_resource_len); - return WIMLIB_ERR_INVALID_RESOURCE_SIZE; - } sd = MALLOC(sizeof(struct wim_security_data)); - if (!sd) + if (!sd) { + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; - p = get_u32(metadata_resource, &sd->total_length); + } + sd->sizes = NULL; + sd->descriptors = NULL; + sd->refcnt = 1; + + p = metadata_resource; + p = get_u32(p, &sd->total_length); p = get_u32(p, &sd->num_entries); /* Verify the listed total length of the security data is big enough to * include the sizes array, verify that the file data is big enough to - * include it as well, then allocate the array of sizes. */ - sizes_size = sd->num_entries * sizeof(u64); + * include it as well, then allocate the array of sizes. + * + * Note: The total length of the security data must fit in a 32-bit + * integer, even though each security descriptor size is a 64-bit + * integer. This is stupid, and we need to be careful not to actually + * let the security descriptor sizes be over 0xffffffff. */ + if ((u64)sd->total_length > metadata_resource_len) { + ERROR("Security data total length (%u) is bigger than the " + "metadata resource length (%"PRIu64")", + sd->total_length, metadata_resource_len); + ret = WIMLIB_ERR_INVALID_RESOURCE_SIZE; + goto out_free_sd; + } - DEBUG("Reading security data with %u entries\n", sd->num_entries); + DEBUG("Reading security data: %u entries, length = %u", + sd->num_entries, sd->total_length); if (sd->num_entries == 0) { - FREE(sd); - return 0; + /* No security data. */ + total_len = 8; + goto out; } + u64 sizes_size = (u64)sd->num_entries * sizeof(u64); u64 size_no_descriptors = 8 + sizes_size; - if (size_no_descriptors > sd->total_length) { - ERROR("Security data total length of %u is too short because\n" - "there must be at least %"PRIu64" bytes of security " - "data!\n", sd->total_length, - 8 + sizes_size); - FREE(sd); - return WIMLIB_ERR_INVALID_RESOURCE_SIZE; - } - if (size_no_descriptors > metadata_resource_len) { - ERROR("File resource of %"PRIu64" bytes is not big enough\n" - "to hold security data of at least %"PRIu64" " - "bytes!\n", metadata_resource_len, size_no_descriptors); - FREE(sd); - return WIMLIB_ERR_INVALID_RESOURCE_SIZE; + if (size_no_descriptors > (u64)sd->total_length) { + ERROR("Security data total length of %u is too short because " + "there must be at least %"PRIu64" bytes of security data", + sd->total_length, 8 + sizes_size); + ret = WIMLIB_ERR_INVALID_RESOURCE_SIZE; + goto out_free_sd; } sd->sizes = MALLOC(sizes_size); if (!sd->sizes) { - FREE(sd); - return WIMLIB_ERR_NOMEM; + ret = WIMLIB_ERR_NOMEM; + goto out_free_sd; } /* Copy the sizes array in from the file data. */ @@ -101,39 +112,46 @@ int read_security_data(const u8 metadata_resource[], /* Allocate the array of pointers to descriptors, and read them in. */ sd->descriptors = CALLOC(sd->num_entries, sizeof(u8*)); if (!sd->descriptors) { - FREE(sd); - FREE(sd->sizes); - return WIMLIB_ERR_NOMEM; + ERROR("Out of memory while allocating security " + "descriptors"); + ret = WIMLIB_ERR_NOMEM; + goto out_free_sd; } - u64 total_len = size_no_descriptors; + total_len = size_no_descriptors; - for (uint i = 0; i < sd->num_entries; i++) { - total_len += sd->sizes[i]; - if (total_len > sd->total_length) { - ERROR("Security data total length of %u is too " - "short because there are at least %"PRIu64" " - "bytes of security data!\n", - sd->total_length, total_len); - free_security_data(sd); - return WIMLIB_ERR_INVALID_RESOURCE_SIZE; + for (u32 i = 0; i < sd->num_entries; i++) { + /* Watch out for huge security descriptor sizes that could + * overflow the total length and wrap it around. */ + if (total_len + sd->sizes[i] < total_len) { + ERROR("Caught overflow in security descriptor lengths " + "(current total length = %"PRIu64", security " + "descriptor size = %"PRIu64")", + total_len, sd->sizes[i]); } - if (total_len > metadata_resource_len) { - ERROR("File resource of %"PRIu64" bytes is not big enough " - "to hold security data of at least %"PRIu64" " - "bytes!\n", metadata_resource_len, total_len); - free_security_data(sd); - return WIMLIB_ERR_INVALID_RESOURCE_SIZE; + total_len += sd->sizes[i]; + if (total_len > (u64)sd->total_length) { + ERROR("Security data total length of %u is too short " + "because there are at least %"PRIu64" bytes of " + "security data", sd->total_length, total_len); + ret = WIMLIB_ERR_INVALID_RESOURCE_SIZE; + goto out_free_sd; } sd->descriptors[i] = MALLOC(sd->sizes[i]); if (!sd->descriptors[i]) { - free_security_data(sd); - return WIMLIB_ERR_NOMEM; + ERROR("Out of memory while allocating security " + "descriptors"); + ret = WIMLIB_ERR_NOMEM; + goto out_free_sd; } p = get_bytes(p, sd->sizes[i], sd->descriptors[i]); } - sd->refcnt = 1; +out: + sd->total_length = (u32)total_len; *sd_p = sd; return 0; +out_free_sd: + free_security_data(sd); + return ret; } /* @@ -141,31 +159,23 @@ int read_security_data(const u8 metadata_resource[], */ u8 *write_security_data(const struct wim_security_data *sd, u8 *p) { - if (sd) { - DEBUG("Writing security data (total_length = %u, " - "num_entries = %u)\n", sd->total_length, - sd->num_entries); - u8 *orig_p = p; - p = put_u32(p, sd->total_length); - p = put_u32(p, sd->num_entries); + DEBUG("Writing security data (total_length = %"PRIu32", num_entries " + "= %"PRIu32")", sd->total_length, sd->num_entries); - for (uint i = 0; i < sd->num_entries; i++) - p = put_u64(p, sd->sizes[i]); + u8 *orig_p = p; + p = put_u32(p, sd->total_length); + p = put_u32(p, sd->num_entries); - for (uint i = 0; i < sd->num_entries; i++) - p = put_bytes(p, sd->sizes[i], sd->descriptors[i]); + for (u32 i = 0; i < sd->num_entries; i++) + p = put_u64(p, sd->sizes[i]); - wimlib_assert(p - orig_p <= sd->total_length); + for (u32 i = 0; i < sd->num_entries; i++) + p = put_bytes(p, sd->sizes[i], sd->descriptors[i]); - DEBUG("Successfully wrote security data.\n"); - return orig_p + sd->total_length; - } else { - DEBUG("Writing security data (total_length = 8, " - "num_entries = 0)\n"); - p = put_u32(p, 8); - return put_u32(p, 0); + wimlib_assert(p - orig_p == sd->total_length); - } + DEBUG("Successfully wrote security data."); + return p; } /* XXX We don't actually do anything with the ACL's yet besides being able to @@ -241,22 +251,14 @@ static void print_security_descriptor(const u8 *p, u64 size) void print_security_data(const struct wim_security_data *sd) { puts("[SECURITY DATA]"); - if (sd) { - printf("Length = %u bytes\n", sd->total_length); - printf("Number of Entries = %u\n", sd->num_entries); + printf("Length = %"PRIu32" bytes\n", sd->total_length); + printf("Number of Entries = %"PRIu32"\n", sd->num_entries); - u64 num_entries = (u64)sd->num_entries; - for (u64 i = 0; i < num_entries; i++) { - printf("[SecurityDescriptor %"PRIu64", " - "length = %"PRIu64"]\n", - i, sd->sizes[i]); - print_security_descriptor(sd->descriptors[i], - sd->sizes[i]); - putchar('\n'); - } - } else { - puts("Length = 8 bytes\n" - "Number of Entries = 0"); + for (u32 i = 0; i < sd->num_entries; i++) { + printf("[SecurityDescriptor %"PRIu32", length = %"PRIu64"]\n", + i, sd->sizes[i]); + print_security_descriptor(sd->descriptors[i], sd->sizes[i]); + putchar('\n'); } putchar('\n'); } @@ -268,8 +270,7 @@ void free_security_data(struct wim_security_data *sd) wimlib_assert(sd->refcnt >= 1); if (sd->refcnt == 1) { u8 **descriptors = sd->descriptors; - u32 num_entries = sd->num_entries; - + u32 num_entries = sd->num_entries; if (descriptors) while (num_entries--) FREE(*descriptors++); diff --git a/src/sha1.c b/src/sha1.c index b65d25d6..7fd67bce 100644 --- a/src/sha1.c +++ b/src/sha1.c @@ -245,10 +245,15 @@ int sha1sum(const char *filename, void *md) fp = fopen(filename, "rb"); if (!fp) { - ERROR("Cannot open the file `%s' for reading: %m\n", filename); + ERROR_WITH_ERRNO("Cannot open the file `%s' for reading", + filename); return WIMLIB_ERR_OPEN; } ret = sha1_stream(fp, md); + if (ret != 0) { + ERROR_WITH_ERRNO("Error calculating SHA1 message digest of " + "`%s'", filename); + } fclose(fp); return ret; } diff --git a/src/split.c b/src/split.c index 25cca9f9..0c41e1ff 100644 --- a/src/split.c +++ b/src/split.c @@ -49,7 +49,7 @@ static int finish_swm(WIMStruct *w, struct lookup_table_entry *lte_chain_head, off_t lookup_table_offset = ftello(w->out_fp); int ret; - DEBUG("Writing lookup table for SWM (offset %"PRIu64")\n", + DEBUG("Writing lookup table for SWM (offset %"PRIu64")", lookup_table_offset); while (lte_chain_head != NULL) { @@ -107,12 +107,12 @@ static int copy_resource_to_swm(struct lookup_table_entry *lte, void *__args) if (args->write_flags & WIMLIB_OPEN_FLAG_SHOW_PROGRESS) printf("Writing `%s' (%"PRIu64" of %"PRIu64" bytes, " - "%.0f%% done)\n", - args->swm_base_name, - args->total_bytes_written, - args->total_bytes, - (double)args->total_bytes_written / - (double)args->total_bytes * 100.0); + "%.0f%% done)\n", + args->swm_base_name, + args->total_bytes_written, + args->total_bytes, + (double)args->total_bytes_written / + (double)args->total_bytes * 100.0); ret = begin_write(w, args->swm_base_name, args->write_flags); if (ret != 0) @@ -187,7 +187,7 @@ WIMLIBAPI int wimlib_split(const char *wimfile, const char *swm_name, struct lookup_table_entry *metadata_lte; - metadata_lte = w->image_metadata[i].lookup_table_entry; + metadata_lte = w->image_metadata[i].metadata_lte; ret = copy_resource(metadata_lte, w); if (ret != 0) return ret; @@ -240,7 +240,7 @@ WIMLIBAPI int wimlib_split(const char *wimfile, const char *swm_name, FILE *fp = fopen(p, "r+b"); if (!fp) { - ERROR("Failed to open `%s': %m\n", p); + ERROR_WITH_ERRNO("Failed to open `%s'"); return WIMLIB_ERR_OPEN; } u8 buf[4]; @@ -250,12 +250,13 @@ WIMLIBAPI int wimlib_split(const char *wimfile, const char *swm_name, if (fseek(fp, 40, SEEK_SET) != 0 || fwrite(buf, 1, sizeof(buf), fp) != sizeof(buf) || fclose(fp) != 0) { - ERROR("Error overwriting header of `%s': %m\n", name); + ERROR_WITH_ERRNO("Error overwriting header of `%s'", + name); return WIMLIB_ERR_WRITE; } } if (write_flags & WIMLIB_OPEN_FLAG_SHOW_PROGRESS) - printf("Done!\n"); + puts("Done!"); wimlib_free(w); return 0; } diff --git a/src/util.c b/src/util.c index bdd0a294..474c6f10 100644 --- a/src/util.c +++ b/src/util.c @@ -35,8 +35,8 @@ #include #include -/* True if WIMLIB is to print an informational message when an error occurs. - * This can be turned off by calling wimlib_set_error_messages(false). */ +/* True if wimlib is to print an informational message when an error occurs. + * This can be turned off by calling wimlib_set_print_errors(false). */ #ifdef ENABLE_ERROR_MESSAGES #include bool __wimlib_print_errors = false; @@ -51,6 +51,23 @@ void wimlib_error(const char *format, ...) errno_save = errno; fputs("ERROR: ", stderr); vfprintf(stderr, format, va); + putc('\n', stderr); + errno = errno_save; + va_end(va); + } +} + +void wimlib_error_with_errno(const char *format, ...) +{ + if (__wimlib_print_errors) { + va_list va; + int errno_save; + + va_start(va, format); + errno_save = errno; + fputs("ERROR: ", stderr); + vfprintf(stderr, format, va); + fprintf(stderr, ": %s\n", strerror(errno_save)); errno = errno_save; va_end(va); } @@ -66,6 +83,7 @@ void wimlib_warning(const char *format, ...) errno_save = errno; fputs("WARNING: ", stderr); vfprintf(stderr, format, va); + putc('\n', stderr); errno = errno_save; va_end(va); } @@ -178,8 +196,8 @@ WIMLIBAPI const char *wimlib_get_error_string(enum wimlib_error_code code) #ifdef ENABLE_CUSTOM_MEMORY_ALLOCATOR -void *(*wimlib_malloc_func)(size_t) = malloc; -void (*wimlib_free_func)(void *) = free; +void *(*wimlib_malloc_func) (size_t) = malloc; +void (*wimlib_free_func) (void *) = free; void *(*wimlib_realloc_func)(void *, size_t) = realloc; void *wimlib_calloc(size_t nmemb, size_t size) @@ -221,9 +239,9 @@ WIMLIBAPI int wimlib_set_memory_allocator(void *(*malloc_func)(size_t), wimlib_realloc_func); return 0; #else - ERROR("Cannot set custom memory allocator functions:\n"); - ERROR("wimlib was compiled with the " - "--without-custom-memory-allocator flag\n"); + ERROR("Cannot set custom memory allocator functions:"); + ERROR("wimlib was compiled with the --without-custom-memory-allocator " + "flag"); return WIMLIB_ERR_UNSUPPORTED; #endif } @@ -240,8 +258,8 @@ char *utf16_to_utf8(const char *utf16_str, size_t utf16_len, if (cd_utf16_to_utf8 == (iconv_t)(-1)) { cd_utf16_to_utf8 = iconv_open("UTF-8", "UTF-16LE"); if (cd_utf16_to_utf8 == (iconv_t)-1) { - ERROR("Failed to get conversion descriptor for " - "converting UTF-16LE to UTF-8: %m\n"); + ERROR_WITH_ERRNO("Failed to get conversion descriptor " + "for converting UTF-16LE to UTF-8"); return NULL; } } @@ -258,8 +276,8 @@ char *utf16_to_utf8(const char *utf16_str, size_t utf16_len, &utf16_bytes_left, &utf8_str, &utf8_bytes_left); if (num_chars_converted == (size_t)(-1)) { - ERROR("Failed to convert UTF-16LE string to UTF-8 string: " - "%m\n"); + ERROR_WITH_ERRNO("Failed to convert UTF-16LE string to UTF-8 " + "string"); FREE(orig_utf8_str); return NULL; } @@ -281,8 +299,8 @@ char *utf8_to_utf16(const char *utf8_str, size_t utf8_len, if (cd_utf8_to_utf16 == (iconv_t)(-1)) { cd_utf8_to_utf16 = iconv_open("UTF-16LE", "UTF-8"); if (cd_utf8_to_utf16 == (iconv_t)-1) { - ERROR("Failed to get conversion descriptor for " - "converting UTF-8 to UTF-16LE: %m\n"); + ERROR_WITH_ERRNO("Failed to get conversion descriptor " + "for converting UTF-8 to UTF-16LE"); return NULL; } } @@ -301,11 +319,8 @@ char *utf8_to_utf16(const char *utf8_str, size_t utf8_len, &utf8_bytes_left, &utf16_str, &utf16_bytes_left); if (num_chars_converted == (size_t)(-1)) { - ERROR("Failed to convert UTF-8 string to UTF-16LE string: " - "%s\n", - (errno == E2BIG) ? - "Not enough room in output buffer" : - strerror(errno)); + ERROR_WITH_ERRNO("Failed to convert UTF-8 string to UTF-16LE " + "string"); FREE(orig_utf16_str); return NULL; } @@ -470,4 +485,3 @@ void print_string(const void *string, size_t len) p++; } } - diff --git a/src/util.h b/src/util.h index 3d917bf5..a3984bb3 100644 --- a/src/util.h +++ b/src/util.h @@ -53,24 +53,29 @@ typedef unsigned uint; extern bool __wimlib_print_errors; extern void wimlib_error(const char *format, ...) FORMAT(printf, 1, 2) COLD; +extern void wimlib_error_with_errno(const char *format, ...) + FORMAT(printf, 1, 2) COLD; extern void wimlib_warning(const char *format, ...) FORMAT(printf, 1, 2) COLD; -# define ERROR wimlib_error -# define WARNING wimlib_warning +# define ERROR wimlib_error +# define ERROR_WITH_ERRNO wimlib_error_with_errno +# define WARNING wimlib_warning #else # define ERROR(format, ...) +# define ERROR_WITH_ERRNO(format, ...) # define WARNING(format, ...) #endif /* ENABLE_ERROR_MESSAGES */ #if defined(ENABLE_DEBUG) || defined(ENABLE_MORE_DEBUG) # include -# define DEBUG(format, ...) \ - ({ \ - int __errno_save = errno; \ - fprintf(stdout, "[%s %d] %s(): " format, \ - __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ - fflush(stdout); \ - errno = __errno_save; \ +# define DEBUG(format, ...) \ + ({ \ + int __errno_save = errno; \ + fprintf(stdout, "[%s %d] %s(): " format, \ + __FILE__, __LINE__, __func__, ## __VA_ARGS__); \ + putchar('\n'); \ + fflush(stdout); \ + errno = __errno_save; \ }) #else diff --git a/src/wim.c b/src/wim.c index 99a8c700..268b3811 100644 --- a/src/wim.c +++ b/src/wim.c @@ -66,38 +66,38 @@ WIMStruct *new_wim_struct() */ int for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *)) { - int ret = 0; + int ret; int i; - int image_count; + int end; - DEBUG("for_image(w = %p, image = %d, visitor = %p)\n", - w, image, visitor); + DEBUG("for_image(w = %p, image = %d, visitor = %p)", w, image, visitor); if (image == WIM_ALL_IMAGES) { - image_count = w->hdr.image_count; - for (i = 1; i <= image_count; i++) { - ret = wimlib_select_image(w, i); - if (ret != 0) - return ret; - ret = visitor(w); - if (ret != 0) - return ret; - } + i = 1; + end = w->hdr.image_count; } else { - ret = wimlib_select_image(w, image); + if (image < 1 || image > w->hdr.image_count) + return WIMLIB_ERR_INVALID_IMAGE; + i = image; + end = image; + } + do { + ret = wimlib_select_image(w, i); if (ret != 0) return ret; ret = visitor(w); - } - return ret; + if (ret != 0) + return ret; + } while (i++ != end); + return 0; } static int sort_image_metadata_by_position(const void *p1, const void *p2) { struct image_metadata *bmd1 = (struct image_metadata*)p1; struct image_metadata *bmd2 = (struct image_metadata*)p2; - u64 offset1 = bmd1->lookup_table_entry->resource_entry.offset; - u64 offset2 = bmd2->lookup_table_entry->resource_entry.offset; + u64 offset1 = bmd1->metadata_lte->resource_entry.offset; + u64 offset2 = bmd2->metadata_lte->resource_entry.offset; if (offset1 < offset2) return -1; else if (offset1 > offset2) @@ -108,7 +108,7 @@ static int sort_image_metadata_by_position(const void *p1, const void *p2) /* * If @lte points to a metadata resource, append it to the list of metadata - * resources in the WIMStruct. + * resources in the WIMStruct. Otherwise, do nothing. */ static int append_metadata_resource_entry(struct lookup_table_entry *lte, void *wim_p) @@ -117,19 +117,18 @@ static int append_metadata_resource_entry(struct lookup_table_entry *lte, if (lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) { if (w->current_image == w->hdr.image_count) { - ERROR("Expected only %u images, but found more!\n", - w->hdr.image_count); + ERROR("Expected only %u images, but found more", + w->hdr.image_count); return WIMLIB_ERR_IMAGE_COUNT; } else { DEBUG("Found metadata resource for image %u at " - "offset %"PRIu64"\n", w->current_image + 1, - lte->resource_entry.offset); + "offset %"PRIu64".", + w->current_image + 1, + lte->resource_entry.offset); w->image_metadata[ - w->current_image++].lookup_table_entry = lte; + w->current_image++].metadata_lte = lte; } } - - /* Do nothing if not a metadata resource. */ return 0; } @@ -169,8 +168,8 @@ WIMLIBAPI int wimlib_create_new_wim(int ctype, WIMStruct **w_ret) struct lookup_table *table; int ret; - DEBUG("Creating new WIM with %s compression\n", - wimlib_get_compression_type_string(ctype)); + DEBUG("Creating new WIM with %s compression.", + wimlib_get_compression_type_string(ctype)); /* Allocate the WIMStruct. */ w = new_wim_struct(); @@ -179,17 +178,17 @@ WIMLIBAPI int wimlib_create_new_wim(int ctype, WIMStruct **w_ret) ret = init_header(&w->hdr, ctype); if (ret != 0) - goto err; + goto out_free; table = new_lookup_table(9001); if (!table) { ret = WIMLIB_ERR_NOMEM; - goto err; + goto out_free; } w->lookup_table = table; *w_ret = w; return 0; -err: +out_free: FREE(w); return ret; } @@ -201,49 +200,49 @@ WIMLIBAPI int wimlib_get_num_images(const WIMStruct *w) int wimlib_select_image(WIMStruct *w, int image) { - DEBUG("Selecting image %u\n", image); + struct image_metadata *imd; + + DEBUG("Selecting image %d", image); if (image == w->current_image) return 0; - if (image > w->hdr.image_count || image < 1) { - ERROR("Cannot select image %u: There are only %u images!\n", - image, w->hdr.image_count); + if (image < 1 || image > w->hdr.image_count) { + ERROR("Cannot select image %d: There are only %u images", + image, w->hdr.image_count); return WIMLIB_ERR_INVALID_IMAGE; } - /* If a valid image is selected, it can be freed if it is not modified. - * */ - if (w->current_image != WIM_NO_IMAGE && - !wim_current_image_is_modified(w)) { - - struct image_metadata *imd; - - DEBUG("Freeing image %u\n", w->current_image); + /* If a valid image is currently selected, it can be freed if it is not + * modified. */ + if (w->current_image != WIM_NO_IMAGE) { imd = wim_get_current_image_metadata(w); - free_dentry_tree(imd->root_dentry, NULL, false); - imd->root_dentry = NULL; + if (!imd->modified) { + DEBUG("Freeing image %u", w->current_image); + free_dentry_tree(imd->root_dentry, NULL, false); + imd->root_dentry = NULL; #ifdef ENABLE_SECURITY_DATA - free_security_data(imd->security_data); - imd->security_data = NULL; + free_security_data(imd->security_data); + imd->security_data = NULL; #endif + } } w->current_image = image; + imd = wim_get_current_image_metadata(w); - if (wim_root_dentry(w)) { + if (imd->root_dentry) { return 0; } else { #ifdef ENABLE_DEBUG DEBUG("Reading metadata resource specified by the following " - "lookup table entry:\n"); - print_lookup_table_entry(wim_metadata_lookup_table_entry(w), NULL); + "lookup table entry:"); + print_lookup_table_entry(imd->metadata_lte, NULL); #endif return read_metadata_resource(w->fp, - wim_metadata_resource_entry(w), - wimlib_get_compression_type(w), - wim_get_current_image_metadata(w)); + wimlib_get_compression_type(w), + imd); } } @@ -284,15 +283,15 @@ WIMLIBAPI int wimlib_resolve_image(WIMStruct *w, const char *image_name_or_num) if (strcmp(image_name_or_num, "all") == 0) return WIM_ALL_IMAGES; - image = strtoul(image_name_or_num, &p, 10); - if (*p == '\0') { + image = strtol(image_name_or_num, &p, 10); + if (p != image_name_or_num && *p == '\0') { if (image < 1 || image > w->hdr.image_count) return WIM_NO_IMAGE; return image; } else { for (i = 1; i <= w->hdr.image_count; i++) { - if (strcmp(image_name_or_num, - wimlib_get_image_name(w, i)) == 0) + if (strcmp(image_name_or_num, + wimlib_get_image_name(w, i)) == 0) return i; } return WIM_NO_IMAGE; @@ -328,7 +327,6 @@ WIMLIBAPI bool wimlib_has_integrity_table(const WIMStruct *w) return w->hdr.integrity.size != 0; } - WIMLIBAPI void wimlib_print_available_images(const WIMStruct *w, int image) { if (image == WIM_ALL_IMAGES) { @@ -371,8 +369,8 @@ WIMLIBAPI int wimlib_set_boot_idx(WIMStruct *w, int boot_idx) sizeof(struct resource_entry)); } else { memcpy(&w->hdr.boot_metadata_res_entry, - &w->image_metadata[boot_idx - 1].lookup_table_entry-> - resource_entry, + &w->image_metadata[ + boot_idx - 1].metadata_lte->resource_entry, sizeof(struct resource_entry)); } return 0; @@ -399,112 +397,105 @@ static int begin_read(WIMStruct *w, const char *in_wim_path, int flags) { int ret; uint xml_num_images; - int integrity_status; - DEBUG("Reading the WIM file `%s'\n", in_wim_path); + DEBUG("Reading the WIM file `%s'", in_wim_path); w->filename = STRDUP(in_wim_path); if (!w->filename) { - ERROR("Failed to allocate memory for WIM filename.\n"); + ERROR("Failed to allocate memory for WIM filename"); return WIMLIB_ERR_NOMEM; } w->fp = fopen(in_wim_path, "rb"); if (!w->fp) { - ERROR("Failed to open the file \"%s\" for reading: %m\n", - in_wim_path); - ret = WIMLIB_ERR_OPEN; - goto done; + ERROR_WITH_ERRNO("Failed to open the file `%s' for reading"); + return WIMLIB_ERR_OPEN; } ret = read_header(w->fp, &w->hdr, flags & WIMLIB_OPEN_FLAG_SPLIT_OK); if (ret != 0) - goto done; + return ret; - DEBUG("Wim file contains %u images\n", w->hdr.image_count); + DEBUG("Wim file contains %u images", w->hdr.image_count); /* If the boot index is invalid, print a warning and set it to 0 */ if (w->hdr.boot_idx > w->hdr.image_count) { - WARNING("In `%s', image %u is marked as bootable,\n" - "\tbut there are only %u images!\n", + WARNING("In `%s', image %u is marked as bootable, " + "but there are only %u images", in_wim_path, w->hdr.boot_idx, w->hdr.image_count); w->hdr.boot_idx = 0; } if (wimlib_get_compression_type(w) == WIM_COMPRESSION_TYPE_INVALID) { - ERROR("Invalid compression type (WIM header flags " - "= %x)\n", w->hdr.flags); - ret = WIMLIB_ERR_INVALID_COMPRESSION_TYPE; - goto done; + ERROR("Invalid compression type (WIM header flags = %x)", + w->hdr.flags); + return WIMLIB_ERR_INVALID_COMPRESSION_TYPE; } if (flags & WIMLIB_OPEN_FLAG_CHECK_INTEGRITY) { + int integrity_status; ret = check_wim_integrity(w, flags & WIMLIB_OPEN_FLAG_SHOW_PROGRESS, &integrity_status); if (ret != 0) { - ERROR("Error in check_wim_integrity()\n"); - goto done; + ERROR("Error in check_wim_integrity()"); + return ret; } if (integrity_status == WIM_INTEGRITY_NONEXISTENT) { WARNING("No integrity information for `%s'; skipping " - "integrity check.\n", w->filename); + "integrity check.", w->filename); } else if (integrity_status == WIM_INTEGRITY_NOT_OK) { - ERROR("WIM is not intact! (Failed integrity check)\n"); - ret = WIMLIB_ERR_INTEGRITY; - goto done; + ERROR("WIM is not intact! (Failed integrity check)"); + return WIMLIB_ERR_INTEGRITY; } } if (resource_is_compressed(&w->hdr.lookup_table_res_entry)) { - ERROR("Didn't expect a compressed lookup table!\n"); - ERROR("Ask the author to implement support for this.\n"); - ret = WIMLIB_ERR_COMPRESSED_LOOKUP_TABLE; - goto done; + ERROR("Didn't expect a compressed lookup table!"); + ERROR("Ask the author to implement support for this."); + return WIMLIB_ERR_COMPRESSED_LOOKUP_TABLE; } ret = read_lookup_table(w->fp, w->hdr.lookup_table_res_entry.offset, w->hdr.lookup_table_res_entry.size, &w->lookup_table); - if (ret != 0) - goto done; + return ret; w->image_metadata = CALLOC(w->hdr.image_count, sizeof(struct image_metadata)); if (!w->image_metadata) { - ERROR("Failed to allocate memory for %u metadata structures\n", - w->hdr.image_count); - goto done; + ERROR("Failed to allocate memory for %u metadata structures", + w->hdr.image_count); + return WIMLIB_ERR_NOMEM; } w->current_image = 0; - DEBUG("Looking for metadata resources in the lookup table.\n"); + DEBUG("Looking for metadata resources in the lookup table."); /* Find the images in the WIM by searching the lookup table. */ ret = for_lookup_table_entry(w->lookup_table, append_metadata_resource_entry, w); - if (ret != 0 && w->hdr.part_number == 1) - goto done; + if (ret != 0) + return ret; /* Make sure all the expected images were found. (We already have * returned false if *extra* images were found) */ if (w->current_image != w->hdr.image_count && w->hdr.part_number == 1) { - ERROR("Only found %u images in WIM, but expected %u!\n", - w->current_image, w->hdr.image_count); - ret = WIMLIB_ERR_IMAGE_COUNT; - goto done; + ERROR("Only found %u images in WIM, but expected %u", + w->current_image, w->hdr.image_count); + return WIMLIB_ERR_IMAGE_COUNT; } /* Sort images by the position of their metadata resources. I'm * assuming that is what determines the other of the images in the WIM - * file, rather than their order in the lookup table, which may be - * random because of hashing. */ + * file, rather than their order in the lookup table, which is random + * because of hashing. */ qsort(w->image_metadata, w->current_image, sizeof(struct image_metadata), sort_image_metadata_by_position); @@ -515,26 +506,21 @@ static int begin_read(WIMStruct *w, const char *in_wim_path, int flags) &w->xml_data, &w->wim_info); if (ret != 0) { - ERROR("Missing or invalid XML data\n"); - goto done; + ERROR("Missing or invalid XML data"); + return ret; } xml_num_images = wim_info_get_num_images(w->wim_info); if (xml_num_images != w->hdr.image_count) { ERROR("In the file `%s', there are %u elements " - "in the XML data,\n", in_wim_path, - xml_num_images); - ERROR("but %u images in the WIM! There must be " - "exactly one element per image.\n", - w->hdr.image_count); - ret = WIMLIB_ERR_IMAGE_COUNT; - goto done; + "in the XML data,", in_wim_path, xml_num_images); + ERROR("but %u images in the WIM! There must be exactly one " + " element per image.", w->hdr.image_count); + return WIMLIB_ERR_IMAGE_COUNT; } - DEBUG("Done beginning read of WIM file.\n"); - ret = 0; -done: - return ret; + DEBUG("Done beginning read of WIM file `%s'.", in_wim_path); + return 0; } @@ -547,15 +533,17 @@ WIMLIBAPI int wimlib_open_wim(const char *wim_file, int flags, WIMStruct *w; int ret; - DEBUG("wim_file = `%s', flags = %d\n", wim_file, flags); + DEBUG("wim_file = `%s', flags = %#x", wim_file, flags); w = new_wim_struct(); - if (!w) + if (!w) { + ERROR("Failed to allocate memory for WIMStruct"); return WIMLIB_ERR_NOMEM; + } ret = begin_read(w, wim_file, flags); if (ret != 0) { - ERROR("Could not begin reading the WIM file `%s'\n", wim_file); - FREE(w); + ERROR("Could not begin reading the WIM file `%s'", wim_file); + wimlib_free(w); return ret; } *w_ret = w; diff --git a/src/wimlib.h b/src/wimlib.h index 4ac00328..15b2d719 100644 --- a/src/wimlib.h +++ b/src/wimlib.h @@ -357,7 +357,10 @@ enum wimlib_error_code { * marked as bootable to the one being added. Otherwise, leave the boot * index unchanged. * - * @return 0 on success; nonzero on error. + * @return 0 on success; nonzero on error. On error, changes to @a wim are + * discarded so that it appears to be in the same state as when this function + * was called. + * * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION * There is already an image named @a name in @a w. * @retval ::WIMLIB_ERR_INVALID_PARAM @@ -413,7 +416,8 @@ extern int wimlib_create_new_wim(int ctype, WIMStruct **wim_ret); * @param image * The number of the image to delete, or ::WIM_ALL_IMAGES to delete all * images. - * @return 0 on success; nonzero on error. + * @return 0 on success; nonzero on error. On error, @a wim is left in an + * indeterminate state and should be freed with wimlib_free(). * @retval ::WIMLIB_ERR_DECOMPRESSION * Could not decompress the metadata resource for @a image. * @retval ::WIMLIB_ERR_INVALID_DENTRY @@ -461,7 +465,8 @@ extern int wimlib_delete_image(WIMStruct *wim, int image); * currently marked as bootable in @a src_wim; if that is the case, then * that image is marked as bootable in the destination WIM. * - * @return 0 on success; nonzero on error. + * @return 0 on success; nonzero on error. On error, @dest_wim is left in an + * indeterminate state and should be freed with wimlib_free(). * @retval ::WIMLIB_ERR_DECOMPRESSION * Could not decompress the metadata resource for @a src_image * in @a src_wim @@ -487,8 +492,8 @@ extern int wimlib_delete_image(WIMStruct *wim, int image); * Could not read the metadata resource for @a src_image from @a src_wim. */ extern int wimlib_export_image(WIMStruct *src_wim, int src_image, - WIMStruct *dest_wim, const char *dest_name, - const char *dest_description, int flags); + WIMStruct *dest_wim, const char *dest_name, + const char *dest_description, int flags); /** * Extracts an image, or all images, from a WIM file. diff --git a/src/wimlib_internal.h b/src/wimlib_internal.h index 157a1174..c1ad1cd4 100644 --- a/src/wimlib_internal.h +++ b/src/wimlib_internal.h @@ -218,7 +218,7 @@ struct image_metadata { #endif /* A pointer to the lookup table entry for this image's metadata * resource. */ - struct lookup_table_entry *lookup_table_entry; + struct lookup_table_entry *metadata_lte; /* True if the filesystem of the image has been modified. If this is * the case, the memory for the filesystem is not freed when switching @@ -303,7 +303,7 @@ static inline struct wim_security_data *wim_security_data(WIMStruct *w) static inline struct lookup_table_entry* wim_metadata_lookup_table_entry(WIMStruct *w) { - return w->image_metadata[w->current_image - 1].lookup_table_entry; + return w->image_metadata[w->current_image - 1].metadata_lte; } /* Nonzero if a struct resource_entry indicates a compressed resource. */ @@ -317,11 +317,6 @@ static inline struct image_metadata *wim_get_current_image_metadata(WIMStruct *w return &w->image_metadata[w->current_image - 1]; } -static inline bool wim_current_image_is_modified(const WIMStruct *w) -{ - return w->image_metadata[w->current_image - 1].modified; -} - /* Prints a hash code field. */ static inline void print_hash(const u8 hash[]) { @@ -363,17 +358,15 @@ extern int extract_full_resource_to_fd(WIMStruct *w, const struct resource_entry *entry, int fd); -extern int read_metadata_resource(FILE *fp, - const struct resource_entry *metadata, - int wim_ctype, +extern int read_metadata_resource(FILE *fp, int wim_ctype, struct image_metadata *image_metadata); extern int resource_compression_type(int wim_ctype, int reshdr_flags); static inline int read_full_resource(FILE *fp, u64 resource_size, - u64 resource_original_size, - u64 resource_offset, - int resource_ctype, void *contents_ret) + u64 resource_original_size, + u64 resource_offset, + int resource_ctype, void *contents_ret) { return read_resource(fp, resource_size, resource_original_size, resource_offset, resource_ctype, diff --git a/src/write.c b/src/write.c index c46494ed..3866bed6 100644 --- a/src/write.c +++ b/src/write.c @@ -38,11 +38,11 @@ static int reopen_rw(WIMStruct *w) FILE *fp; if (fclose(w->fp) != 0) - ERROR("Failed to close the file `%s': %m\n", w->filename); + ERROR_WITH_ERRNO("Failed to close the file `%s'", w->filename); fp = fopen(w->filename, "r+b"); if (!fp) { - ERROR("Failed to open `%s' for reading and writing: " - "%m\n", w->filename); + ERROR_WITH_ERRNO("Failed to open `%s' for reading and writing", + w->filename); return WIMLIB_ERR_OPEN; } w->fp = fp; @@ -62,7 +62,7 @@ WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int flags) wimfile_name = w->filename; - DEBUG("Replacing WIM file `%s'\n", wimfile_name); + DEBUG("Replacing WIM file `%s'.", wimfile_name); if (!wimfile_name) return WIMLIB_ERR_NO_FILENAME; @@ -77,29 +77,28 @@ WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int flags) ret = wimlib_write(w, tmpfile, WIM_ALL_IMAGES, flags); if (ret != 0) { - ERROR("Failed to write the WIM file `%s'!\n", tmpfile); + ERROR("Failed to write the WIM file `%s'", tmpfile); return ret; } - DEBUG("Closing original WIM file.\n"); + DEBUG("Closing original WIM file."); /* Close the original WIM file that was opened for reading. */ if (w->fp) { if (fclose(w->fp) != 0) { - WARNING("Failed to close the file `%s'\n", - wimfile_name); + WARNING("Failed to close the file `%s'", wimfile_name); } w->fp = NULL; } - DEBUG("Renaming `%s' to `%s'\n", tmpfile, wimfile_name); + DEBUG("Renaming `%s' to `%s'", tmpfile, wimfile_name); /* Rename the new file to the old file .*/ if (rename(tmpfile, wimfile_name) != 0) { - ERROR("Failed to rename `%s' to `%s': %m\n", tmpfile, - wimfile_name); + ERROR_WITH_ERRNO("Failed to rename `%s' to `%s'", + tmpfile, wimfile_name); /* Remove temporary file. */ if (unlink(tmpfile) != 0) - ERROR("Failed to remove `%s': %m\n", tmpfile); + ERROR_WITH_ERRNO("Failed to remove `%s'", tmpfile); return WIMLIB_ERR_RENAME; } @@ -116,8 +115,8 @@ WIMLIBAPI int wimlib_overwrite_xml_and_header(WIMStruct *w, int flags) off_t xml_size; size_t bytes_written; - DEBUG("Overwriting XML and header of `%s', flags = %d\n", - w->filename, flags); + DEBUG("Overwriting XML and header of `%s', flags = %d", + w->filename, flags); if (!w->filename) return WIMLIB_ERR_NO_FILENAME; @@ -133,7 +132,7 @@ WIMLIBAPI int wimlib_overwrite_xml_and_header(WIMStruct *w, int flags) * */ if (flags & WIMLIB_WRITE_FLAG_CHECK_INTEGRITY && w->hdr.integrity.offset != 0) { - DEBUG("Reading existing integrity table.\n"); + DEBUG("Reading existing integrity table."); integrity_table = MALLOC(w->hdr.integrity.size); if (!integrity_table) return WIMLIB_ERR_NOMEM; @@ -143,14 +142,14 @@ WIMLIBAPI int wimlib_overwrite_xml_and_header(WIMStruct *w, int flags) integrity_table); if (ret != 0) goto err; - DEBUG("Done reading existing integrity table.\n"); + DEBUG("Done reading existing integrity table."); } - DEBUG("Overwriting XML data.\n"); + DEBUG("Overwriting XML data."); /* Overwrite the XML data. */ if (fseeko(fp, w->hdr.xml_res_entry.offset, SEEK_SET) != 0) { - ERROR("Failed to seek to byte %"PRIu64" for XML data: " - "%m\n", w->hdr.xml_res_entry.offset); + ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" " + "for XML data", w->hdr.xml_res_entry.offset); ret = WIMLIB_ERR_WRITE; goto err; } @@ -158,7 +157,7 @@ WIMLIBAPI int wimlib_overwrite_xml_and_header(WIMStruct *w, int flags) if (ret != 0) goto err; - DEBUG("Updating XML resource entry.\n"); + DEBUG("Updating XML resource entry."); /* Update the XML resource entry in the WIM header. */ xml_end = ftello(fp); if (xml_end == -1) { @@ -170,14 +169,15 @@ WIMLIBAPI int wimlib_overwrite_xml_and_header(WIMStruct *w, int flags) w->hdr.xml_res_entry.original_size = xml_size; if (flags & WIMLIB_WRITE_FLAG_CHECK_INTEGRITY) { - DEBUG("Writing integrity table.\n"); + DEBUG("Writing integrity table."); w->hdr.integrity.offset = xml_end; if (integrity_table) { /* The existing integrity table was saved. */ bytes_written = fwrite(integrity_table, 1, w->hdr.integrity.size, fp); if (bytes_written != w->hdr.integrity.size) { - ERROR("Failed to write integrity table: %m\n"); + ERROR_WITH_ERRNO("Failed to write integrity " + "table"); ret = WIMLIB_ERR_WRITE; goto err; } @@ -198,44 +198,43 @@ WIMLIBAPI int wimlib_overwrite_xml_and_header(WIMStruct *w, int flags) w->hdr.integrity.flags = 0; } } else { - DEBUG("Truncating file to end of XML data.\n"); + DEBUG("Truncating file to end of XML data."); /* No integrity table to write. The file should be truncated * because it's possible that the old file was longer (due to it * including an integrity table, or due to its XML data being * longer) */ if (fflush(fp) != 0) { - ERROR("Failed to flush stream for file `%s': %m\n", - w->filename); + ERROR_WITH_ERRNO("Failed to flush stream for file `%s'", + w->filename); return WIMLIB_ERR_WRITE; } if (ftruncate(fileno(fp), xml_end) != 0) { - ERROR("Failed to truncate `%s' to %"PRIu64" " - "bytes: %m\n", - w->filename, xml_end); + ERROR_WITH_ERRNO("Failed to truncate `%s' to %"PRIu64" " + "bytes", w->filename, xml_end); return WIMLIB_ERR_WRITE; } memset(&w->hdr.integrity, 0, sizeof(struct resource_entry)); } - DEBUG("Overwriting header.\n"); + DEBUG("Overwriting header."); /* Overwrite the header. */ if (fseeko(fp, 0, SEEK_SET) != 0) { - ERROR("Failed to seek to beginning of `%s': %m\n", - w->filename); + ERROR_WITH_ERRNO("Failed to seek to beginning of `%s'", + w->filename); return WIMLIB_ERR_WRITE; } ret = write_header(&w->hdr, fp); if (ret != 0) - return ret;; + return ret; - DEBUG("Closing file.\n"); + DEBUG("Closing `%s'.", w->filename); if (fclose(fp) != 0) { - ERROR("Failed to close `%s': %m\n", w->filename); + ERROR_WITH_ERRNO("Failed to close `%s'", w->filename); return WIMLIB_ERR_WRITE; } w->fp = NULL; - DEBUG("Done.\n"); + DEBUG("Done."); return 0; err: FREE(integrity_table); @@ -247,11 +246,12 @@ err: static int write_file_resources(WIMStruct *w) { - DEBUG("Writing file resources for image %u\n", w->current_image); + DEBUG("Writing file resources for image %u.", w->current_image); return for_dentry_in_tree(wim_root_dentry(w), write_file_resource, w); } -/* Write lookup table, xml data, lookup table, and rewrite header +/* Write the lookup table, xml data, and integrity table, then overwrite the WIM + * header. * * write_lt is zero iff the lookup table is not to be written; i.e. it is * handled elsewhere. */ @@ -273,7 +273,7 @@ int finish_write(WIMStruct *w, int image, int flags, int write_lt) if (lookup_table_offset == -1) return WIMLIB_ERR_WRITE; - DEBUG("Writing lookup table (offset %"PRIu64")\n", lookup_table_offset); + DEBUG("Writing lookup table (offset %"PRIu64")", lookup_table_offset); /* Write the lookup table. */ ret = write_lookup_table(w->lookup_table, out); if (ret != 0) @@ -284,7 +284,7 @@ int finish_write(WIMStruct *w, int image, int flags, int write_lt) xml_data_offset = ftello(out); if (xml_data_offset == -1) return WIMLIB_ERR_WRITE; - DEBUG("Writing XML data (offset %"PRIu64")\n", xml_data_offset); + DEBUG("Writing XML data (offset %"PRIu64")", xml_data_offset); /* @hdr will be the header for the new WIM. First copy all the data * from the header in the WIMStruct; then set all the fields that may @@ -334,7 +334,7 @@ int finish_write(WIMStruct *w, int image, int flags, int write_lt) } hdr.integrity.flags = 0; - DEBUG("Updating WIM header.\n"); + DEBUG("Updating WIM header."); /* * In the WIM header, there is room for the resource entry for a @@ -349,9 +349,9 @@ int finish_write(WIMStruct *w, int image, int flags, int write_lt) sizeof(struct resource_entry)); } else { memcpy(&hdr.boot_metadata_res_entry, - &w->image_metadata[hdr.boot_idx - 1].lookup_table_entry-> - output_resource_entry, - sizeof(struct resource_entry)); + &w->image_metadata[ + hdr.boot_idx - 1].metadata_lte->output_resource_entry, + sizeof(struct resource_entry)); } /* Set image count and boot index correctly for single image writes */ @@ -374,7 +374,7 @@ int finish_write(WIMStruct *w, int image, int flags, int write_lt) int begin_write(WIMStruct *w, const char *path, int flags) { const char *mode; - DEBUG("Opening `%s' for new WIM\n", path); + DEBUG("Opening `%s' for new WIM", path); /* checking the integrity requires going back over the file to read it. * XXX @@ -387,7 +387,8 @@ int begin_write(WIMStruct *w, const char *path, int flags) w->out_fp = fopen(path, mode); if (!w->out_fp) { - ERROR("Failed to open the file `%s' for writing!\n", path); + ERROR_WITH_ERRNO("Failed to open the file `%s' for writing", + path); return WIMLIB_ERR_OPEN; } @@ -401,13 +402,13 @@ WIMLIBAPI int wimlib_write(WIMStruct *w, const char *path, int image, int flags) int ret; if (image != WIM_ALL_IMAGES && - (image < 1 || image > w->hdr.image_count)) + (image < 1 || image > w->hdr.image_count)) return WIMLIB_ERR_INVALID_IMAGE; if (image == WIM_ALL_IMAGES) - DEBUG("Writing all images to `%s'\n", path); + DEBUG("Writing all images to `%s'.", path); else - DEBUG("Writing image %d to `%s'\n", image, path); + DEBUG("Writing image %d to `%s'.", image, path); ret = begin_write(w, path, flags); if (ret != 0) @@ -417,24 +418,24 @@ WIMLIBAPI int wimlib_write(WIMStruct *w, const char *path, int image, int flags) ret = for_image(w, image, write_file_resources); if (ret != 0) { - ERROR("Failed to write file resources!\n"); + ERROR("Failed to write WIM file resources to `%s'", path); goto done; } ret = for_image(w, image, write_metadata_resource); if (ret != 0) { - ERROR("Failed to write image metadata!\n"); + ERROR("Failed to write WIM image metadata to `%s'", path); goto done; } ret = finish_write(w, image, flags, 1); done: - DEBUG("Closing output file.\n"); + DEBUG("Closing output file."); if (w->out_fp != NULL) { if (fclose(w->out_fp) != 0) { - ERROR("Failed to close the file `%s': %m\n", path); + ERROR_WITH_ERRNO("Failed to close the file `%s'", path); ret = WIMLIB_ERR_WRITE; } w->out_fp = NULL; diff --git a/src/xml.c b/src/xml.c index 39692029..77e58757 100644 --- a/src/xml.c +++ b/src/xml.c @@ -33,8 +33,8 @@ #include #include -/* The following 4 structures are used to form an in-memory representation of - * the XML data (other than the raw parse tree from libxml). */ +/* Structures used to form an in-memory representation of the XML data (other + * than the raw parse tree from libxml). */ struct windows_version { u64 major; @@ -99,8 +99,8 @@ static const char *get_arch(int arch) /* Iterate through the children of an xmlNode. */ -#define for_node_child(parent, child) for (child = parent->children; \ - child != NULL; child = child->next) +#define for_node_child(parent, child) \ + for (child = parent->children; child != NULL; child = child->next) /* Utility functions for xmlNodes */ static inline bool node_is_element(xmlNode *node) @@ -154,8 +154,10 @@ static int node_get_string(const xmlNode *string_node, char **str) for_node_child(string_node, child) { if (node_is_text(child) && child->content) { p = STRDUP(child->content); - if (!p) + if (!p) { + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; + } break; } } @@ -276,8 +278,10 @@ static int xml_read_languages(const xmlNode *languages_node, num_languages++; languages = CALLOC(num_languages, sizeof(char*)); - if (!languages) + if (!languages) { + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; + } *languages_ret = languages; *num_languages_ret = num_languages; @@ -294,7 +298,7 @@ static int xml_read_languages(const xmlNode *languages_node, if (ret != 0) return ret; } - return 0; + return ret; } /* Reads the information from a element inside an element. */ @@ -342,7 +346,7 @@ static int xml_read_windows_info(const xmlNode *windows_node, if (ret != 0) return ret; } - return 0; + return ret; } /* Reads the information from an element. */ @@ -355,7 +359,8 @@ static int xml_read_image_info(xmlNode *image_node, index_prop = xmlGetProp(image_node, "INDEX"); if (index_prop) { - image_info->index = strtoul(index_prop, NULL, 10); + char *tmp; + image_info->index = strtoul(index_prop, &tmp, 10); FREE(index_prop); } else { image_info->index = 0; @@ -378,9 +383,9 @@ static int xml_read_image_info(xmlNode *image_node, else if (node_name_is(child, "LASTMODIFICATIONTIME")) image_info->last_modification_time = node_get_timestamp(child); else if (node_name_is(child, "WINDOWS")) { - DEBUG("Found tag\n"); - ret = xml_read_windows_info(child, - &image_info->windows_info); + DEBUG("Found tag"); + ret = xml_read_windows_info(child, + &image_info->windows_info); image_info->windows_info_exists = true; } else if (node_name_is(child, "NAME")) { ret = node_get_string(child, &image_info->name); @@ -397,23 +402,22 @@ static int xml_read_image_info(xmlNode *image_node, return ret; } if (!image_info->name) { - WARNING("Image with index %"PRIu64" has no name\n", - image_info->index); + WARNING("Image with index %"PRIu64" has no name", + image_info->index); image_info->name = MALLOC(1); if (!image_info->name) { - ERROR("Out of memory!\n"); + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; } image_info->name[0] = '\0'; - return 0; } - - return 0; + return ret; } /* Reads the information from a element, which should be the root element * of the XML tree. */ -static int xml_read_wim_info(const xmlNode *wim_node, struct wim_info **wim_info_ret) +static int xml_read_wim_info(const xmlNode *wim_node, + struct wim_info **wim_info_ret) { struct wim_info *wim_info; xmlNode *child; @@ -423,7 +427,7 @@ static int xml_read_wim_info(const xmlNode *wim_node, struct wim_info **wim_info wim_info = CALLOC(1, sizeof(struct wim_info)); if (!wim_info) { - ERROR("Out of memory!\n"); + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; } @@ -440,7 +444,7 @@ static int xml_read_wim_info(const xmlNode *wim_node, struct wim_info **wim_info wim_info->images = CALLOC(num_images, sizeof(wim_info->images[0])); if (!wim_info->images) { ret = WIMLIB_ERR_NOMEM; - ERROR("Out of memory!\n"); + ERROR("Out of memory!"); goto err; } wim_info->num_images = num_images; @@ -449,7 +453,7 @@ static int xml_read_wim_info(const xmlNode *wim_node, struct wim_info **wim_info if (!node_is_element(child)) continue; if (node_name_is(child, "IMAGE")) { - DEBUG("Found tag\n"); + DEBUG("Found tag"); ret = xml_read_image_info(child, cur_image_info++); if (ret != 0) goto err; @@ -717,7 +721,7 @@ static int xml_write_image_info(xmlTextWriter *writer, if (rc < 0) return rc; } else { - DEBUG(" tag does not exist.\n"); + DEBUG(" tag does not exist."); } if (image_info->name) { @@ -765,8 +769,8 @@ static struct image_info *add_image_info_struct(struct wim_info *wim_info) images = CALLOC(wim_info->num_images + 1, sizeof(struct image_info)); if (!images) return NULL; - memcpy(images, wim_info->images, - wim_info->num_images * sizeof(struct image_info)); + memcpy(images, wim_info->images, + wim_info->num_images * sizeof(struct image_info)); FREE(wim_info->images); wim_info->images = images; wim_info->num_images++; @@ -868,8 +872,7 @@ int xml_export_image(const struct wim_info *old_wim_info, char *name; char *desc; - DEBUG("Copying XML data between WIM files for source image %d\n", - image); + DEBUG("Copying XML data between WIM files for source image %d.", image); wimlib_assert(image >= 1 && image <= old_wim_info->num_images); @@ -907,7 +910,7 @@ int xml_export_image(const struct wim_info *old_wim_info, *new_wim_info_p = new_wim_info; return 0; err: - ERROR("Out of memory!\n"); + ERROR("Out of memory"); free_wim_info(new_wim_info); return WIMLIB_ERR_NOMEM; } @@ -918,7 +921,7 @@ void xml_delete_image(struct wim_info **wim_info_p, int image) struct wim_info *wim_info; int i; - DEBUG("Deleting image %d from the XML data\n", image); + DEBUG("Deleting image %d from the XML data.", image); wim_info = *wim_info_p; @@ -963,7 +966,7 @@ void xml_update_image_info(WIMStruct *w, int image) struct image_info *image_info; struct dentry *root; - DEBUG("Updating the image info for image %d\n", image); + DEBUG("Updating the image info for image %d", image); image_info = &w->wim_info->images[image - 1]; root = w->image_metadata[image - 1].root_dentry; @@ -986,34 +989,34 @@ int xml_add_image(WIMStruct *w, struct dentry *root_dentry, const char *name, wimlib_assert(name); - DEBUG("Adding image: name = %s, description = %s, flags_element = %s\n", - name, description, flags_element); + DEBUG("Adding image: name = %s, description = %s, flags_element = %s", + name, description, flags_element); /* If this is the first image, allocate the struct wim_info. Otherwise * use the existing struct wim_info. */ if (w->wim_info) { wim_info = w->wim_info; } else { - DEBUG("Allocing struct wim_info with 1 image\n"); + DEBUG("Allocing struct wim_info with 1 image"); wim_info = CALLOC(1, sizeof(struct wim_info)); if (!wim_info) { ERROR("Could not allocate WIM information struct--- " - "out of memory!\n"); + "out of memory"); return WIMLIB_ERR_NOMEM; } } image_info = add_image_info_struct(wim_info); if (!image_info) - goto err_nomem1; + goto out_free_wim_info; if (!(image_info->name = STRDUP(name))) - goto err_nomem2; + goto out_destroy_image_info; if (description && !(image_info->description = STRDUP(description))) - goto err_nomem2; + goto out_destroy_image_info; if (flags_element && !(image_info->flags = STRDUP(flags_element))) - goto err_nomem2; + goto out_destroy_image_info; w->wim_info = wim_info; image_info->index = wim_info->num_images; @@ -1021,14 +1024,14 @@ int xml_add_image(WIMStruct *w, struct dentry *root_dentry, const char *name, xml_update_image_info(w, image_info->index); return 0; -err_nomem2: +out_destroy_image_info: destroy_image_info(image_info); -err_nomem1: +out_free_wim_info: if (w->wim_info) wim_info->num_images--; else FREE(wim_info); - ERROR("Out of memory!\n"); + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; } @@ -1103,16 +1106,16 @@ int read_xml_data(FILE *fp, const struct resource_entry *res, u8 **xml_data_ret, xmlNode *root; int ret; - DEBUG("XML data is %"PRIu64" bytes at offset %"PRIu64"\n", - (u64)res->size, res->offset); + DEBUG("XML data is %"PRIu64" bytes at offset %"PRIu64"", + (u64)res->size, res->offset); if (resource_is_compressed(res)) { - ERROR("XML data is supposed to be uncompressed!\n"); + ERROR("XML data is supposed to be uncompressed"); ret = WIMLIB_ERR_XML; goto err0; } if (res->size < 2) { - ERROR("XML data must be at least 2 bytes!\n"); + ERROR("XML data must be at least 2 bytes"); ret = WIMLIB_ERR_XML; goto err0; } @@ -1130,29 +1133,29 @@ int read_xml_data(FILE *fp, const struct resource_entry *res, u8 **xml_data_ret, xml_data[res->size] = 0; xml_data[res->size + 1] = 0; - DEBUG("Parsing XML using libxml2 to create XML tree.\n"); + DEBUG("Parsing XML using libxml2 to create XML tree."); doc = xmlReadMemory(xml_data, res->size, "noname.xml", "UTF-16", 0); if (!doc) { - ERROR("Failed to parse XML data!\n"); + ERROR("Failed to parse XML data"); ret = WIMLIB_ERR_XML; goto err1; } - DEBUG("Constructing WIM information structure from XML tree.\n"); + DEBUG("Constructing WIM information structure from XML tree."); root = xmlDocGetRootElement(doc); if (!root) { - ERROR("Empty XML document!\n"); + ERROR("Empty XML document"); ret = WIMLIB_ERR_XML; goto err2; } if (!node_is_element(root) || !node_name_is(root, "WIM")) { - ERROR("Expected for the root XML element! " - "(found <%s>)\n", root->name); + ERROR("Expected for the root XML element (found <%s>)", + root->name); ret = WIMLIB_ERR_XML; goto err2; } @@ -1161,7 +1164,7 @@ int read_xml_data(FILE *fp, const struct resource_entry *res, u8 **xml_data_ret, if (ret != 0) goto err2; - DEBUG("Freeing XML tree.\n"); + DEBUG("Freeing XML tree."); xmlFreeDoc(doc); xmlCleanupParser(); @@ -1177,7 +1180,7 @@ err0: } #define CHECK_RET ({ if (ret < 0) { \ - ERROR("Error writing XML data!\n"); \ + ERROR("Error writing XML data"); \ ret = WIMLIB_ERR_WRITE; \ goto err2; \ } }) @@ -1218,16 +1221,16 @@ int write_xml_data(const struct wim_info *wim_info, int image, FILE *out, return WIMLIB_ERR_WRITE; } - DEBUG("Creating XML buffer and text writer\n"); + DEBUG("Creating XML buffer and text writer."); buf = xmlBufferCreate(); if (!buf) { - ERROR("Failed to allocate XML buffer!\n"); + ERROR("Failed to allocate XML buffer"); ret = WIMLIB_ERR_NOMEM; goto err0; } writer = xmlNewTextWriterMemory(buf, 0); if (!writer) { - ERROR("Failed to allocate XML writer!\n"); + ERROR("Failed to allocate XML writer"); ret = WIMLIB_ERR_NOMEM; goto err1; } @@ -1242,7 +1245,7 @@ int write_xml_data(const struct wim_info *wim_info, int image, FILE *out, CHECK_RET; #endif - DEBUG("Writing element\n"); + DEBUG("Writing element"); ret = xmlTextWriterStartElement(writer, "WIM"); CHECK_RET; @@ -1254,12 +1257,12 @@ int write_xml_data(const struct wim_info *wim_info, int image, FILE *out, num_images = wim_info->num_images; else num_images = 0; - DEBUG("Writing %u elements\n", num_images); + DEBUG("Writing %u elements", num_images); for (i = 1; i <= num_images; i++) { if (image != WIM_ALL_IMAGES && i != image) continue; - DEBUG("Writing element for image %d\n", i); + DEBUG("Writing element for image %d", i); ret = xml_write_image_info(writer, &wim_info->images[i - 1]); CHECK_RET; } @@ -1271,7 +1274,7 @@ int write_xml_data(const struct wim_info *wim_info, int image, FILE *out, CHECK_RET; DEBUG("Done composing XML document. Now converting to UTF-16 and " - "writing it to the output file.\n"); + "writing it to the output file."); content = xmlBufferContent(buf); len = xmlBufferLength(buf); @@ -1285,12 +1288,12 @@ int write_xml_data(const struct wim_info *wim_info, int image, FILE *out, if ((putc(0xff, out)) == EOF || (putc(0xfe, out) == EOF) || ((bytes_written = fwrite(utf16_str, 1, utf16_len, out)) != utf16_len)) { - ERROR("Error writing XML data: %m\n"); + ERROR_WITH_ERRNO("Error writing XML data"); ret = WIMLIB_ERR_WRITE; goto err3; } - DEBUG("Cleaning up.\n"); + DEBUG("Cleaning up."); ret = 0; err3: @@ -1306,7 +1309,7 @@ err0: /* Returns the name of the specified image. */ WIMLIBAPI const char *wimlib_get_image_name(const WIMStruct *w, int image) { - DEBUG("Getting the name of image %d\n", image); + DEBUG("Getting the name of image %d", image); if (image < 1 || image > w->hdr.image_count) return NULL; @@ -1317,7 +1320,7 @@ WIMLIBAPI const char *wimlib_get_image_name(const WIMStruct *w, int image) WIMLIBAPI const char *wimlib_get_image_description(const WIMStruct *w, int image) { - DEBUG("Getting the description of image %d\n", image); + DEBUG("Getting the description of image %d", image); if (image < 1 || image > w->hdr.image_count) return NULL; @@ -1329,8 +1332,7 @@ WIMLIBAPI bool wimlib_image_name_in_use(const WIMStruct *w, const char *name) { int i; - DEBUG("Checking to see if the image name `%s' is already " - "in use\n", name); + DEBUG("Checking to see if the image name `%s' is already in use", name); if (!name || !w->wim_info) return false; for (i = 1; i <= w->wim_info->num_images; i++) @@ -1342,10 +1344,10 @@ WIMLIBAPI bool wimlib_image_name_in_use(const WIMStruct *w, const char *name) WIMLIBAPI int wimlib_extract_xml_data(WIMStruct *w, FILE *fp) { - DEBUG("Extracting the XML data.\n"); + DEBUG("Extracting the XML data."); if (fwrite(w->xml_data, 1, w->hdr.xml_res_entry.size, fp) != w->hdr.xml_res_entry.size) { - ERROR("Failed to extract XML data!\n"); + ERROR_WITH_ERRNO("Failed to extract XML data"); return WIMLIB_ERR_WRITE; } return 0; @@ -1357,15 +1359,14 @@ WIMLIBAPI int wimlib_set_image_name(WIMStruct *w, int image, const char *name) char *p; int i; - DEBUG("Setting the name of image %d to %s\n", image, name); + DEBUG("Setting the name of image %d to %s", image, name); if (!name || !*name) { - ERROR("Must specify a non-empty string for the image " - "name!\n"); + ERROR("Must specify a non-empty string for the image name"); return WIMLIB_ERR_INVALID_PARAM; } if (image < 1 || image > w->hdr.image_count) { - ERROR("%d is not a valid image!\n", image); + ERROR("%d is not a valid image", image); return WIMLIB_ERR_INVALID_IMAGE; } @@ -1373,15 +1374,15 @@ WIMLIBAPI int wimlib_set_image_name(WIMStruct *w, int image, const char *name) if (i == image) continue; if (strcmp(w->wim_info->images[i - 1].name, name) == 0) { - ERROR("The name `%s' is already used for image %d!\n", - name, i); + ERROR("The name `%s' is already used for image %d", + name, i); return WIMLIB_ERR_IMAGE_NAME_COLLISION; } } p = STRDUP(name); if (!p) { - ERROR("Out of memory!\n"); + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; } FREE(w->wim_info->images[image - 1].name); @@ -1395,17 +1396,16 @@ WIMLIBAPI int wimlib_set_image_descripton(WIMStruct *w, int image, { char *p; - DEBUG("Setting the description of image %d to %s\n", image, - description); + DEBUG("Setting the description of image %d to %s", image, description); if (image < 1 || image > w->hdr.image_count) { - ERROR("%d is not a valid image!\n", image); + ERROR("%d is not a valid image", image); return WIMLIB_ERR_INVALID_IMAGE; } if (description) { p = STRDUP(description); if (!p) { - ERROR("Out of memory!\n"); + ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; } } else { diff --git a/src/xpress-comp.c b/src/xpress-comp.c index b5cf85ea..646dc67f 100644 --- a/src/xpress-comp.c +++ b/src/xpress-comp.c @@ -190,7 +190,7 @@ int xpress_compress(const void *__uncompressed_data, uint uncompressed_len, uint i; int ret; - XPRESS_DEBUG("uncompressed_len = %u\n", uncompressed_len); + XPRESS_DEBUG("uncompressed_len = %u", uncompressed_len); if (uncompressed_len < 300) return 1; @@ -203,7 +203,7 @@ int xpress_compress(const void *__uncompressed_data, uint uncompressed_len, NULL, freq_tab, &xpress_lz_params); - XPRESS_DEBUG("using %u matches\n", num_matches); + XPRESS_DEBUG("using %u matches", num_matches); freq_tab[256]++; @@ -240,32 +240,31 @@ int xpress_compress(const void *__uncompressed_data, uint uncompressed_len, compressed_len = ostream.output - (u8*)__compressed_data; - XPRESS_DEBUG("Compressed %u => %u bytes\n", - uncompressed_len, compressed_len); + XPRESS_DEBUG("Compressed %u => %u bytes", + uncompressed_len, compressed_len); *compressed_len_ret = compressed_len; #ifdef ENABLE_VERIFY_COMPRESSION /* Verify that we really get the same thing back when decompressing. */ - XPRESS_DEBUG("Verifying the compressed data.\n"); + XPRESS_DEBUG("Verifying the compressed data."); u8 buf[uncompressed_len]; ret = xpress_decompress(__compressed_data, compressed_len, buf, uncompressed_len); if (ret != 0) { - fprintf(stderr, "xpress_compress(): Failed to decompress data " - "we compressed!\n"); + ERROR("xpress_compress(): Failed to decompress data we " + "compressed"); abort(); } for (i = 0; i < uncompressed_len; i++) { if (buf[i] != uncompressed_data[i]) { - fprintf(stderr, "xpress_compress(): Data we compressed " - "didn't decompress to the original data " - "(difference at byte %u of %u)\n", - i + 1, uncompressed_len); + ERROR("xpress_compress(): Data we compressed didn't " + "decompress to the original data (difference at " + "byte %u of %u)", i + 1, uncompressed_len); abort(); } } - XPRESS_DEBUG("Compression verified to be correct.\n"); + XPRESS_DEBUG("Compression verified to be correct."); #endif return 0; diff --git a/src/xpress-decomp.c b/src/xpress-decomp.c index f885c1d3..0d1f68c5 100644 --- a/src/xpress-decomp.c +++ b/src/xpress-decomp.c @@ -69,7 +69,7 @@ * the end. Otherwise Microsoft's software will fail to decompress the * XPRESS-compressed data. * - * Howeve, WIMLIB's decompressor in xpress-decomp.c currently does not care if + * Howeve, wimlib's decompressor in xpress-decomp.c currently does not care if * this extra symbol is there or not. */ @@ -81,8 +81,6 @@ #include "decomp.h" - - /* Decodes @huffsym, a value >= XPRESS_NUM_CHARS, that is the header of a match. * */ static int xpress_decode_match(int huffsym, uint window_pos, uint window_len, @@ -140,15 +138,14 @@ static int xpress_decode_match(int huffsym, uint window_pos, uint window_len, if (window_pos + match_len > window_len) { ERROR("XPRESS dedecompression error: match of length %d " - "bytes overflows window\n", match_len); + "bytes overflows window", match_len); return -1; } if (match_src < window) { ERROR("XPRESS decompression error: match of length %d bytes " - "references data before window (match_offset = " - "%d, window_pos = %d)\n", match_len, - match_offset, window_pos); + "references data before window (match_offset = %d, " + "window_pos = %d)", match_len, match_offset, window_pos); return -1; } @@ -207,8 +204,8 @@ int xpress_decompress(const void *__compressed_data, uint compressed_len, compressed_data = __compressed_data; lens_p = lens; - DEBUG2("compressed_len = %d, uncompressed_len = %d\n", - compressed_len, uncompressed_len); + DEBUG2("compressed_len = %d, uncompressed_len = %d", + compressed_len, uncompressed_len); /* XPRESS uses only one Huffman tree. It contains 512 symbols, and the * code lengths of these symbols are given literally as 4-bit integers @@ -229,7 +226,7 @@ int xpress_decompress(const void *__compressed_data, uint compressed_len, return ret; init_input_bitstream(&istream, compressed_data + XPRESS_NUM_SYMBOLS / 2, - compressed_len - XPRESS_NUM_SYMBOLS / 2); + compressed_len - XPRESS_NUM_SYMBOLS / 2); return xpress_decompress_literals(&istream, uncompressed_data, uncompressed_len, lens, decode_table); -- 2.43.0