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);
}
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;
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;
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;
}
}
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;
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;
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;
}
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);
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;
}
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;
}
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;
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;
}
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);
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;
}
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;
}
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;
}
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;
}
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);
}
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;
}
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);
}
} 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)
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);
}
}
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;
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)
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];
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;
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:
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;
}
int ret;
if (argc < 2) {
- imagex_error("No command specified!\n");
+ imagex_error("No command specified");
usage_all();
return 1;
}
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;
}
/* 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);
ret = bitstream_ensure_bits(stream, 16);
if (ret != 0) {
ERROR("Unexpected end of input when "
- "aligning bitstream!\n");
+ "aligning bitstream");
return ret;
}
}
* 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;
}
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;
}
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;
}
}
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);
/* 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. */
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);
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--;
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;
}
/*
*/
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;
}
/*
{
memset(dentry, 0, sizeof(struct dentry));
dentry->refcnt = 1;
-#ifdef ENABLE_SECURITY_DATA
- dentry->security_id = -1;
-#endif
}
/*
/* Arguments for do_free_dentry(). */
struct free_dentry_args {
struct lookup_table *lookup_table;
- bool decrement_refcnt;
+ bool lt_decrement_refcnt;
};
/*
{
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);
}
* 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);
}
* 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;
/*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;
}
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;
}
* 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;
}
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);
&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);
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;
}
* 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)
* 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;
}
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,
#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)
{
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 {
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;
}
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;
}
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;
}
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;
}
}
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);
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);
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) {
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);
u32 wim_version;
u32 chunk_size;
- DEBUG("Reading WIM header.\n");
+ DEBUG("Reading WIM header.");
bytes_read = fread(buf, 1, WIM_MAGIC_LEN, fp);
/* 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;
}
/* 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;
}
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;
}
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 */
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;
}
* @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);
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;
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;
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;
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;
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);
/* 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 +
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;
}
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;
}
(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;
}
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) {
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;
" ");
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;
}
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;
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;
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;
} 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;
}
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]));
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;
}
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;
* 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;
* 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;
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;
}
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;
}
return 0;
if (lte->output_resource_entry.flags & WIM_RESHDR_FLAG_METADATA)
- DEBUG("Writing metadata entry at %lu\n", ftello(out));
+ DEBUG("Writing metadata entry at %lu", ftello(out));
p = put_resource_entry(buf, <e->output_resource_entry);
p = put_u16(p, lte->part_number);
p = put_u32(p, lte->out_refcnt);
p = put_bytes(p, WIM_HASH_SIZE, lte->hash);
if (fwrite(buf, 1, sizeof(buf), out) != sizeof(buf)) {
- ERROR("Failed to write lookup table entry: %m\n");
+ ERROR_WITH_ERRNO("Failed to write lookup table entry");
return WIMLIB_ERR_WRITE;
}
return 0;
}
-static int do_free_lookup_table_entry(struct lookup_table_entry *entry, void *ignore)
+static int do_free_lookup_table_entry(struct lookup_table_entry *entry,
+ void *ignore)
{
free_lookup_table_entry(entry);
return 0;
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)
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 = ");
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;
}
*
* 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;
};
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
* 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];
* 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;
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;
&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);
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;
ret = bitstream_ensure_bits(istream, 4);
if (ret != 0) {
- ERROR("Input stream overrun!\n");
+ ERROR("LZX input stream overrun");
return ret;
}
switch (block_type) {
case LZX_BLOCKTYPE_ALIGNED:
-
/* Read the path lengths for the elements of the aligned tree,
* then build it. */
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;
}
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,
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;
queue->R2 = R[2];
break;
default:
- LZX_DEBUG("Found invalid block\n");
+ LZX_DEBUG("Found invalid block.");
return 1;
}
*block_type_ret = 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;
}
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);
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 -
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;
}
#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
* 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;
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;
}
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 {
* 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) {
} 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;
}
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);
*/
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;
+
}
/*
/* 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
* */
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++) {
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;
}
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);
}
/*
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
/* 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;
}
{
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;
}
staging_dir_name = MALLOC(staging_dir_name_len + 1);
if (!staging_dir_name) {
- ERROR("Out of memory!\n");
+ ERROR("Out of memory");
return;
}
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;
}
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;
}
0700, NULL);
if (unmount_to_daemon_mq == -1) {
- ERROR("mq_open(): %m\n");
+ ERROR_WITH_ERRNO("mq_open()");
ret = WIMLIB_ERR_MQUEUE;
goto err2;
}
0700, NULL);
if (daemon_to_unmount_mq == -1) {
- ERROR("mq_open(): %m\n");
+ ERROR_WITH_ERRNO("mq_open()");
ret = WIMLIB_ERR_MQUEUE;
goto err3;
}
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;
}
}
{
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;
}
}
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;
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 {
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;
}
ret = wimlib_overwrite(w, check_integrity);
if (ret != 0) {
- ERROR("Failed to commit changes\n");
+ ERROR("Failed to commit changes");
return ret;
}
return ret;
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);
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;
if (commit) {
status = chdir(working_directory);
if (status != 0) {
- ERROR("chdir(): %m\n");
+ ERROR_WITH_ERRNO("chdir()");
status = WIMLIB_ERR_NOTDIR;
goto done;
}
}
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;
}
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();
}
/* doesn't exist--- ok */
}
- DEBUG("Creating staging file '%s'\n", name);
+ DEBUG("Creating staging file '%s'", name);
fd = creat(name, 0600);
if (fd == -1) {
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;
}
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;
}
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;
}
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];
}
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;
}
#include "xpress.h"
#include "sha1.h"
#include "dentry.h"
+#include "config.h"
#include <unistd.h>
#include <errno.h>
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;
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;
}
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;
}
/* 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. */
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 */
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
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;
}
}
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,
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;
}
{
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;
}
{
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,
* 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;
- }
}
/*
* 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;
/*
* 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];
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;
}
}
* 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
* 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 *);
/* 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;
}
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;
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;
/* 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;
}
}
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);
}
}
* 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.
* 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;
}
/* 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;
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;
/* 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;
* 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;
}
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;
}
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;
}
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);
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
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
* 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;
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))
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) */
* 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;
}
*
* @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. */
/* 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;
}
/*
*/
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
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');
}
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++);
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;
}
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) {
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)
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;
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];
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;
}
#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;
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);
}
errno_save = errno;
fputs("WARNING: ", stderr);
vfprintf(stderr, format, va);
+ putc('\n', stderr);
errno = errno_save;
va_end(va);
}
#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)
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
}
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;
}
}
&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;
}
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;
}
}
&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;
}
p++;
}
}
-
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
*/
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)
/*
* 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)
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;
}
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();
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;
}
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);
}
}
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;
return w->hdr.integrity.size != 0;
}
-
WIMLIBAPI void wimlib_print_available_images(const WIMStruct *w, int image)
{
if (image == WIM_ALL_IMAGES) {
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;
{
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);
&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;
}
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;
* 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
* @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
* 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
* 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.
#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
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. */
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[])
{
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,
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;
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;
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;
}
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;
* */
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;
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;
}
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) {
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;
}
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);
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. */
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)
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
}
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
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 */
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
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;
}
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)
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;
#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;
/* 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)
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;
}
}
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;
if (ret != 0)
return ret;
}
- return 0;
+ return ret;
}
/* Reads the information from a <WINDOWS> element inside an <IMAGE> element. */
if (ret != 0)
return ret;
}
- return 0;
+ return ret;
}
/* Reads the information from an <IMAGE> element. */
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;
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);
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;
wim_info = CALLOC(1, sizeof(struct wim_info));
if (!wim_info) {
- ERROR("Out of memory!\n");
+ ERROR("Out of memory");
return WIMLIB_ERR_NOMEM;
}
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;
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;
if (rc < 0)
return rc;
} else {
- DEBUG("<WINDOWS> tag does not exist.\n");
+ DEBUG("<WINDOWS> tag does not exist.");
}
if (image_info->name) {
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++;
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);
*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;
}
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;
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;
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;
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;
}
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;
}
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;
}
if (ret != 0)
goto err2;
- DEBUG("Freeing XML tree.\n");
+ DEBUG("Freeing XML tree.");
xmlFreeDoc(doc);
xmlCleanupParser();
}
#define CHECK_RET ({ if (ret < 0) { \
- ERROR("Error writing XML data!\n"); \
+ ERROR("Error writing XML data"); \
ret = WIMLIB_ERR_WRITE; \
goto err2; \
} })
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;
}
CHECK_RET;
#endif
- DEBUG("Writing <WIM> element\n");
+ DEBUG("Writing <WIM> element");
ret = xmlTextWriterStartElement(writer, "WIM");
CHECK_RET;
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;
}
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);
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:
/* 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;
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;
{
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++)
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;
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;
}
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);
{
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 {
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;
NULL, freq_tab,
&xpress_lz_params);
- XPRESS_DEBUG("using %u matches\n", num_matches);
+ XPRESS_DEBUG("using %u matches", num_matches);
freq_tab[256]++;
compressed_len = ostream.output - (u8*)__compressed_data;
- XPRESS_DEBUG("Compressed %u => %u bytes\n",
- uncompressed_len, compressed_len);
+ XPRESS_DEBUG("Compressed %u => %u bytes",
+ uncompressed_len, compressed_len);
*compressed_len_ret = compressed_len;
#ifdef ENABLE_VERIFY_COMPRESSION
/* Verify that we really get the same thing back when decompressing. */
- XPRESS_DEBUG("Verifying the compressed data.\n");
+ XPRESS_DEBUG("Verifying the compressed data.");
u8 buf[uncompressed_len];
ret = xpress_decompress(__compressed_data, compressed_len, buf,
uncompressed_len);
if (ret != 0) {
- fprintf(stderr, "xpress_compress(): Failed to decompress data "
- "we compressed!\n");
+ ERROR("xpress_compress(): Failed to decompress data we "
+ "compressed");
abort();
}
for (i = 0; i < uncompressed_len; i++) {
if (buf[i] != uncompressed_data[i]) {
- fprintf(stderr, "xpress_compress(): Data we compressed "
- "didn't decompress to the original data "
- "(difference at byte %u of %u)\n",
- i + 1, uncompressed_len);
+ ERROR("xpress_compress(): Data we compressed didn't "
+ "decompress to the original data (difference at "
+ "byte %u of %u)", i + 1, uncompressed_len);
abort();
}
}
- XPRESS_DEBUG("Compression verified to be correct.\n");
+ XPRESS_DEBUG("Compression verified to be correct.");
#endif
return 0;
* the end. Otherwise Microsoft's software will fail to decompress the
* XPRESS-compressed data.
*
- * Howeve, WIMLIB's decompressor in xpress-decomp.c currently does not care if
+ * Howeve, wimlib's decompressor in xpress-decomp.c currently does not care if
* this extra symbol is there or not.
*/
#include "decomp.h"
-
-
/* Decodes @huffsym, a value >= XPRESS_NUM_CHARS, that is the header of a match.
* */
static int xpress_decode_match(int huffsym, uint window_pos, uint window_len,
if (window_pos + match_len > window_len) {
ERROR("XPRESS dedecompression error: match of length %d "
- "bytes overflows window\n", match_len);
+ "bytes overflows window", match_len);
return -1;
}
if (match_src < window) {
ERROR("XPRESS decompression error: match of length %d bytes "
- "references data before window (match_offset = "
- "%d, window_pos = %d)\n", match_len,
- match_offset, window_pos);
+ "references data before window (match_offset = %d, "
+ "window_pos = %d)", match_len, match_offset, window_pos);
return -1;
}
compressed_data = __compressed_data;
lens_p = lens;
- DEBUG2("compressed_len = %d, uncompressed_len = %d\n",
- compressed_len, uncompressed_len);
+ DEBUG2("compressed_len = %d, uncompressed_len = %d",
+ compressed_len, uncompressed_len);
/* XPRESS uses only one Huffman tree. It contains 512 symbols, and the
* code lengths of these symbols are given literally as 4-bit integers
return ret;
init_input_bitstream(&istream, compressed_data + XPRESS_NUM_SYMBOLS / 2,
- compressed_len - XPRESS_NUM_SYMBOLS / 2);
+ compressed_len - XPRESS_NUM_SYMBOLS / 2);
return xpress_decompress_literals(&istream, uncompressed_data,
uncompressed_len, lens, decode_table);