X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=programs%2Fimagex.c;h=f83bbb0b1ded60aad5ba178557a264868df66b8f;hp=2d664084606ae10c8e2d09eb99e2e76ea820bafa;hb=200bd141bea66770dd9845a95f2403d59956b931;hpb=53d4db68e30bf45b983c59f91e5e2a3e039e1426 diff --git a/programs/imagex.c b/programs/imagex.c index 2d664084..f83bbb0b 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -75,14 +75,14 @@ static const char *path_basename(const char *path) static const char *usage_strings[] = { [APPEND] = " imagex append DIRECTORY WIMFILE [\"IMAGE_NAME\"] [\"DESCRIPTION\"] [--boot]\n" -" [--check] [--config CONFIG_FILE] [--flags EDITIONID] [--verify]\n", +" [--check] [--flags EDITIONID] [--dereference]\n", [APPLY] = " imagex apply WIMFILE [IMAGE_NUM | IMAGE_NAME | all] DIRECTORY [--check]\n" -" [--verify] [--hardlink] [--symlink] [--verbose]\n", +" [--hardlink] [--symlink] [--verbose]\n", [CAPTURE] = " imagex capture DIRECTORY WIMFILE [\"IMAGE_NAME\"] [\"DESCRIPTION\"]\n" -" [--boot] [--check] [--compress[=TYPE]] [--config CONFIG_FILE]\n" -" [--flags \"EditionID\"] [--norpfix] [--verify] [--verbose]\n", +" l [--boot] [--check] [--compress[=TYPE]]\n" +" [--flags \"EditionID\"] [--verbose] [--dereference]\n", [DELETE] = " imagex delete WIMFILE (IMAGE_NUM | IMAGE_NAME | all) [--check]\n", [DIR] = @@ -90,19 +90,19 @@ static const char *usage_strings[] = { [EXPORT] = " imagex export SRC_WIMFILE (SRC_IMAGE_NUM | SRC_IMAGE_NAME | all ) \n" " DEST_WIMFILE [\"DEST_IMAGE_NAME\"] [\"DEST_IMAGE_DESCRIPTION\"]\n" -" [--boot] [--check] [--compress[=TYPE]]\n", +" [--boot] [--check] [--compress[=TYPE]]\n", [INFO] = " imagex info WIMFILE [IMAGE_NUM | IMAGE_NAME] [NEW_NAME]\n" -" [NEW_DESC] [--boot] [--check] [--header] [--lookup-table]\n" -" [--xml] [--extract-xml FILE] [--metadata]\n", +" [NEW_DESC] [--boot] [--check] [--header] [--lookup-table]\n" +" [--xml] [--extract-xml FILE] [--metadata]\n", [JOIN] = " imagex join [--check] WIMFILE SPLIT_WIM...\n", [MOUNT] = " imagex mount WIMFILE (IMAGE_NUM | IMAGE_NAME) DIRECTORY\n" -" [--check] [--debug]\n", +" [--check] [--debug] [--stream-interface=INTERFACE]\n", [MOUNTRW] = " imagex mountrw WIMFILE [IMAGE_NUM | IMAGE_NAME] DIRECTORY\n" -" [--check] [--debug]\n", +" [--check] [--debug] [--stream-interface=INTERFACE]\n", [SPLIT] = " imagex split WIMFILE SPLIT_WIMFILE PART_SIZE [--check]\n", [UNMOUNT] = @@ -118,28 +118,26 @@ static const struct option common_options[] = { static const struct option append_options[] = { {"boot", no_argument, NULL, 'b'}, {"check", no_argument, NULL, 'c'}, - {"config", required_argument, NULL, 'C'}, {"flags", required_argument, NULL, 'f'}, - {"verify", no_argument, NULL, 'V'}, + {"dereference", no_argument, NULL, 'L'}, {NULL, 0, NULL, 0}, }; static const struct option apply_options[] = { {"check", no_argument, NULL, 'c'}, - {"verify", no_argument, NULL, 'V'}, {"hardlink", no_argument, NULL, 'h'}, {"symlink", no_argument, NULL, 's'}, {"verbose", no_argument, NULL, 'v'}, + {"ntfs", no_argument, NULL, 'N'}, {NULL, 0, NULL, 0}, }; static const struct option capture_options[] = { {"boot", no_argument, NULL, 'b'}, {"check", no_argument, NULL, 'c'}, {"compress", optional_argument, NULL, 'x'}, - {"config", required_argument, NULL, 'C'}, {"flags", required_argument, NULL, 'f'}, - {"norpfix", no_argument, NULL, 'n'}, - {"verify", no_argument, NULL, 'V'}, - {"verbose", no_argument, NULL, 'v'}, + {"verbose", no_argument, NULL,'v'}, + {"ntfs", no_argument, NULL, 'N'}, + {"dereference", no_argument, NULL, 'L'}, {NULL, 0, NULL, 0}, }; static const struct option delete_options[] = { @@ -173,6 +171,7 @@ static const struct option join_options[] = { static const struct option mount_options[] = { {"check", no_argument, NULL, 'c'}, {"debug", no_argument, NULL, 'd'}, + {"stream-interface", required_argument, NULL, 's'}, {NULL, 0, NULL, 0}, }; @@ -195,6 +194,19 @@ static void imagex_error(const char *format, ...) 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); } @@ -235,7 +247,7 @@ static void usage_all() 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; @@ -244,7 +256,7 @@ static int verify_image_exists(int image) 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; @@ -271,8 +283,7 @@ static int get_compression_type(const char *optarg) 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; } } @@ -300,14 +311,11 @@ static int imagex_append(int argc, const char **argv) open_flags |= WIMLIB_OPEN_FLAG_CHECK_INTEGRITY; write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY; break; - case 'C': - /*config = optarg;*/ - break; case 'f': flags_element = optarg; break; - case 'V': - /* verify */ + case 'L': + add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE; break; default: usage(APPEND); @@ -343,9 +351,7 @@ done: static int imagex_apply(int argc, const char **argv) { int c; - int link_type = WIM_LINK_TYPE_NONE; int open_flags = WIMLIB_OPEN_FLAG_SHOW_PROGRESS; - bool verbose = false; int image; int num_images; WIMStruct *w; @@ -353,23 +359,24 @@ static int imagex_apply(int argc, const char **argv) const char *wimfile; const char *dir; const char *image_num_or_name; + int extract_flags = 0; for_opt(c, apply_options) { switch (c) { case 'c': open_flags |= WIMLIB_OPEN_FLAG_CHECK_INTEGRITY; break; - case 'V': - /* verify */ - break; case 'h': - link_type = WIM_LINK_TYPE_HARD; + extract_flags |= WIMLIB_EXTRACT_FLAG_HARDLINK; break; case 's': - link_type = WIM_LINK_TYPE_SYMBOLIC; + extract_flags |= WIMLIB_EXTRACT_FLAG_SYMLINK; break; case 'v': - verbose = true; + extract_flags |= WIMLIB_EXTRACT_FLAG_VERBOSE; + break; + case 'N': + extract_flags |= WIMLIB_EXTRACT_FLAG_NTFS; break; default: usage(APPLY); @@ -404,17 +411,12 @@ static int imagex_apply(int argc, const char **argv) 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_set_output_dir(w, dir); - if (ret != 0) - goto done; - wimlib_set_verbose(w, verbose); - wimlib_set_link_type(w, link_type); - ret = wimlib_extract_image(w, image); + ret = wimlib_extract_image(w, image, dir, extract_flags); done: wimlib_free(w); return ret; @@ -428,8 +430,7 @@ static int imagex_capture(int argc, const char **argv) int add_image_flags = 0; int write_flags = WIMLIB_WRITE_FLAG_SHOW_PROGRESS; int compression_type = WIM_COMPRESSION_TYPE_NONE; - const char *flags_element = NULL; - bool verbose = false; + const char *flags_element = NULL; const char *dir; const char *wimfile; const char *name; @@ -450,20 +451,17 @@ static int imagex_capture(int argc, const char **argv) if (compression_type == WIM_COMPRESSION_TYPE_INVALID) return -1; break; - case 'C': - /*config = optarg;*/ - break; case 'f': flags_element = optarg; break; - case 'n': - /*norpfix = true;*/ - break; case 'v': - verbose = true; + add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_VERBOSE; + break; + case 'N': + add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_NTFS; break; - case 'V': - /*verify = true;*/ + case 'L': + add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE; break; default: usage(CAPTURE); @@ -486,18 +484,16 @@ static int imagex_capture(int argc, const char **argv) if (ret != 0) return ret; - wimlib_set_verbose(w, verbose); - 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; @@ -531,9 +527,9 @@ static int imagex_delete(int argc, const char **argv) 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; } @@ -552,15 +548,14 @@ static int imagex_delete(int argc, const char **argv) 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); @@ -578,12 +573,12 @@ static int imagex_dir(int argc, const char **argv) 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; } @@ -595,9 +590,9 @@ static int imagex_dir(int argc, const char **argv) 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; } @@ -613,7 +608,7 @@ static int imagex_dir(int argc, const char **argv) 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; @@ -691,7 +686,7 @@ static int imagex_export(int argc, const char **argv) 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; } @@ -702,8 +697,9 @@ static int imagex_export(int argc, const char **argv) 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"); + ret = -1; goto done; } compression_type = wimlib_get_compression_type(dest_w); @@ -715,7 +711,7 @@ static int imagex_export(int argc, const char **argv) 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; } @@ -838,12 +834,12 @@ static int imagex_info(int argc, const char **argv) 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; } @@ -851,15 +847,15 @@ static int imagex_info(int argc, const char **argv) 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; } @@ -870,8 +866,8 @@ static int imagex_info(int argc, const char **argv) 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; } @@ -885,8 +881,8 @@ static int imagex_info(int argc, const char **argv) 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); } @@ -900,15 +896,16 @@ static int imagex_info(int argc, const char **argv) 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; } @@ -922,8 +919,8 @@ static int imagex_info(int argc, const char **argv) 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); @@ -932,7 +929,7 @@ static int imagex_info(int argc, const char **argv) } } 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) @@ -940,18 +937,18 @@ static int imagex_info(int argc, const char **argv) 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); } } @@ -959,11 +956,11 @@ static int imagex_info(int argc, const char **argv) 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; @@ -974,11 +971,11 @@ static int imagex_info(int argc, const char **argv) 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) @@ -1026,8 +1023,8 @@ static int imagex_join(int argc, const char **argv) 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]; @@ -1060,19 +1057,26 @@ static int imagex_mount_rw_or_ro(int argc, const char **argv) case 'd': mount_flags |= WIMLIB_MOUNT_FLAG_DEBUG; break; + case 's': + if (strcasecmp(optarg, "none") == 0) + mount_flags |= WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_NONE; + else if (strcasecmp(optarg, "xattr") == 0) + mount_flags |= WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR; + else if (strcasecmp(optarg, "windows") == 0) + mount_flags |= WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS; + else { + imagex_error("Unknown stream interface \"%s\"", optarg); + goto mount_usage; + } + break; default: - usage((mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) - ? MOUNTRW : MOUNT); - return -1; + goto mount_usage; } } argc -= optind; argv += optind; - if (argc != 2 && argc != 3) { - usage((mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) - ? MOUNTRW : MOUNT); - return -1; - } + if (argc != 2 && argc != 3) + goto mount_usage; wimfile = argv[0]; @@ -1085,7 +1089,7 @@ static int imagex_mount_rw_or_ro(int argc, const char **argv) 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; @@ -1103,13 +1107,17 @@ static int imagex_mount_rw_or_ro(int argc, const char **argv) 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: wimlib_free(w); return ret; +mount_usage: + usage((mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) + ? MOUNTRW : MOUNT); + return -1; } /* Split a WIM into a spanned set */ @@ -1169,7 +1177,7 @@ static int imagex_unmount(int argc, const char **argv) 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; } @@ -1235,7 +1243,7 @@ int main(int argc, const char **argv) int ret; if (argc < 2) { - imagex_error("No command specified!\n"); + imagex_error("No command specified"); usage_all(); return 1; } @@ -1251,14 +1259,21 @@ int main(int argc, const char **argv) 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; } +/*#ifndef WITH_NTFS_3G*/ + /*ERROR("wimlib was not compiled with support for NTFS-3g, so we cannot extract");*/ + /*ERROR("a WIM to a NTFS filesystem while preserving NTFS-specific metadata.");*/ + /*ERROR("Please apply the WIM to a directory rather than a block device, ");*/ + /*ERROR("and without the NTFS flag; or compile in support for NTFS-3g.");*/ + /*return WIMLIB_ERR_UNSUPPORTED;*/ +/*#endif*/