X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=programs%2Fimagex.c;h=fe7f3be9866de20ee66888a4c6ab3e89f59bad0f;hp=1fce776bcd5b1684cfd1174768a858496ba7d8cd;hb=1dde5fb0d809f2f5e032e4d5241d1cb15ff3eb65;hpb=f7d48eea9e1a6a9620ee7d8e883a6505939c7777 diff --git a/programs/imagex.c b/programs/imagex.c index 1fce776b..fe7f3be9 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -80,23 +80,27 @@ static const char *path_basename(const char *path) static const char *usage_strings[] = { [APPEND] = -" imagex append DIRECTORY WIMFILE [\"IMAGE_NAME\"] [\"DESCRIPTION\"] [--boot]\n" -" [--check] [--flags EDITIONID] [--dereference]\n", +" imagex append (DIRECTORY | NTFS_VOLUME) WIMFILE [IMAGE_NAME]\n" +" [DESCRIPTION] [--boot] [--check] [--flags EDITION_ID]\n" +" [--verbose] [--dereference] [--config=FILE]\n", [APPLY] = -" imagex apply WIMFILE [IMAGE_NUM | IMAGE_NAME | all] DIRECTORY [--check]\n" -" [--hardlink] [--symlink] [--verbose]\n", +" imagex apply WIMFILE [IMAGE_NUM | IMAGE_NAME | all]\n" +" (DIRECTORY | NTFS_VOLUME) [--check] [--hardlink]\n" +" [--symlink] [--verbose]\n", [CAPTURE] = -" imagex capture DIRECTORY WIMFILE [\"IMAGE_NAME\"] [\"DESCRIPTION\"]\n" -" l [--boot] [--check] [--compress[=TYPE]]\n" -" [--flags \"EditionID\"] [--verbose] [--dereference]\n", +" imagex capture (DIRECTORY | NTFS_VOLUME) WIMFILE [IMAGE_NAME]\n" +" [DESCRIPTION] [--boot] [--check] [--compress=TYPE]\n" +" [--flags EDITION_ID] [--verbose] [--dereference]\n" +" [--config=FILE]\n", [DELETE] = " imagex delete WIMFILE (IMAGE_NUM | IMAGE_NAME | all) [--check]\n", [DIR] = -" imagex dir WIMFILE (IMAGE_NUM | IMAGE_NAME | \"all\")\n", +" imagex dir WIMFILE (IMAGE_NUM | IMAGE_NAME | all)\n", [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", +" DEST_WIMFILE [DEST_IMAGE_NAME]\n" +" [DEST_IMAGE_DESCRIPTION] [--boot] [--check]\n" +" [--compress=TYPE]\n", [INFO] = " imagex info WIMFILE [IMAGE_NUM | IMAGE_NAME] [NEW_NAME]\n" " [NEW_DESC] [--boot] [--check] [--header] [--lookup-table]\n" @@ -105,12 +109,12 @@ static const char *usage_strings[] = { " imagex join [--check] WIMFILE SPLIT_WIM...\n", [MOUNT] = " imagex mount WIMFILE (IMAGE_NUM | IMAGE_NAME) DIRECTORY\n" -" [--check] [--debug] [--stream-interface=INTERFACE]\n", +" [--check] [--debug] [--streams-interface=INTERFACE]\n", [MOUNTRW] = " imagex mountrw WIMFILE [IMAGE_NUM | IMAGE_NAME] DIRECTORY\n" -" [--check] [--debug] [--stream-interface=INTERFACE]\n", +" [--check] [--debug] [--streams-interface=INTERFACE]\n", [SPLIT] = -" imagex split WIMFILE SPLIT_WIMFILE PART_SIZE [--check]\n", +" imagex split WIMFILE SPLIT_WIMFILE PART_SIZE_MB [--check]\n", [UNMOUNT] = " imagex unmount DIRECTORY [--commit] [--check]\n", }; @@ -122,10 +126,12 @@ static const struct option common_options[] = { }; static const struct option append_options[] = { - {"boot", no_argument, NULL, 'b'}, - {"check", no_argument, NULL, 'c'}, - {"flags", required_argument, NULL, 'f'}, - {"dereference", no_argument, NULL, 'L'}, + {"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[] = { @@ -136,12 +142,13 @@ static const struct option apply_options[] = { {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'}, - {"flags", required_argument, NULL, 'f'}, - {"verbose", no_argument, NULL,'v'}, - {"dereference", no_argument, NULL, 'L'}, + {"boot", no_argument, NULL, 'b'}, + {"check", no_argument, NULL, 'c'}, + {"compress", required_argument, NULL, 'x'}, + {"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 delete_options[] = { @@ -150,20 +157,20 @@ static const struct option delete_options[] = { }; static const struct option export_options[] = { - {"boot", no_argument, NULL, 'b'}, - {"check", no_argument , NULL, 'c'}, - {"compress", optional_argument, NULL, 'x'}, + {"boot", no_argument, NULL, 'b'}, + {"check", no_argument, NULL, 'c'}, + {"compress", required_argument, NULL, 'x'}, {NULL, 0, NULL, 0}, }; static const struct option info_options[] = { {"boot", no_argument, NULL, 'b'}, {"check", no_argument, NULL, 'c'}, + {"extract-xml", required_argument, NULL, 'X'}, {"header", no_argument, NULL, 'h'}, {"lookup-table", no_argument, NULL, 'l'}, - {"xml", no_argument, NULL, 'x'}, - {"extract-xml", required_argument, NULL, 'X'}, {"metadata", no_argument, NULL, 'm'}, + {"xml", no_argument, NULL, 'x'}, {NULL, 0, NULL, 0}, }; @@ -175,7 +182,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'}, + {"streams-interface", required_argument, NULL, 's'}, {NULL, 0, NULL, 0}, }; @@ -277,8 +284,6 @@ static int verify_image_exists_and_is_single(int image) static int get_compression_type(const char *optarg) { - if (!optarg) - return WIM_COMPRESSION_TYPE_XPRESS; if (strcasecmp(optarg, "maximum") == 0 || strcasecmp(optarg, "lzx") == 0) return WIM_COMPRESSION_TYPE_LZX; else if (strcasecmp(optarg, "fast") == 0 || strcasecmp(optarg, "xpress") == 0) @@ -292,6 +297,45 @@ static int get_compression_type(const char *optarg) } } +static const char *file_get_contents(const char *filename, size_t *len_ret) +{ + struct stat stbuf; + char *buf; + size_t len; + FILE *fp; + + if (stat(filename, &stbuf) != 0) { + imagex_error_with_errno("Failed to stat the file `%s'", filename); + return NULL; + } + len = stbuf.st_size; + + fp = fopen(filename, "rb"); + if (!fp) { + imagex_error_with_errno("Failed to open the file `%s'", filename); + return NULL; + } + + buf = malloc(len); + if (!buf) { + imagex_error("Failed to allocate buffer of %zu bytes to hold " + "contents of file `%s'", len, filename); + goto out_fclose; + } + if (fread(buf, 1, len, fp) != len) { + imagex_error_with_errno("Failed to read %lu bytes from the " + "file `%s'", len, filename); + goto out_free_buf; + } + *len_ret = len; + return buf; +out_free_buf: + free(buf); +out_fclose: + fclose(fp); + return NULL; +} + static int imagex_append(int argc, const char **argv) { int c; @@ -303,8 +347,12 @@ static int imagex_append(int argc, const char **argv) 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) { @@ -315,12 +363,18 @@ 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_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; @@ -337,16 +391,56 @@ static int imagex_append(int argc, const char **argv) 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; - ret = wimlib_add_image(w, dir, name, desc, - flags_element, add_image_flags); +#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 done; + 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); -done: +out: wimlib_free(w); return ret; } @@ -457,7 +551,11 @@ static int imagex_capture(int argc, const char **argv) 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 cur_image; int ret; for_opt(c, capture_options) { @@ -468,6 +566,9 @@ static int imagex_capture(int argc, const char **argv) case 'c': write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY; break; + case 'C': + config_file = optarg; + break; case 'x': compression_type = get_compression_type(optarg); if (compression_type == WIM_COMPRESSION_TYPE_INVALID) @@ -500,21 +601,61 @@ static int imagex_capture(int argc, const char **argv) name = (argc >= 3) ? argv[2] : 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_create_new_wim(compression_type, &w); if (ret != 0) return ret; - ret = wimlib_add_image(w, dir, name, desc, flags_element, - add_image_flags); +#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) { imagex_error("Failed to add the image `%s'", dir); - goto done; + 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_write(w, wimfile, WIM_ALL_IMAGES, write_flags); if (ret != 0) imagex_error("Failed to write the WIM file `%s'", wimfile); -done: +out: wimlib_free(w); return ret; }