extract_wim_resource() refactor
authorEric Biggers <ebiggers3@gmail.com>
Mon, 17 Dec 2012 03:50:12 +0000 (21:50 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 17 Dec 2012 03:50:12 +0000 (21:50 -0600)
src/extract_image.c
src/ntfs-apply.c
src/resource.c
src/util.c
src/util.h
src/wimlib_internal.h

index 470469a..ba9b8c6 100644 (file)
@@ -174,7 +174,7 @@ static int extract_regular_file_unlinked(struct dentry *dentry,
                goto out;
        }
 
-       ret = extract_full_wim_resource_to_fd(lte, out_fd);
+       ret = extract_wim_resource_to_fd(lte, out_fd, wim_resource_size(lte));
        if (ret != 0) {
                ERROR("Failed to extract resource to `%s'", output_path);
                goto out;
index dc732d8..f1ff0dd 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 
+static int extract_wim_chunk_to_ntfs_attr(const u8 *buf, size_t len,
+                                         u64 offset, void *arg)
+{
+       ntfs_attr *na = arg;
+       if (ntfs_attr_pwrite(na, offset, len, buf) == len) {
+               return 0;
+       } else {
+               ERROR_WITH_ERRNO("Error extracting WIM resource to NTFS attribute");
+               return WIMLIB_ERR_WRITE;
+       }
+}
+
 /*
  * Extracts a WIM resource to a NTFS attribute.
  */
@@ -51,37 +63,8 @@ static int
 extract_wim_resource_to_ntfs_attr(const struct lookup_table_entry *lte,
                                  ntfs_attr *na)
 {
-       u64 bytes_remaining = wim_resource_size(lte);
-       u8 buf[min(WIM_CHUNK_SIZE, bytes_remaining)];
-       u64 offset = 0;
-       int ret = 0;
-       u8 hash[SHA1_HASH_SIZE];
-
-       SHA_CTX ctx;
-       sha1_init(&ctx);
-
-       while (bytes_remaining) {
-               u64 to_read = min(bytes_remaining, WIM_CHUNK_SIZE);
-               ret = read_wim_resource(lte, buf, to_read, offset, 0);
-               if (ret != 0)
-                       break;
-               sha1_update(&ctx, buf, to_read);
-               if (ntfs_attr_pwrite(na, offset, to_read, buf) != to_read) {
-                       ERROR_WITH_ERRNO("Error extracting WIM resource");
-                       return WIMLIB_ERR_WRITE;
-               }
-               bytes_remaining -= to_read;
-               offset += to_read;
-       }
-       sha1_final(hash, &ctx);
-       if (!hashes_equal(hash, lte->hash)) {
-               ERROR("Invalid checksum on a WIM resource "
-                     "(detected when extracting to NTFS stream)");
-               ERROR("The following WIM resource is invalid:");
-               print_lookup_table_entry(lte);
-               return WIMLIB_ERR_INVALID_RESOURCE_HASH;
-       }
-       return 0;
+       return extract_wim_resource(lte, wim_resource_size(lte),
+                                   extract_wim_chunk_to_ntfs_attr, na);
 }
 
 /* Writes the data streams to a NTFS file
index 6636013..9d6fe2d 100644 (file)
  * wimlib; if not, see http://www.gnu.org/licenses/.
  */
 
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include "dentry.h"
-
 #include "wimlib_internal.h"
+#include "dentry.h"
 #include "lookup_table.h"
 #include "buffer_io.h"
 #include "lzx.h"
 #include "xpress.h"
 #include "sha1.h"
-#include <unistd.h>
+
 #include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
 
 #ifdef WITH_NTFS_3G
 #include <time.h>
@@ -45,7 +42,6 @@
 #include <ntfs-3g/dir.h>
 #endif
 
-
 /*
  * Reads all or part of a compressed resource into an in-memory buffer.
  *
@@ -375,9 +371,6 @@ int read_uncompressed_resource(FILE *fp, u64 offset, u64 len,
        return 0;
 }
 
-
-
-
 /* Reads the contents of a struct resource_entry, as represented in the on-disk
  * format, from the memory pointed to by @p, and fills in the fields of @entry.
  * A pointer to the byte after the memory read at @p is returned. */
@@ -609,14 +602,10 @@ int read_full_wim_resource(const struct lookup_table_entry *lte, u8 buf[],
        return read_wim_resource(lte, buf, wim_resource_size(lte), 0, flags);
 }
 
-/*
- * Extracts the first @size bytes of the WIM resource specified by @lte to the
- * open file descriptor @fd.
- *
- * Returns 0 on success; nonzero on failure.
- */
-int extract_wim_resource_to_fd(const struct lookup_table_entry *lte, int fd,
-                              u64 size)
+int extract_wim_resource(const struct lookup_table_entry *lte,
+                        u64 size,
+                        extract_chunk_func_t extract_chunk,
+                        void *extract_chunk_arg)
 {
        u64 bytes_remaining = size;
        u8 buf[min(WIM_CHUNK_SIZE, bytes_remaining)];
@@ -628,37 +617,65 @@ int extract_wim_resource_to_fd(const struct lookup_table_entry *lte, int fd,
        sha1_init(&ctx);
 
        while (bytes_remaining) {
-               u64 to_read = min(bytes_remaining, WIM_CHUNK_SIZE);
+               u64 to_read = min(bytes_remaining, sizeof(buf));
                ret = read_wim_resource(lte, buf, to_read, offset, 0);
                if (ret != 0)
                        break;
                sha1_update(&ctx, buf, to_read);
-               if (full_write(fd, buf, to_read) < to_read) {
+               ret = extract_chunk(buf, to_read, offset, extract_chunk_arg);
+               if (ret != 0) {
                        ERROR_WITH_ERRNO("Error extracting WIM resource");
-                       return WIMLIB_ERR_WRITE;
+                       return ret;
                }
                bytes_remaining -= to_read;
                offset += to_read;
        }
        sha1_final(hash, &ctx);
        if (!hashes_equal(hash, lte->hash)) {
-               ERROR("Invalid checksum on a WIM resource "
-                     "(detected when extracting to external file)");
-               ERROR("The following WIM resource is invalid:");
+       #ifdef ENABLE_ERROR_MESSAGES
+               ERROR("Invalid checksum on the following WIM resource:");
                print_lookup_table_entry(lte);
+       #endif
                return WIMLIB_ERR_INVALID_RESOURCE_HASH;
        }
        return 0;
 }
 
-/*
- * Extracts the WIM resource specified by @lte to the open file descriptor @fd.
+/* Write @n bytes from @buf to the file descriptor @fd, retrying on interupt and
+ * on short writes.
  *
- * Returns 0 on success; nonzero on failure.
- */
-int extract_full_wim_resource_to_fd(const struct lookup_table_entry *lte, int fd)
+ * Returns short count and set errno on failure. */
+static ssize_t full_write(int fd, const void *buf, size_t n)
+{
+       const char *p = buf;
+       ssize_t ret;
+       ssize_t total = 0;
+
+       while (total != n) {
+               ret = write(fd, p, n);
+               if (ret < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       else
+                               break;
+               }
+               total += ret;
+               p += ret;
+       }
+       return total;
+}
+
+int extract_wim_chunk_to_fd(const u8 *buf, size_t len,
+                           u64 offset, void *arg)
 {
-       return extract_wim_resource_to_fd(lte, fd, wim_resource_size(lte));
+       int fd = *(int*)arg;
+       ssize_t ret = full_write(fd, buf, len);
+       if (ret < len) {
+               ERROR_WITH_ERRNO("Error writing to file descriptor");
+               return WIMLIB_ERR_WRITE;
+       } else {
+               return 0;
+       }
 }
 
 /*
index 01ba8f3..78272df 100644 (file)
@@ -360,31 +360,6 @@ char *utf8_to_utf16(const char *utf8_str, size_t utf8_len,
        return orig_utf16_str;
 }
 
-/* Write @n bytes from @buf to the file descriptor @fd, retrying on interupt and
- * on short writes.
- *
- * Returns short count and set errno on failure. */
-ssize_t full_write(int fd, const void *buf, size_t n)
-{
-       const char *p = buf;
-       ssize_t ret;
-       ssize_t total = 0;
-
-       while (total != n) {
-               ret = write(fd, p, n);
-               if (ret < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       else
-                               break;
-               }
-               total += ret;
-               p += ret;
-       }
-       return total;
-}
-
-
 static bool seeded = false;
 
 static void seed_random()
index 2893593..083ddb2 100644 (file)
@@ -181,8 +181,6 @@ extern void print_string(const void *string, size_t len);
 
 extern int get_num_path_components(const char *path);
 
-extern ssize_t full_write(int fd, const void *buf, size_t n);
-
 static inline void print_byte_field(const u8 field[], size_t len)
 {
        while (len--)
index 458cace..9d25e1e 100644 (file)
@@ -396,6 +396,12 @@ extern int new_joined_lookup_table(WIMStruct *w,
                                   unsigned num_additional_swms,
                                   struct lookup_table **table_ret);
 
+/* metadata_resource.c */
+
+extern int read_metadata_resource(WIMStruct *w,
+                                 struct image_metadata *image_metadata);
+extern int write_metadata_resource(WIMStruct *w);
+
 /* ntfs-apply.c */
 
 struct apply_args {
@@ -447,20 +453,32 @@ extern int write_wim_resource(struct lookup_table_entry *lte,
                              struct resource_entry *out_res_entry,
                              int flags);
 
-extern int extract_wim_resource_to_fd(const struct lookup_table_entry *lte,
-                                     int fd, u64 size);
 
+typedef int (*extract_chunk_func_t)(const u8 *, size_t, u64, void *);
 
-extern int extract_full_wim_resource_to_fd(const struct lookup_table_entry *lte,
-                                          int fd);
+extern int extract_wim_chunk_to_fd(const u8 *buf, size_t len,
+                                  u64 offset, void *arg);
 
-extern int read_metadata_resource(WIMStruct *w,
-                                 struct image_metadata *image_metadata);
+extern int extract_wim_resource(const struct lookup_table_entry *lte,
+                               u64 size, extract_chunk_func_t extract_chunk,
+                               void *extract_chunk_arg);
+/*
+ * Extracts the first @size bytes of the WIM resource specified by @lte to the
+ * open file descriptor @fd.
+ *
+ * Returns 0 on success; nonzero on failure.
+ */
+static inline int
+extract_wim_resource_to_fd(const struct lookup_table_entry *lte,
+                          int fd, u64 size)
+{
+       return extract_wim_resource(lte, size,
+                                   extract_wim_chunk_to_fd, &fd);
+}
 
 
 extern int write_dentry_resources(struct dentry *dentry, void *wim_p);
 extern int copy_resource(struct lookup_table_entry *lte, void *w);
-extern int write_metadata_resource(WIMStruct *w);
 
 
 /* security.c */