X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=programs%2Fimagex.c;h=fc89cdfe036aec38146f5dee6464b1d3f54a82d8;hp=07381a9bf5752bf2f2642ceeb1e31e2b05920cee;hb=e03410487e77ea4aa8af8ebcf279f4ccbcd9ccba;hpb=512d3f87a1e7b59ca19ae6d6965dbcf7f4a17c15 diff --git a/programs/imagex.c b/programs/imagex.c index 07381a9b..fc89cdfe 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0])) @@ -81,7 +82,7 @@ static const char *usage_strings[] = { " imagex export SRC_WIMFILE (SRC_IMAGE_NUM | SRC_IMAGE_NAME | all ) \n" " DEST_WIMFILE [DEST_IMAGE_NAME]\n" " [DEST_IMAGE_DESCRIPTION] [--boot] [--check]\n" -" [--compress=TYPE]\n", +" [--compress=TYPE] [--ref=\"GLOB\"]\n", [INFO] = " imagex info WIMFILE [IMAGE_NUM | IMAGE_NAME] [NEW_NAME]\n" " [NEW_DESC] [--boot] [--check] [--header] [--lookup-table]\n" @@ -107,15 +108,6 @@ static const struct option common_options[] = { {NULL, 0, NULL, 0}, }; -static const struct option append_options[] = { - {"boot", no_argument, NULL, 'b'}, - {"check", no_argument, NULL, 'c'}, - {"config", required_argument, NULL, 'C'}, - {"dereference", no_argument, NULL, 'L'}, - {"flags", required_argument, NULL, 'f'}, - {"verbose", no_argument, NULL, 'v'}, - {NULL, 0, NULL, 0}, -}; static const struct option apply_options[] = { {"check", no_argument, NULL, 'c'}, {"hardlink", no_argument, NULL, 'h'}, @@ -124,7 +116,7 @@ static const struct option apply_options[] = { {"ref", required_argument, NULL, 'r'}, {NULL, 0, NULL, 0}, }; -static const struct option capture_options[] = { +static const struct option capture_or_append_options[] = { {"boot", no_argument, NULL, 'b'}, {"check", no_argument, NULL, 'c'}, {"compress", required_argument, NULL, 'x'}, @@ -143,6 +135,7 @@ static const struct option export_options[] = { {"boot", no_argument, NULL, 'b'}, {"check", no_argument, NULL, 'c'}, {"compress", required_argument, NULL, 'x'}, + {"ref", required_argument, NULL, 'r'}, {NULL, 0, NULL, 0}, }; @@ -266,7 +259,7 @@ static int get_compression_type(const char *optarg) } } -static const char *file_get_contents(const char *filename, size_t *len_ret) +static char *file_get_contents(const char *filename, size_t *len_ret) { struct stat stbuf; char *buf; @@ -361,114 +354,6 @@ out: return ret; } -static int imagex_append(int argc, const char **argv) -{ - int c; - const char *flags_element = NULL; - int open_flags = WIMLIB_OPEN_FLAG_SHOW_PROGRESS; - int add_image_flags = 0; - int write_flags = WIMLIB_WRITE_FLAG_SHOW_PROGRESS; - const char *dir; - const char *wimfile; - const char *name; - const char *desc; - const char *config_file = NULL; - const char *config_str = NULL; - size_t config_len = 0; - WIMStruct *w; - int ret; - int cur_image; - - for_opt(c, append_options) { - switch (c) { - case 'b': - add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_BOOT; - break; - case 'c': - open_flags |= WIMLIB_OPEN_FLAG_CHECK_INTEGRITY; - write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY; - break; - case 'C': - config_file = optarg; - break; - case 'f': - flags_element = optarg; - break; - case 'L': - add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE; - break; - case 'v': - add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_VERBOSE; - break; - default: - usage(APPEND); - return -1; - } - } - argc -= optind; - argv += optind; - if (argc < 2 || argc > 4) { - usage(APPEND); - return -1; - } - dir = argv[0]; - wimfile = argv[1]; - name = (argc >= 3) ? argv[2] : path_basename(dir); - desc = (argc >= 4) ? argv[3] : NULL; - - if (config_file) { - config_str = file_get_contents(config_file, &config_len); - if (!config_str) - return -1; - } - - ret = wimlib_open_wim(wimfile, open_flags, &w); - if (ret != 0) - return ret; - -#ifdef WITH_NTFS_3G - struct stat stbuf; - - ret = stat(dir, &stbuf); - if (ret == 0) { - if (S_ISBLK(stbuf.st_mode) || S_ISREG(stbuf.st_mode)) { - const char *ntfs_device = dir; - printf("Capturing WIM image NTFS filesystem on `%s'\n", - ntfs_device); - ret = wimlib_add_image_from_ntfs_volume(w, ntfs_device, - name, - config_str, - config_len, - add_image_flags); - goto out_write; - } - } else { - if (errno != ENOENT) - imagex_error_with_errno("Failed to stat `%s'", dir); - } -#endif - ret = wimlib_add_image(w, dir, name, config_str, config_len, - add_image_flags); - -out_write: - if (ret != 0) - goto out; - cur_image = wimlib_get_num_images(w); - if (desc) { - ret = wimlib_set_image_descripton(w, cur_image, desc); - if (ret != 0) - goto out; - } - if (flags_element) { - ret = wimlib_set_image_flags(w, cur_image, flags_element); - if (ret != 0) - goto out; - } - ret = wimlib_overwrite(w, write_flags); -out: - wimlib_free(w); - return ret; -} /* Extract one image, or all images, from a WIM file into a directory. */ static int imagex_apply(int argc, const char **argv) @@ -585,32 +470,34 @@ out: return ret; } - -/* Create a WIM file from a directory. */ -static int imagex_capture(int argc, const char **argv) +static int imagex_capture_or_append(int argc, const char **argv) { int c; + int open_flags = WIMLIB_OPEN_FLAG_SHOW_PROGRESS; int add_image_flags = 0; int write_flags = WIMLIB_WRITE_FLAG_SHOW_PROGRESS; int compression_type = WIM_COMPRESSION_TYPE_XPRESS; - const char *flags_element = NULL; const char *dir; const char *wimfile; const char *name; const char *desc; + const char *flags_element = NULL; const char *config_file = NULL; - const char *config_str = NULL; + char *config_str = NULL; size_t config_len = 0; - WIMStruct *w; - int cur_image; + WIMStruct *w = NULL; int ret; + int cur_image; + char *default_name; + int cmd = strcmp(argv[0], "append") ? CAPTURE : APPEND; - for_opt(c, capture_options) { + for_opt(c, capture_or_append_options) { switch (c) { case 'b': add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_BOOT; break; case 'c': + open_flags |= WIMLIB_OPEN_FLAG_CHECK_INTEGRITY; write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY; break; case 'C': @@ -624,28 +511,31 @@ static int imagex_capture(int argc, const char **argv) case 'f': flags_element = optarg; break; - case 'v': - add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_VERBOSE; - write_flags |= WIMLIB_WRITE_FLAG_VERBOSE; - break; case 'L': add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE; break; + case 'v': + add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_VERBOSE; + break; default: - usage(CAPTURE); + usage(cmd); return -1; } } - argc -= optind; argv += optind; if (argc < 2 || argc > 4) { - usage(CAPTURE); + usage(cmd); return -1; } dir = argv[0]; wimfile = argv[1]; - name = (argc >= 3) ? argv[2] : dir; + + char dir_copy[strlen(dir) + 1]; + memcpy(dir_copy, dir, strlen(dir) + 1); + default_name = basename(dir_copy); + + name = (argc >= 3) ? argv[2] : default_name; desc = (argc >= 4) ? argv[3] : NULL; if (config_file) { @@ -654,9 +544,12 @@ static int imagex_capture(int argc, const char **argv) return -1; } - ret = wimlib_create_new_wim(compression_type, &w); + if (cmd == APPEND) + ret = wimlib_open_wim(wimfile, open_flags, &w); + else + ret = wimlib_create_new_wim(compression_type, &w); if (ret != 0) - return ret; + goto out; #ifdef WITH_NTFS_3G struct stat stbuf; @@ -675,18 +568,19 @@ static int imagex_capture(int argc, const char **argv) goto out_write; } } else { - if (errno != ENOENT) + if (errno != ENOENT) { imagex_error_with_errno("Failed to stat `%s'", dir); + ret = -1; + goto out; + } } #endif - ret = wimlib_add_image(w, dir, name, config_str, - config_len, add_image_flags); + ret = wimlib_add_image(w, dir, name, config_str, config_len, + add_image_flags); out_write: - if (ret != 0) { - imagex_error("Failed to add the image `%s'", dir); + if (ret != 0) goto out; - } cur_image = wimlib_get_num_images(w); if (desc) { ret = wimlib_set_image_descripton(w, cur_image, desc); @@ -698,12 +592,15 @@ out_write: if (ret != 0) goto out; } - - ret = wimlib_write(w, wimfile, WIM_ALL_IMAGES, write_flags); + if (cmd == APPEND) + ret = wimlib_overwrite(w, write_flags); + else + ret = wimlib_write(w, wimfile, WIM_ALL_IMAGES, write_flags); if (ret != 0) imagex_error("Failed to write the WIM file `%s'", wimfile); out: wimlib_free(w); + free(config_str); return ret; } @@ -851,6 +748,9 @@ static int imagex_export(int argc, const char **argv) int image; struct stat stbuf; bool wim_is_new; + const char *swm_glob = NULL; + WIMStruct **additional_swms = NULL; + unsigned num_additional_swms = 0; for_opt(c, export_options) { switch (c) { @@ -867,6 +767,9 @@ static int imagex_export(int argc, const char **argv) return -1; compression_type_specified = true; break; + case 'r': + swm_glob = optarg; + break; default: usage(EXPORT); return -1; @@ -883,7 +786,8 @@ static int imagex_export(int argc, const char **argv) dest_wimfile = argv[2]; dest_name = (argc >= 4) ? argv[3] : NULL; dest_desc = (argc >= 5) ? argv[4] : NULL; - ret = wimlib_open_wim(src_wimfile, open_flags, &src_w); + ret = wimlib_open_wim(src_wimfile, + open_flags | WIMLIB_OPEN_FLAG_SPLIT_OK, &src_w); if (ret != 0) return ret; @@ -896,11 +800,11 @@ static int imagex_export(int argc, const char **argv) if (!S_ISREG(stbuf.st_mode) && !S_ISLNK(stbuf.st_mode)) { imagex_error("`%s' is not a regular file", dest_wimfile); - goto done; + goto out; } ret = wimlib_open_wim(dest_wimfile, open_flags, &dest_w); if (ret != 0) - goto done; + goto out; if (compression_type_specified && compression_type != wimlib_get_compression_type(dest_w)) { @@ -908,7 +812,7 @@ static int imagex_export(int argc, const char **argv) "not the same as that used in the " "destination WIM"); ret = -1; - goto done; + goto out; } compression_type = wimlib_get_compression_type(dest_w); } else { @@ -917,23 +821,32 @@ static int imagex_export(int argc, const char **argv) if (errno == ENOENT) { ret = wimlib_create_new_wim(compression_type, &dest_w); if (ret != 0) - goto done; + goto out; } else { imagex_error_with_errno("Cannot stat file `%s'", dest_wimfile); - goto done; + goto out; } } image = wimlib_resolve_image(src_w, src_image_num_or_name); ret = verify_image_exists(image); if (ret != 0) - goto done; + goto out; + + if (swm_glob) { + ret = open_swms_from_glob(swm_glob, src_wimfile, open_flags, + &additional_swms, + &num_additional_swms); + if (ret != 0) + goto out; + } ret = wimlib_export_image(src_w, image, dest_w, dest_name, dest_desc, - export_flags); + export_flags, additional_swms, + num_additional_swms); if (ret != 0) - goto done; + goto out; if (wim_is_new) @@ -941,9 +854,12 @@ static int imagex_export(int argc, const char **argv) write_flags); else ret = wimlib_overwrite(dest_w, write_flags); -done: +out: wimlib_free(src_w); wimlib_free(dest_w); + if (additional_swms) + for (unsigned i = 0; i < num_additional_swms; i++) + wimlib_free(additional_swms[i]); return ret; } @@ -1125,12 +1041,6 @@ static int imagex_info(int argc, const char **argv) wimlib_print_available_images(w, image); if (metadata) { - if (total_parts != 1 && part_number != 1) { - imagex_error("Select part 1 of this %d-part WIM " - "to see the image metadata", - total_parts); - return WIMLIB_ERR_SPLIT_UNSUPPORTED; - } ret = wimlib_print_metadata(w, image); if (ret != 0) goto done; @@ -1419,9 +1329,9 @@ struct imagex_command { p != &imagex_commands[ARRAY_LEN(imagex_commands)]; p++) static struct imagex_command imagex_commands[] = { - {"append", imagex_append, APPEND}, + {"append", imagex_capture_or_append, APPEND}, {"apply", imagex_apply, APPLY}, - {"capture", imagex_capture, CAPTURE}, + {"capture", imagex_capture_or_append, CAPTURE}, {"delete", imagex_delete, DELETE}, {"dir", imagex_dir, DIR}, {"export", imagex_export, EXPORT},