]> wimlib.net Git - wimlib/blobdiff - programs/imagex.c
wimlib-imagex append: Generate unique name if default name conflicts
[wimlib] / programs / imagex.c
index f8ffc7c1bce4190868f4aa88a79b852a792dfdec..1a3cbbd5a05176975e22ea78764d7b8e43bdbeb6 100644 (file)
@@ -104,7 +104,7 @@ IMAGEX_PROGNAME" apply WIMFILE [IMAGE_NUM | IMAGE_NAME | all]\n"
 "                    (DIRECTORY | NTFS_VOLUME) [--check] [--hardlink]\n"
 "                    [--symlink] [--verbose] [--ref=\"GLOB\"] [--unix-data]\n"
 "                    [--no-acls] [--strict-acls] [--rpfix] [--norpfix]\n"
-"                    [--including-invalid-names]\n"
+"                    [--include-invalid-names]\n"
 ),
 [CAPTURE] =
 T(
@@ -135,7 +135,7 @@ T(
 IMAGEX_PROGNAME" extract WIMFILE (IMAGE_NUM | IMAGE_NAME) [PATH...]\n"
 "              [--check] [--ref=\"GLOB\"] [--verbose] [--unix-data]\n"
 "              [--no-acls] [--strict-acls] [--to-stdout] [--dest-dir=DIR]\n"
-"              [--including-invalid-names]\n"
+"              [--include-invalid-names]\n"
 ),
 [INFO] =
 T(
@@ -211,7 +211,7 @@ enum {
        IMAGEX_FORCE_OPTION,
        IMAGEX_HARDLINK_OPTION,
        IMAGEX_HEADER_OPTION,
-       IMAGEX_INCLUDING_INVALID_NAMES_OPTION,
+       IMAGEX_INCLUDE_INVALID_NAMES_OPTION,
        IMAGEX_LAZY_OPTION,
        IMAGEX_LOOKUP_TABLE_OPTION,
        IMAGEX_METADATA_OPTION,
@@ -247,7 +247,7 @@ static const struct option apply_options[] = {
        {T("strict-acls"), no_argument,       NULL, IMAGEX_STRICT_ACLS_OPTION},
        {T("rpfix"),       no_argument,       NULL, IMAGEX_RPFIX_OPTION},
        {T("norpfix"),     no_argument,       NULL, IMAGEX_NORPFIX_OPTION},
-       {T("including-invalid-names"), no_argument,       NULL, IMAGEX_INCLUDING_INVALID_NAMES_OPTION},
+       {T("include-invalid-names"), no_argument,       NULL, IMAGEX_INCLUDE_INVALID_NAMES_OPTION},
        {NULL, 0, NULL, 0},
 };
 static const struct option capture_or_append_options[] = {
@@ -295,7 +295,7 @@ static const struct option extract_options[] = {
        {T("strict-acls"), no_argument,       NULL, IMAGEX_STRICT_ACLS_OPTION},
        {T("dest-dir"),    required_argument, NULL, IMAGEX_DEST_DIR_OPTION},
        {T("to-stdout"),   no_argument,       NULL, IMAGEX_TO_STDOUT_OPTION},
-       {T("including-invalid-names"), no_argument, NULL, IMAGEX_INCLUDING_INVALID_NAMES_OPTION},
+       {T("include-invalid-names"), no_argument, NULL, IMAGEX_INCLUDE_INVALID_NAMES_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -1083,8 +1083,8 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                unit_shift = get_unit(info->integrity.total_bytes, &unit_name);
                percent_done = TO_PERCENT(info->integrity.completed_bytes,
                                          info->integrity.total_bytes);
-               tprintf(T("\rVerifying integrity of \"%"TS"\": %"PRIu64" "TS" "
-                       "of %"PRIu64" "TS" (%u%%) done"),
+               tprintf(T("\rVerifying integrity of \"%"TS"\": %"PRIu64" %"TS" "
+                       "of %"PRIu64" %"TS" (%u%%) done"),
                        info->integrity.filename,
                        info->integrity.completed_bytes >> unit_shift,
                        unit_name,
@@ -1536,7 +1536,7 @@ imagex_apply(int argc, tchar **argv)
                case IMAGEX_RPFIX_OPTION:
                        extract_flags |= WIMLIB_EXTRACT_FLAG_RPFIX;
                        break;
-               case IMAGEX_INCLUDING_INVALID_NAMES_OPTION:
+               case IMAGEX_INCLUDE_INVALID_NAMES_OPTION:
                        extract_flags |= WIMLIB_EXTRACT_FLAG_REPLACE_INVALID_FILENAMES;
                        extract_flags |= WIMLIB_EXTRACT_FLAG_ALL_CASE_CONFLICTS;
                        break;
@@ -1659,6 +1659,7 @@ imagex_capture_or_append(int argc, tchar **argv)
        bool capture_sources_malloced;
        struct wimlib_capture_source *capture_sources;
        size_t num_sources;
+       bool name_defaulted;
 
        for_opt(c, capture_or_append_options) {
                switch (c) {
@@ -1730,13 +1731,16 @@ imagex_capture_or_append(int argc, tchar **argv)
 
        if (argc >= 3) {
                name = argv[2];
+               name_defaulted = false;
        } else {
                /* Set default name to SOURCE argument, omitting any directory
                 * prefixes and trailing slashes.  This requires making a copy
-                * of @source. */
+                * of @source.  Leave some free characters at the end in case we
+                * append a number to keep the name unique. */
                source_name_len = tstrlen(source);
-               source_copy = alloca((source_name_len + 1) * sizeof(tchar));
+               source_copy = alloca((source_name_len + 1 + 25) * sizeof(tchar));
                name = tbasename(tstrcpy(source_copy, source));
+               name_defaulted = true;
        }
        /* Image description defaults to NULL if not given. */
        desc = (argc >= 4) ? argv[3] : NULL;
@@ -1815,6 +1819,20 @@ imagex_capture_or_append(int argc, tchar **argv)
                        }
                }
        }
+
+       if (cmd == APPEND && name_defaulted) {
+               /* If the user did not specify an image name, and the basename
+                * of the source already exists as an image name in the WIM
+                * file, append a suffix to make it unique. */
+               unsigned long conflict_idx;
+               tchar *name_end = tstrchr(name, T('\0'));
+               for (conflict_idx = 1;
+                    wimlib_image_name_in_use(w, name);
+                    conflict_idx++)
+               {
+                       tsprintf(name_end, T(" (%lu)"), conflict_idx);
+               }
+       }
 #ifdef __WIN32__
        win32_acquire_capture_privileges();
 #endif
@@ -2271,7 +2289,7 @@ imagex_extract(int argc, tchar **argv)
                        extract_flags |= WIMLIB_EXTRACT_FLAG_TO_STDOUT;
                        imagex_be_quiet = true;
                        break;
-               case IMAGEX_INCLUDING_INVALID_NAMES_OPTION:
+               case IMAGEX_INCLUDE_INVALID_NAMES_OPTION:
                        extract_flags |= WIMLIB_EXTRACT_FLAG_REPLACE_INVALID_FILENAMES;
                        extract_flags |= WIMLIB_EXTRACT_FLAG_ALL_CASE_CONFLICTS;
                        break;
@@ -3176,7 +3194,6 @@ out_release_privs:
 #ifdef __WIN32__
        win32_release_capture_privileges();
 #endif
-out_free_cmds:
        free(cmds);
 out_free_cmd_file_contents:
        free(cmd_file_contents);