Various minor changes and fixes.
authorEric Biggers <ebiggers3@gmail.com>
Mon, 13 Aug 2012 20:54:21 +0000 (15:54 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 13 Aug 2012 20:54:21 +0000 (15:54 -0500)
- 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.

30 files changed:
programs/imagex.c
src/decomp.c
src/decomp.h
src/dentry.c
src/dentry.h
src/endianness.h
src/extract.c
src/header.c
src/integrity.c
src/join.c
src/lookup_table.c
src/lookup_table.h
src/lz.c
src/lzx-comp.c
src/lzx-decomp.c
src/modify.c
src/mount.c
src/resource.c
src/security.c
src/sha1.c
src/split.c
src/util.c
src/util.h
src/wim.c
src/wimlib.h
src/wimlib_internal.h
src/write.c
src/xml.c
src/xpress-comp.c
src/xpress-decomp.c

index 2d66408..a1b9cea 100644 (file)
@@ -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;
 }
index 998ffd5..c9e0398 100644 (file)
@@ -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);
index 7351e25..c039582 100644 (file)
@@ -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--;
index 4dd26ee..5cdc002 100644 (file)
@@ -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;
                }
index dc80a14..cf36e22 100644 (file)
@@ -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, 
index 55a832d..ba66b27 100644 (file)
@@ -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)
 {
index 8873683..bd3ef92 100644 (file)
@@ -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);
index 6d00ccb..7cd25b1 100644 (file)
@@ -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;
index ade79f4..49fe514 100644 (file)
@@ -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;
        }
index 3b96695..c6fbc82 100644 (file)
@@ -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;
                }
index 1f6384c..a24b02e 100644 (file)
@@ -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, &lte->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;
 }
index 91684c4..6deb86f 100644 (file)
@@ -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
index 94cfc69..f079fc8 100644 (file)
--- 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;
index 0f12079..601513d 100644 (file)
@@ -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;
index 267320a..9b5ea98 100644 (file)
@@ -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;
 }
index ce362d6..4a28e0a 100644 (file)
 #include <string.h>
 #include <errno.h>
 
+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;
 }
index 3cb61ee..53a7f36 100644 (file)
@@ -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;
 }
 
index a5f0e4d..9349c3b 100644 (file)
@@ -31,6 +31,7 @@
 #include "xpress.h"
 #include "sha1.h"
 #include "dentry.h"
+#include "config.h"
 #include <unistd.h>
 #include <errno.h>
 
@@ -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;
 }
index 65d8555..9707bd3 100644 (file)
  *
  * @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++);
index b65d25d..7fd67bc 100644 (file)
@@ -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;
 }
index 25cca9f..0c41e1f 100644 (file)
@@ -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;
 }
index bdd0a29..474c6f1 100644 (file)
@@ -35,8 +35,8 @@
 #include <unistd.h>
 #include <errno.h>
 
-/* 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 <stdarg.h>
 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++;
        }
 }
-
index 3d917bf..a3984bb 100644 (file)
@@ -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 <errno.h>
-#      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
index 99a8c70..268b381 100644 (file)
--- 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 <IMAGE> elements "
-                               "in the XML data,\n", in_wim_path, 
-                                                       xml_num_images);
-               ERROR("but %u images in the WIM!  There must be "
-                               "exactly one <IMAGE> 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 "
+                     "<IMAGE> 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;
index 4ac0032..15b2d71 100644 (file)
@@ -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.
index 157a117..c1ad1cd 100644 (file)
@@ -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,
index c46494e..3866bed 100644 (file)
@@ -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;
index 3969202..77e5875 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -33,8 +33,8 @@
 #include <libxml/tree.h>
 #include <libxml/xmlwriter.h>
 
-/* 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 <WINDOWS> element inside an <IMAGE> 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 <IMAGE> 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 <WINDOWS> tag\n");
-                       ret = xml_read_windows_info(child, 
-                                               &image_info->windows_info);
+                       DEBUG("Found <WINDOWS> 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 <WIM> 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 <IMAGE> tag\n");
+                       DEBUG("Found <IMAGE> 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("<WINDOWS> tag does not exist.\n");
+               DEBUG("<WINDOWS> 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 <WIM> for the root XML element! "
-                               "(found <%s>)\n", root->name);
+               ERROR("Expected <WIM> 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 <WIM> element\n");
+       DEBUG("Writing <WIM> 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 <IMAGE> elements\n", num_images);
+       DEBUG("Writing %u <IMAGE> elements", num_images);
 
        for (i = 1; i <= num_images; i++) {
                if (image != WIM_ALL_IMAGES && i != image)
                        continue;
-               DEBUG("Writing <IMAGE> element for image %d\n", i);
+               DEBUG("Writing <IMAGE> 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 {
index b5cf85e..646dc67 100644 (file)
@@ -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();