From 150fd376ac944f0fdc22c0df7beaa8dbd076061c Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 20 Aug 2012 22:35:55 -0500 Subject: [PATCH 1/1] wimlib_apply_image_to_ntfs_volume() API function --- programs/imagex.c | 107 +++++----------------------------------------- src/extract.c | 51 +++++++++++++--------- src/wimlib.h | 5 --- 3 files changed, 42 insertions(+), 121 deletions(-) diff --git a/programs/imagex.c b/programs/imagex.c index 45d7dd1e..a9bdab02 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -133,7 +133,6 @@ static const struct option apply_options[] = { {"hardlink", no_argument, NULL, 'h'}, {"symlink", no_argument, NULL, 's'}, {"verbose", no_argument, NULL, 'v'}, - {"mkntfs-args", required_argument, NULL, 'm'}, {NULL, 0, NULL, 0}, }; static const struct option capture_options[] = { @@ -364,10 +363,8 @@ static int imagex_apply(int argc, const char **argv) const char *wimfile; const char *dir; const char *image_num_or_name; - const char *mkntfs_args = ""; int extract_flags = 0; - for_opt(c, apply_options) { switch (c) { case 'c': @@ -382,9 +379,6 @@ static int imagex_apply(int argc, const char **argv) case 'v': extract_flags |= WIMLIB_EXTRACT_FLAG_VERBOSE; break; - case 'm': - mkntfs_args = optarg; - break; default: usage(APPLY); return -1; @@ -406,11 +400,6 @@ static int imagex_apply(int argc, const char **argv) dir = argv[2]; } -#ifdef WITH_NTFS_3G - char tmpdir[strlen(dir) + 50]; - tmpdir[0] = '\0'; -#endif - ret = wimlib_open_wim(wimfile, open_flags, &w); if (ret != 0) goto out; @@ -430,102 +419,28 @@ static int imagex_apply(int argc, const char **argv) } #ifdef WITH_NTFS_3G - /* Check to see if a block device file or regular file was specified. - * If so, try to create a NTFS filesystem on it, mount it on a temporary - * directory, and replace @dir with the name of the temporary directory - * so that we extract the files to the NTFS filesystem. */ struct stat stbuf; ret = stat(dir, &stbuf); - if (ret != 0) - imagex_error_with_errno("Failed to stat `%s'", dir); - if (S_ISBLK(stbuf.st_mode) || S_ISREG(stbuf.st_mode)) { - extract_flags |= WIMLIB_EXTRACT_FLAG_NTFS; - - const char *dev = dir; - printf("Making NTFS filesystem on `%s'\n", dev); - - char mkntfs_cmdline[sizeof("mkntfs ") + strlen(mkntfs_args) + - sizeof(" ") + strlen(dev)]; - sprintf(mkntfs_cmdline, "mkntfs %s %s", mkntfs_args, dev); - puts(mkntfs_cmdline); - ret = system(mkntfs_cmdline); - if (ret == -1) { - imagex_error_with_errno("Failed to execute the " - "`mkntfs' program"); - return -1; - } else if (ret > 0) { - imagex_error("`mkntfs' exited with failure status"); - imagex_error("Note: You can pass additional arguments " - "to `mkntfs' using the --mkntfs-args " - "argument"); - return -1; - } - sprintf(tmpdir, "/tmp/imagex-%d-ntfsmount-%s-XXXXXX", - getpid(), dev); - dir = mkdtemp(tmpdir); - if (!dir) { - imagex_error_with_errno("Failed to create " - "temporary directory " - "`%s'", tmpdir); - } - char ntfs_3g_cmdline[sizeof("ntfs-3g ") + strlen(dev) + - sizeof(" ") + strlen(dir)]; - sprintf(ntfs_3g_cmdline, "ntfs-3g %s %s", dev, dir); - puts(ntfs_3g_cmdline); - ret = system(ntfs_3g_cmdline); - if (ret == -1) { - imagex_error_with_errno("Failed to execute the " - "`ntfs-3g' program"); - ret = -1; - goto out; - } else if (ret > 0) { - imagex_error("`ntfs-3g' exited with failure status"); - ret = -1; + if (ret == 0) { + if (S_ISBLK(stbuf.st_mode) || S_ISREG(stbuf.st_mode)) { + const char *ntfs_device = dir; + printf("Applying image %d of `%s' to NTFS filesystem on `%s'\n", + image, wimfile, ntfs_device); + ret = wimlib_apply_image_to_ntfs_volume(w, image, + ntfs_device, + extract_flags); goto out; } - printf("Applying image %d of `%s' to NTFS filesystem on `%s'\n", - image, wimfile, dev); + } else { + if (errno != -ENOENT) + imagex_error_with_errno("Failed to stat `%s'", dir); } #endif ret = wimlib_extract_image(w, image, dir, extract_flags); out: wimlib_free(w); -#ifdef WITH_NTFS_3G - if (tmpdir[0] != '\0') { - /* Unmount and remove the NTFS-3g mounted directory */ - - int pid = fork(); - int status; - if (pid == -1) { - imagex_error_with_errno("Failed to fork()"); - return -1; - } - if (pid == 0) { - execlp("fusermount", "fusermount", "-u", dir, NULL); - imagex_error_with_errno("Failed to execute `fusermount'"); - return -1; - } - - if (waitpid(pid, &status, 0) == -1) { - imagex_error_with_errno("Failed to wait for " - "fusermount process to " - "terminate"); - return -1; - } - - if (status != 0) { - imagex_error("fusermount exited with status %d", - status); - return -1; - } - if (rmdir(tmpdir) != 0) { - imagex_error_with_errno("Failed to remove temporary " - "directory `%s'", tmpdir); - } - } -#endif return ret; } diff --git a/src/extract.c b/src/extract.c index 4a9b0399..da637d2e 100644 --- a/src/extract.c +++ b/src/extract.c @@ -425,7 +425,6 @@ done: WIMLIBAPI int wimlib_extract_image(WIMStruct *w, int image, const char *output_dir, int flags) { - if (!output_dir) return WIMLIB_ERR_INVALID_PARAM; @@ -433,9 +432,6 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w, int image, == (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) return WIMLIB_ERR_INVALID_PARAM; - - /*ntfs_initialize_file_security(*/ - for_lookup_table_entry(w->lookup_table, zero_out_refcnts, NULL); if (image == WIM_ALL_IMAGES) { @@ -451,21 +447,36 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w, int image, WIMLIBAPI int wimlib_apply_image_to_ntfs_volume(WIMStruct *w, int image, const char *device, int flags) { - if ((flags & WIMLIB_EXTRACT_FLAG_NTFS)) { - #ifndef WITH_NTFS_3G - ERROR("wimlib was compiled without support for NTFS-3g, so"); - ERROR("we cannot extract a WIM image while preserving NTFS-"); - ERROR("specific information"); - #endif - if (flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) - return WIMLIB_ERR_INVALID_PARAM; - if (getuid() != 0) { - ERROR("We are not root, but NTFS-3g requires root privileges to set arbitrary"); - ERROR("security data on the NTFS filesystem. Please run this program as root"); - ERROR("if you want to extract a WIM image while preserving NTFS-specific"); - ERROR("information."); - - return WIMLIB_ERR_NOT_ROOT; - } +#ifdef WITH_NTFS_3G + int ret; + + if (!device) + return WIMLIB_ERR_INVALID_PARAM; + if (image == WIM_ALL_IMAGES) { + ERROR("Can only apply a single image when applying " + "directly to a NTFS volume"); + return WIMLIB_ERR_INVALID_PARAM; + } + if (flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) { + ERROR("Cannot specifcy symlink or hardlink flags when applying "); + ERROR("directly to a NTFS volume"); + return WIMLIB_ERR_INVALID_PARAM; + } + ret = wimlib_select_image(w, image); + if (ret != 0) + return ret; + + if (getuid() != 0) { + ERROR("We are not root, but NTFS-3g requires root privileges to set arbitrary"); + ERROR("security data on the NTFS filesystem. Please run this program as root"); + ERROR("if you want to extract a WIM image while preserving NTFS-specific"); + ERROR("information."); + + return WIMLIB_ERR_NOT_ROOT; } +#else /* WITH_NTFS_3G */ + ERROR("wimlib was compiled without support for NTFS-3g, so"); + ERROR("we cannot apply a WIM image directly to a NTFS volume"); + return WIMLIB_ERR_UNSUPPORTED; +#endif /* !WITH_NTFS_3G */ } diff --git a/src/wimlib.h b/src/wimlib.h index 7fff0549..ba787c32 100644 --- a/src/wimlib.h +++ b/src/wimlib.h @@ -299,11 +299,6 @@ enum wim_compression_type { /** When identical files are extracted from the WIM, symlink them together. */ #define WIMLIB_EXTRACT_FLAG_SYMLINK 0x00000002 -/** Apply NTFS-specific information when applying the WIM image. This flag can - * only be specified if the output directory is on a NTFS filesystem mounted - * with NTFS-3g, and wimlib was compiled with support for NTFS-3g */ -#define WIMLIB_EXTRACT_FLAG_NTFS 0x00000004 - /** Print the name of each file as it is extracted from the WIM image. */ #define WIMLIB_EXTRACT_FLAG_VERBOSE 0x00000008 -- 2.43.0