]> wimlib.net Git - wimlib/blobdiff - programs/imagex.c
Fix glob()
[wimlib] / programs / imagex.c
index f635e08613ec9e2447db625f41372784e301ab08..0f65ae51cbdd1a18ef988fae3ef4f529f5a92717 100644 (file)
@@ -29,7 +29,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <getopt.h>
-#include <glob.h>
+
 #include <inttypes.h>
 #include <libgen.h>
 #include <limits.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <locale.h>
 
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
 #endif
 
+#ifdef __WIN32__
+#  include "imagex-win32.h"
+#else
+#  include <glob.h>
+#endif
+
 #define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
 
 #define for_opt(c, opts) while ((c = getopt_long_only(argc, (char**)argv, "", \
@@ -733,6 +740,7 @@ static int open_swms_from_glob(const char *swm_glob,
        glob_t globbuf;
        int ret;
 
+       /* Warning: glob() is replaced in Windows native builds */
        ret = glob(swm_glob, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf);
        if (ret != 0) {
                if (ret == GLOB_NOMATCH) {
@@ -893,11 +901,17 @@ static int imagex_apply(int argc, char **argv)
                }
        }
 
+#ifdef __WIN32__
+       win32_acquire_restore_privileges();
+#endif
        ret = wimlib_extract_image(w, image, target, extract_flags,
                                   additional_swms, num_additional_swms,
                                   imagex_progress_func);
        if (ret == 0)
                printf("Done applying WIM image.\n");
+#ifdef __WIN32__
+       win32_release_restore_privileges();
+#endif
 out:
        wimlib_free(w);
        if (additional_swms) {
@@ -1074,6 +1088,9 @@ static int imagex_capture_or_append(int argc, char **argv)
                        }
                }
        }
+#ifdef __WIN32__
+       win32_acquire_capture_privileges();
+#endif
 
        ret = wimlib_add_image_multisource(w, capture_sources,
                                           num_sources, name,
@@ -1084,17 +1101,17 @@ static int imagex_capture_or_append(int argc, char **argv)
                                           add_image_flags,
                                           imagex_progress_func);
        if (ret != 0)
-               goto out;
+               goto out_release_privs;
        cur_image = wimlib_get_num_images(w);
        if (desc) {
                ret = wimlib_set_image_descripton(w, cur_image, desc);
                if (ret != 0)
-                       goto out;
+                       goto out_release_privs;
        }
        if (flags_element) {
                ret = wimlib_set_image_flags(w, cur_image, flags_element);
                if (ret != 0)
-                       goto out;
+                       goto out_release_privs;
        }
        if (cmd == APPEND) {
                ret = wimlib_overwrite(w, write_flags, num_threads,
@@ -1107,6 +1124,10 @@ static int imagex_capture_or_append(int argc, char **argv)
                ret = 0;
        if (ret != 0)
                imagex_error("Failed to write the WIM file `%s'", wimfile);
+out_release_privs:
+#ifdef __WIN32__
+       win32_release_capture_privileges();
+#endif
 out:
        wimlib_free(w);
        free(config_str);
@@ -1322,9 +1343,10 @@ static int imagex_export(int argc, char **argv)
 
                wim_is_new = false;
                /* Destination file exists. */
-               if (!S_ISREG(stbuf.st_mode) && !S_ISLNK(stbuf.st_mode)) {
+
+               if (!S_ISREG(stbuf.st_mode)) {
                        imagex_error("`%s' is not a regular file",
-                                       dest_wimfile);
+                                    dest_wimfile);
                        ret = -1;
                        goto out;
                }
@@ -2099,6 +2121,8 @@ int main(int argc, char **argv)
        const struct imagex_command *cmd;
        int ret;
 
+       setlocale(LC_ALL, "");
+
        if (argc < 2) {
                imagex_error("No command specified");
                usage_all();
@@ -2114,8 +2138,7 @@ int main(int argc, char **argv)
        /* The user may like to see more informative error messages. */
        wimlib_set_print_errors(true);
 
-       /* Calling wimlib_global_init() is not strictly necessary because
-        * 'imagex' is single-threaded. */
+       /* Do any initializations that the library needs */
        ret = wimlib_global_init();
        if (ret)
                goto out;
@@ -2124,14 +2147,14 @@ int main(int argc, char **argv)
        for_imagex_command(cmd) {
                if (strcmp(cmd->name, *argv) == 0) {
                        ret = cmd->func(argc, argv);
-                       goto out;
+                       goto out_check_write_error;
                }
        }
 
        imagex_error("Unrecognized command: `%s'", argv[0]);
        usage_all();
        return 1;
-out:
+out_check_write_error:
        /* For 'imagex info' and 'imagex dir', data printed to standard output
         * is part of the program's actual behavior and not just for
         * informational purposes, so we should set a failure exit status if
@@ -2143,7 +2166,7 @@ out:
                                ret = -1;
                }
        }
-
+out:
        /* Exit status (ret):  -1 indicates an error found by 'imagex' outside
         * of the wimlib library code.  0 indicates success.  > 0 indicates a
         * wimlib error code from which an error message can be printed. */
@@ -2154,8 +2177,9 @@ out:
                if (ret == WIMLIB_ERR_NTFS_3G && errno != 0)
                        imagex_error_with_errno("errno");
        }
-       /* Calling wimlib_global_cleanup() is not strictly necessary because the
-        * process is exiting anyway. */
+
+       /* Make the library free any resources it's holding (not strictly
+        * necessary because the process is ending anyway). */
        wimlib_global_cleanup();
        return ret;
 }