]> wimlib.net Git - wimlib/blobdiff - src/wim.c
Implement advisory locking for WIM overwrites
[wimlib] / src / wim.c
index d455857814d2c2f4eb20f882d3f867abb239ce44..44653f191f685e95de5e4b5fc9a0b022d5fd458c 100644 (file)
--- a/src/wim.c
+++ b/src/wim.c
@@ -30,6 +30,8 @@
 #include <stdarg.h>
 
 #include "dentry.h"
+#include <unistd.h>
+#include <fcntl.h>
 
 #ifdef WITH_NTFS_3G
 #include <time.h>
@@ -41,7 +43,6 @@
 #include "lookup_table.h"
 #include "xml.h"
 
-
 static int print_metadata(WIMStruct *w)
 {
        DEBUG("Printing metadata for image %d", w->current_image);
@@ -72,7 +73,7 @@ WIMStruct *new_wim_struct()
 }
 
 /*
- * Calls a function on images in the WIM.  If @image is WIM_ALL_IMAGES, @visitor
+ * Calls a function on images in the WIM.  If @image is WIMLIB_ALL_IMAGES, @visitor
  * is called on the WIM once for each image, with each image selected as the
  * current image in turn.  If @image is a certain image, @visitor is called on
  * the WIM only once, with that image selected.
@@ -84,7 +85,7 @@ int for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *))
        int end;
        int i;
 
-       if (image == WIM_ALL_IMAGES) {
+       if (image == WIMLIB_ALL_IMAGES) {
                start = 1;
                end = w->hdr.image_count;
        } else if (image >= 1 && image <= w->hdr.image_count) {
@@ -130,7 +131,8 @@ static int append_metadata_resource_entry(struct lookup_table_entry *lte,
 
        if (lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) {
                if (w->current_image == w->hdr.image_count) {
-                       ERROR("Expected only %u images, but found more",
+                       ERROR("The WIM header says there are %u images in the WIM,\n"
+                             "        but we found more metadata resources than this",
                              w->hdr.image_count);
                        ret = WIMLIB_ERR_IMAGE_COUNT;
                } else {
@@ -150,13 +152,13 @@ int wim_hdr_flags_compression_type(int wim_hdr_flags)
 {
        if (wim_hdr_flags & WIM_HDR_FLAG_COMPRESSION) {
                if (wim_hdr_flags & WIM_HDR_FLAG_COMPRESS_LZX)
-                       return WIM_COMPRESSION_TYPE_LZX;
+                       return WIMLIB_COMPRESSION_TYPE_LZX;
                else if (wim_hdr_flags & WIM_HDR_FLAG_COMPRESS_XPRESS)
-                       return WIM_COMPRESSION_TYPE_XPRESS;
+                       return WIMLIB_COMPRESSION_TYPE_XPRESS;
                else
-                       return WIM_COMPRESSION_TYPE_INVALID;
+                       return WIMLIB_COMPRESSION_TYPE_INVALID;
        } else {
-               return WIM_COMPRESSION_TYPE_NONE;
+               return WIMLIB_COMPRESSION_TYPE_NONE;
        }
 }
 
@@ -214,10 +216,9 @@ int select_wim_image(WIMStruct *w, int image)
                return WIMLIB_ERR_INVALID_IMAGE;
        }
 
-
        /* If a valid image is currently selected, it can be freed if it is not
         * modified.  */
-       if (w->current_image != WIM_NO_IMAGE) {
+       if (w->current_image != WIMLIB_NO_IMAGE) {
                imd = wim_get_current_image_metadata(w);
                if (!imd->modified) {
                        DEBUG("Freeing image %u", w->current_image);
@@ -252,11 +253,11 @@ WIMLIBAPI int wimlib_get_compression_type(const WIMStruct *w)
 WIMLIBAPI const char *wimlib_get_compression_type_string(int ctype)
 {
        switch (ctype) {
-               case WIM_COMPRESSION_TYPE_NONE:
+               case WIMLIB_COMPRESSION_TYPE_NONE:
                        return "None";
-               case WIM_COMPRESSION_TYPE_LZX:
+               case WIMLIB_COMPRESSION_TYPE_LZX:
                        return "LZX";
-               case WIM_COMPRESSION_TYPE_XPRESS:
+               case WIMLIB_COMPRESSION_TYPE_XPRESS:
                        return "XPRESS";
                default:
                        return "Invalid";
@@ -274,16 +275,16 @@ WIMLIBAPI int wimlib_resolve_image(WIMStruct *w, const char *image_name_or_num)
        int image;
        int i;
 
-       if (!image_name_or_num)
-               return WIM_NO_IMAGE;
+       if (!image_name_or_num || !*image_name_or_num)
+               return WIMLIB_NO_IMAGE;
 
        if (strcmp(image_name_or_num, "all") == 0
            || strcmp(image_name_or_num, "*") == 0)
-               return WIM_ALL_IMAGES;
+               return WIMLIB_ALL_IMAGES;
        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;
+       if (p != image_name_or_num && *p == '\0' && image > 0) {
+               if (image > w->hdr.image_count)
+                       return WIMLIB_NO_IMAGE;
                return image;
        } else {
                for (i = 1; i <= w->hdr.image_count; i++) {
@@ -291,7 +292,7 @@ WIMLIBAPI int wimlib_resolve_image(WIMStruct *w, const char *image_name_or_num)
                                   wimlib_get_image_name(w, i)) == 0)
                                return i;
                }
-               return WIM_NO_IMAGE;
+               return WIMLIB_NO_IMAGE;
        }
 }
 
@@ -330,7 +331,7 @@ WIMLIBAPI void wimlib_print_available_images(const WIMStruct *w, int image)
        int last;
        int i;
        int n;
-       if (image == WIM_ALL_IMAGES) {
+       if (image == WIMLIB_ALL_IMAGES) {
                n = printf("Available Images:\n");
                first = 1;
                last = w->hdr.image_count;
@@ -351,8 +352,8 @@ WIMLIBAPI void wimlib_print_available_images(const WIMStruct *w, int image)
 }
 
 
-/* Prints the metadata for the specified image, which may be WIM_ALL_IMAGES, but
- * not WIM_NO_IMAGE. */
+/* Prints the metadata for the specified image, which may be WIMLIB_ALL_IMAGES, but
+ * not WIMLIB_NO_IMAGE. */
 WIMLIBAPI int wimlib_print_metadata(WIMStruct *w, int image)
 {
        if (!w)
@@ -419,7 +420,7 @@ WIMLIBAPI int wimlib_get_boot_idx(const WIMStruct *w)
 }
 
 /* Opens a WIM readable */
-int open_wim_readable(WIMStruct *w, const char *path)
+static int open_wim_readable(WIMStruct *w, const char *path)
 {
        if (w->fp != NULL)
                fclose(w->fp);
@@ -433,25 +434,12 @@ int open_wim_readable(WIMStruct *w, const char *path)
        return 0;
 }
 
-/* Opens a WIM writable */
-int open_wim_writable(WIMStruct *w, const char *path)
-{
-       wimlib_assert(w->out_fp == NULL);
-       wimlib_assert(path != NULL);
-       w->out_fp = fopen(path, "w+b");
-       if (!w->out_fp) {
-               ERROR_WITH_ERRNO("Failed to open `%s' for writing",
-                                path);
-               return WIMLIB_ERR_OPEN;
-       }
-       return 0;
-}
-
 /*
  * Begins the reading of a WIM file; opens the file and reads its header and
  * lookup table, and optionally checks the integrity.
  */
-static int begin_read(WIMStruct *w, const char *in_wim_path, int open_flags)
+static int begin_read(WIMStruct *w, const char *in_wim_path, int open_flags,
+                     wimlib_progress_func_t progress_func)
 {
        int ret;
        uint xml_num_images;
@@ -483,7 +471,7 @@ static int begin_read(WIMStruct *w, const char *in_wim_path, int open_flags)
                w->hdr.boot_idx = 0;
        }
 
-       if (wimlib_get_compression_type(w) == WIM_COMPRESSION_TYPE_INVALID) {
+       if (wimlib_get_compression_type(w) == WIMLIB_COMPRESSION_TYPE_INVALID) {
                ERROR("Invalid compression type (WIM header flags = %x)",
                      w->hdr.flags);
                ret = WIMLIB_ERR_INVALID_COMPRESSION_TYPE;
@@ -491,8 +479,7 @@ static int begin_read(WIMStruct *w, const char *in_wim_path, int open_flags)
        }
 
        if (open_flags & WIMLIB_OPEN_FLAG_CHECK_INTEGRITY) {
-               ret = check_wim_integrity(w,
-                                         open_flags & WIMLIB_OPEN_FLAG_SHOW_PROGRESS);
+               ret = check_wim_integrity(w, progress_func);
                if (ret == WIM_INTEGRITY_NONEXISTENT) {
                        WARNING("No integrity information for `%s'; skipping "
                                "integrity check.", w->filename);
@@ -554,7 +541,7 @@ static int begin_read(WIMStruct *w, const char *in_wim_path, int open_flags)
        qsort(w->image_metadata, w->current_image,
              sizeof(struct image_metadata), sort_image_metadata_by_position);
 
-       w->current_image = WIM_NO_IMAGE;
+       w->current_image = WIMLIB_NO_IMAGE;
 
        /* Read the XML data. */
        ret = read_xml_data(w->fp, &w->hdr.xml_res_entry,
@@ -588,7 +575,7 @@ out_free_xml_data:
 out_free_image_metadata:
        /*FREE(w->image_metadata);*/
        /*w->image_metadata = NULL;*/
-       /*w->current_image = WIM_NO_IMAGE;*/
+       /*w->current_image = WIMLIB_NO_IMAGE;*/
 out_free_lookup_table:
        /*free_lookup_table(w->lookup_table);*/
        /*w->lookup_table = NULL;*/
@@ -604,7 +591,8 @@ out:
  * Opens a WIM file and creates a WIMStruct for it.
  */
 WIMLIBAPI int wimlib_open_wim(const char *wim_file, int open_flags,
-                             WIMStruct **w_ret)
+                             WIMStruct **w_ret,
+                             wimlib_progress_func_t progress_func)
 {
        WIMStruct *w;
        int ret;
@@ -616,7 +604,7 @@ WIMLIBAPI int wimlib_open_wim(const char *wim_file, int open_flags,
                return WIMLIB_ERR_NOMEM;
        }
 
-       ret = begin_read(w, wim_file, open_flags);
+       ret = begin_read(w, wim_file, open_flags, progress_func);
        if (ret == 0) {
                *w_ret = w;
        } else {