]> wimlib.net Git - wimlib/commitdiff
Don't exclude out-of-tree absolute symlinks in reparse point fix mode
authorEric Biggers <ebiggers3@gmail.com>
Wed, 11 Jun 2014 01:55:10 +0000 (20:55 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Wed, 11 Jun 2014 01:58:31 +0000 (20:58 -0500)
Excluding such links may not be the expected behavior.  In addition,
Microsoft's documentation for ImageX seems to be incorrect when it states
that ImageX excludes such links.  Actually, it does not.  So, for the
sake of consistency and also doing something that may more sense anyway,
just retain such links, but leave their targets as-is.

NEWS
doc/man1/imagex-capture.1.in
include/wimlib.h
programs/imagex.c
src/capture_common.c
src/unix_capture.c
src/win32_apply.c
src/win32_capture.c
tests/test-imagex-capture_and_apply
tests/win32-test-imagex-capture_and_apply.bat

diff --git a/NEWS b/NEWS
index b5dd7dae72742272df1d0dbc28f636f0f5a511d2..45a2e9789f9eb5fe86b2e60f687019857e7d498f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,10 @@ Version 1.7.0-BETA:
        nondirectory files by default.  Use the --no-replace option to get the
        old behavior.
 
+       In reparse-point fixup mode (the default for capture), symbolic links
+       and junctions that point outside the tree being captured are no longer
+       excluded from capture.
+
        Added support for "WIMBoot" capture and extraction.  See the
        documentation for the new '--wimboot' option to wimcapture and wimapply
        for more information.
index 2d23ce6fce73db51c4732301032c32199c7cbef2..465b01b092698f0342bab9aca16f2ba29877429c 100644 (file)
@@ -371,10 +371,8 @@ although the Administrator should have permission to read everything anyway.
 Set whether to fix targets of absolute symbolic links (reparse points in Windows
 terminology) or not.  When enabled (\fB--rpfix\fR), absolute symbolic links that
 point inside the directory tree being captured will be adjusted to be absolute
-relative to the root of the directory tree being captured.  In addition,
-absolute symbolic links that point outside the directory tree being captured
-will be ignored and not be captured at all.  When disabled (\fB--norpfix\fR),
-absolute symbolic links will be captured exactly as is.
+relative to the root of the directory tree being captured.  When disabled
+(\fB--norpfix\fR), absolute symbolic links will be captured exactly as is.
 .IP ""
 The default behavior for \fB@IMAGEX_PROGNAME@ capture\fR is equivalent to
 \fB--rpfix\fR.  The default behavior for \fB@IMAGEX_PROGNAME@ append\fR will be
index 7d39ba646c922230c6419045c515f0aecc8423ef..5e49f92eaec78c12c8bbcf970ae7bde807d072ff 100644 (file)
@@ -716,14 +716,6 @@ union wimlib_progress_info {
                         * unsupported (e.g. an encrypted or device file).  */
                        WIMLIB_SCAN_DENTRY_UNSUPPORTED,
 
-                       /** The file is an absolute symbolic link or junction
-                        * point and it is being excluded from capture because
-                        * it points outside of the capture directory and
-                        * reparse-point fixups are enabled.  (Reparse point
-                        * fixups can be disabled by using the flag
-                        * ::WIMLIB_ADD_FLAG_NORPFIX.)  */
-                       WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK,
-
                        /** The file is an absolute symbolic link or junction
                         * that points into the capture directory, and
                         * reparse-point fixups are enabled, so its target is
@@ -731,6 +723,12 @@ union wimlib_progress_info {
                         * disabled with the flag ::WIMLIB_ADD_FLAG_NORPFIX.)
                         */
                        WIMLIB_SCAN_DENTRY_FIXED_SYMLINK,
+
+                       /** Reparse-point fixups are enabled, but the file is an
+                        * absolute symbolic link or junction that does
+                        * <b>not</b> point into the capture directory, so its
+                        * target is <b>not</b> being adjusted.  */
+                       WIMLIB_SCAN_DENTRY_NOT_FIXED_SYMLINK,
                } status;
 
                union {
@@ -740,9 +738,9 @@ union wimlib_progress_info {
                        const wimlib_tchar *wim_target_path;
 
                        /** For ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY and a status
-                        * of @p WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK or @p
-                        * WIMLIB_SCAN_DENTRY_FIXED_SYMLINK, this is the target
-                        * of the absolute symbolic link or junction.  */
+                        * of @p WIMLIB_SCAN_DENTRY_FIXED_SYMLINK or @p
+                        * WIMLIB_SCAN_DENTRY_NOT_FIXED_SYMLINK, this is the
+                        * target of the absolute symbolic link or junction.  */
                        const wimlib_tchar *symlink_target;
                };
 
@@ -1378,8 +1376,7 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour
 /** Reparse-point fixups:  Modify absolute symbolic links (or junction points,
  * in the case of Windows) that point inside the directory being captured to
  * instead be absolute relative to the directory being captured, rather than the
- * current root; also exclude absolute symbolic links that point outside the
- * directory tree being captured.
+ * current root.
  *
  * Without this flag, the default is to do this if WIM_HDR_FLAG_RP_FIX is set in
  * the WIM header or if this is the first image being added.
index 67a9723928a599d89036e5a2255b1fd55baa05a8..81f2f9f6a7b9aa392488e8e930dd6657dbed5133 100644 (file)
@@ -1078,24 +1078,13 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                        imagex_printf(T("\nWARNING: Excluding unsupported file or directory\n"
                                        "         \"%"TS"\" from capture\n"), info->scan.cur_path);
                        break;
-               case WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK:
-                       imagex_printf(T("\nWARNING: Ignoring absolute symbolic link "
-                                       "with out-of-tree target:\n"
-                                       "           \"%"TS"\" => \"%"TS"\"\n"
-                                       "           (Use --norpfix to capture "
-                                       "absolute symbolic links as-is)\n"),
-                                       info->scan.cur_path, info->scan.symlink_target);
-                       break;
                case WIMLIB_SCAN_DENTRY_FIXED_SYMLINK:
                        /* Symlink fixups are enabled by default.  This is
                         * mainly intended for Windows, which for some reason
                         * uses absolute junctions (with drive letters!) in the
                         * default installation.  On UNIX-like systems, warn the
                         * user when fixing the target of an absolute symbolic
-                        * link, so they know to disable this if they want.
-                        * (Although, more likely they will get the warning
-                        * about an absolute symbolic link with an out-of-tree
-                        * target first.)  */
+                        * link, so they know to disable this if they want.  */
                #ifndef __WIN32__
                        imagex_printf(T("\nWARNING: Adjusted target of "
                                        "absolute symbolic link \"%"TS"\"\n"
@@ -1104,6 +1093,8 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                                        info->scan.cur_path);
                #endif
                        break;
+               default:
+                       break;
                }
                break;
        case WIMLIB_PROGRESS_MSG_SCAN_END:
index be7c8983d0f443a3d48f954f72ded06f2a8b3d1b..7d7315a8e6ffd1480a92e4b3888db0e35a9de1b6 100644 (file)
@@ -62,8 +62,8 @@ do_capture_progress(struct add_image_params *params, int status,
                        return 0;
        case WIMLIB_SCAN_DENTRY_UNSUPPORTED:
        case WIMLIB_SCAN_DENTRY_EXCLUDED:
-       case WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK:
        case WIMLIB_SCAN_DENTRY_FIXED_SYMLINK:
+       case WIMLIB_SCAN_DENTRY_NOT_FIXED_SYMLINK:
                if (!(params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE))
                        return 0;
        }
index 8b1e793413c7faf3f56b96b77c50ffbfca56d8cd..15e1d153923a0bedfee0603ee412b89552f2d44a 100644 (file)
@@ -251,8 +251,7 @@ unix_fixup_abslink(char *dest, u64 ino, u64 dev)
 }
 
 static int
-unix_scan_symlink(struct wim_dentry **root_p, const char *full_path,
-                 int dirfd, const char *relpath,
+unix_scan_symlink(const char *full_path, int dirfd, const char *relpath,
                  struct wim_inode *inode, struct add_image_params *params)
 {
        char deref_name_buf[4096];
@@ -281,31 +280,33 @@ unix_scan_symlink(struct wim_dentry **root_p, const char *full_path,
        if ((params->add_flags & WIMLIB_ADD_FLAG_RPFIX) &&
             dest[0] == '/')
        {
+               char *fixed_dest;
+
                /* RPFIX (reparse point fixup) mode:  Change target of absolute
                 * symbolic link to be "absolute" relative to the tree being
                 * captured.  */
-               dest = unix_fixup_abslink(dest,
-                                         params->capture_root_ino,
-                                         params->capture_root_dev);
+               fixed_dest = unix_fixup_abslink(dest,
+                                               params->capture_root_ino,
+                                               params->capture_root_dev);
                params->progress.scan.cur_path = full_path;
                params->progress.scan.symlink_target = deref_name_buf;
-               if (dest) {
-                       /* Successfully fixed the link target.  */
+               if (fixed_dest) {
+                       /* Link points inside the tree being captured, so it was
+                        * fixed.  */
                        inode->i_not_rpfixed = 0;
+                       dest = fixed_dest;
                        ret = do_capture_progress(params,
                                                  WIMLIB_SCAN_DENTRY_FIXED_SYMLINK,
                                                  NULL);
-                       if (ret)
-                               return ret;
                } else {
-                       /* Link points outside of the tree being captured.
-                        * Exclude it.  */
-                       free_dentry(*root_p);
-                       *root_p = NULL;
-                       return do_capture_progress(params,
-                                                  WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK,
-                                                  NULL);
+                       /* Link points outside the tree being captured, so it
+                        * was not fixed.  */
+                       ret = do_capture_progress(params,
+                                                 WIMLIB_SCAN_DENTRY_NOT_FIXED_SYMLINK,
+                                                 NULL);
                }
+               if (ret)
+                       return ret;
        }
        ret = wim_inode_set_symlink(inode, dest, params->lookup_table);
        if (ret)
@@ -422,10 +423,8 @@ unix_build_dentry_tree_recursive(struct wim_dentry **tree_ret,
                ret = unix_scan_directory(tree, full_path, full_path_len,
                                          dirfd, relpath, params);
        } else if (S_ISLNK(stbuf.st_mode)) {
-               ret = unix_scan_symlink(&tree, full_path, dirfd, relpath,
+               ret = unix_scan_symlink(full_path, dirfd, relpath,
                                        inode, params);
-               if (!tree)
-                       goto out;
        }
 
        if (ret)
index 280f7f541f46f8e3ceae71693a2711b07afec938..842d588e93d8f2dabc2205cac91d9f417ef97a37 100644 (file)
@@ -1476,7 +1476,7 @@ skip_nt_toplevel_component(const wchar_t *path, size_t path_nchars)
  * The path has an explicit length and is not necessarily null terminated.
  *
  * If the path just something like \??\e: then the returned pointer will point
- * just past the colon; in this case the length of the result will be 0
+ * just past the colon.  In this case the length of the result will be 0
  * characters.  */
 static const wchar_t *
 get_device_relative_path(const wchar_t *path, size_t path_nchars)
index bc5422e85c7feaeebfcd2989aaea0f93b6fdb802..30dc3ef51f7a836cf9a6b05c09ba491821496fae 100644 (file)
@@ -453,9 +453,6 @@ out_free_buf:
 
 /* Reparse point fixup status code  */
 enum rp_status {
-       /* Reparse point should be excluded from capture  */
-       RP_EXCLUDED     = -0,
-
        /* Reparse point will be captured literally (no fixup)  */
        RP_NOT_FIXED    = -1,
 
@@ -650,14 +647,13 @@ winnt_try_rpfix(u8 *rpbuf, u16 *rpbuflen_p,
                                                    capture_root_ino,
                                                    capture_root_dev);
        if (!rel_target) {
-               /* Target points outside of the tree being captured.  Exclude
-                * this reparse point from the capture (but inform the library
-                * user).  */
+               /* Target points outside of the tree being captured.  Don't
+                * adjust it.  */
                ret = winnt_rpfix_progress(params, path, &rpdata,
-                                          WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK);
+                                          WIMLIB_SCAN_DENTRY_NOT_FIXED_SYMLINK);
                if (ret)
                        return ret;
-               return RP_EXCLUDED;
+               return RP_NOT_FIXED;
        }
 
        if (rel_target == rpdata.substitute_name) {
@@ -722,7 +718,7 @@ winnt_try_rpfix(u8 *rpbuf, u16 *rpbuflen_p,
  *     On success, the length of the reparse point buffer in bytes is written
  *     to this location.
  *
- * On success, returns a nonpositive `enum rp_status' value.
+ * On success, returns a negative `enum rp_status' value.
  * On failure, returns a positive error code.
  */
 static int
@@ -1201,9 +1197,6 @@ winnt_build_dentry_tree_recursive(struct wim_dentry **root_ret,
                ret = winnt_get_reparse_data(h, full_path, params,
                                             rpbuf, &rpbuflen);
                switch (ret) {
-               case RP_EXCLUDED:
-                       ret = 0;
-                       goto out;
                case RP_FIXED:
                        not_rpfixed = 0;
                        break;
index 105d0f3955bc22d4be247a47786a8454bf68dd05..672c8ae37d37943216e687fb0568724b6b158922 100755 (executable)
@@ -170,9 +170,9 @@ if [[ `readlink out.dir/absrootlink` != "/" ]] ||
        error "imagex capture --rpfix failed to fix absolute link to capture root"
 fi
 
-if [[ -e out.dir/absnonexistent ]] ||
-   [[ -e out.dir/absoutoftree ]]; then
-       error "imagex capture --rpfix failed to exclude out of tree absolute links"
+if [[ ! -L out.dir/absnonexistent ]] ||
+   [[ ! -L out.dir/absoutoftree ]]; then
+       error "imagex capture --rpfix failed to also capture out of tree absolute links"
 fi
 if [[ `readlink out.dir/relalink` != "file" ]]; then
        error "imagex capture --rpfix failed to capture relative symlink"
index 01e3f32099894b8a8ddeb90774cceecf6b37ef7a..2ce8febb0876289f10054a37085554a36e3b1c2a 100644 (file)
@@ -330,17 +330,6 @@ del tmp1 tmp2
 md in.dir\r
 cd in.dir\r
 \r
-echo Testing rpfix exclude\r
-mklink otherlink c:\some\other\directory > nul\r
-cd ..\r
-%WIMLIB_IMAGEX% capture in.dir test.wim > nul\r
-%WIMLIB_IMAGEX% apply test.wim out.dir > nul\r
-rd out.dir\r
-if %errorlevel% neq 0 exit /b %errorlevel%\r
-rd /s /q in.dir\r
-md in.dir\r
-cd in.dir\r
-\r
 echo Testing rpfix relative\r
 echo 1 > file\r
 mklink relink file > nul\r