]> wimlib.net Git - wimlib/blobdiff - src/reparse.c
win32_common.c: Remove duplicate declaration of func_NtOpenFile
[wimlib] / src / reparse.c
index cbb3a08c11aaae2b3fc115cfa51c2cd102df3117..28976927c0abdbeeda87f954cef5f35e748cd877 100644 (file)
 #include "wimlib/assert.h"
 #include "wimlib/compiler.h"
 #include "wimlib/endianness.h"
-#include "wimlib/dentry.h"
 #include "wimlib/encoding.h"
 #include "wimlib/error.h"
+#include "wimlib/inode.h"
 #include "wimlib/lookup_table.h"
 #include "wimlib/reparse.h"
 #include "wimlib/resource.h"
 
-#ifdef __WIN32__
-#  include "wimlib/win32.h" /* for win32_get_file_and_vol_ids() */
-#endif
-
 #ifdef HAVE_ALLOCA_H
 #  include <alloca.h>
 #endif
@@ -68,7 +64,7 @@ struct reparse_buffer_disk {
 
 static const utf16lechar volume_junction_prefix[11] = {
        cpu_to_le16('\\'),
-       cpu_to_le16('\\'),
+       cpu_to_le16('?'),
        cpu_to_le16('?'),
        cpu_to_le16('\\'),
        cpu_to_le16('V'),
@@ -299,7 +295,7 @@ wim_inode_get_reparse_data(const struct wim_inode * restrict inode,
        rpdatalen = lte->size;
 
        /* Read the data from the WIM file */
-       ret = read_full_resource_into_buf(lte, rpbuf + 8);
+       ret = read_full_stream_into_buf(lte, rpbuf + 8);
        if (ret)
                return ret;
 
@@ -321,15 +317,36 @@ wim_inode_get_reparse_data(const struct wim_inode * restrict inode,
 }
 
 /* UNIX version of getting and setting the data in reparse points */
-#if !defined(__WIN32__)
+#ifndef __WIN32__
 
-/* Get the UNIX symlink target from a WIM inode.  The inode may be either a
- * "real" symlink (reparse tag WIM_IO_REPARSE_TAG_SYMLINK), or it may be a
- * junction point (reparse tag WIM_IO_REPARSE_TAG_MOUNT_POINT).
+/*
+ * Get the UNIX-style symlink target from the WIM inode for a reparse point.
+ * Specifically, this translates the target from UTF-16 to the current multibyte
+ * encoding, strips the drive prefix if present, and replaces backslashes with
+ * forward slashes.
+ *
+ * @inode
+ *     The inode to read the symlink from.  It must be a reparse point with
+ *     tag WIM_IO_REPARSE_TAG_SYMLINK (a real symlink) or
+ *     WIM_IO_REPARSE_TAG_MOUNT_POINT (a mount point or junction point).
+ *
+ * @buf
+ *     Buffer into which to place the link target.
+ *
+ * @bufsize
+ *     Available space in @buf, in bytes.
  *
- * This has similar semantics to the UNIX readlink() function, except the path
- * argument is swapped out with the `struct wim_inode' for a reparse point, and
- * on failure a negated error code is returned rather than -1 with errno set.  */
+ * @lte_override
+ *     If not NULL, the stream from which to read the reparse data.  Otherwise,
+ *     the reparse data will be read from the unnamed stream of @inode.
+ *
+ * If the entire symbolic link target was placed in the buffer, returns the
+ * number of bytes written.  The resulting string is not null-terminated.  If
+ * the symbolic link target was too large to be placed in the buffer, the first
+ * @bufsize bytes of it are placed in the buffer and
+ * -ENAMETOOLONG is returned.  Otherwise, a negative errno value indicating
+ *  another error is returned.
+ */
 ssize_t
 wim_inode_readlink(const struct wim_inode * restrict inode,
                   char * restrict buf, size_t bufsize,
@@ -502,95 +519,4 @@ wim_inode_set_symlink(struct wim_inode *inode,
        return ret;
 }
 
-#include <sys/stat.h>
-
-static int
-unix_get_ino_and_dev(const char *path, u64 *ino_ret, u64 *dev_ret)
-{
-       struct stat stbuf;
-       if (stat(path, &stbuf)) {
-               if (errno != ENOENT)
-                       WARNING_WITH_ERRNO("Failed to stat \"%s\"", path);
-               /* Treat as a link pointing outside the capture root (it
-                * most likely is). */
-               return WIMLIB_ERR_STAT;
-       } else {
-               *ino_ret = stbuf.st_ino;
-               *dev_ret = stbuf.st_dev;
-               return 0;
-       }
-}
-
-#endif /* !defined(__WIN32__) */
-
-/* is_rp_path_separator() - characters treated as path separators in absolute
- * symbolic link targets */
-
-#ifdef __WIN32__
-#  define is_rp_path_separator(c) ((c) == L'\\' || (c) == L'/')
-#  define os_get_ino_and_dev win32_get_file_and_vol_ids
-#else
-#  define is_rp_path_separator(c) ((c) == '/')
-#  define os_get_ino_and_dev unix_get_ino_and_dev
-#endif
-
-/* Fix up absolute symbolic link targets--- mostly shared between UNIX and
- * Windows */
-tchar *
-capture_fixup_absolute_symlink(tchar *dest,
-                              u64 capture_root_ino, u64 capture_root_dev)
-{
-       tchar *p = dest;
-
-#ifdef __WIN32__
-       /* Skip drive letter */
-       if (!is_rp_path_separator(*dest))
-               p += 2;
-#endif
-
-       DEBUG("Fixing symlink or junction \"%"TS"\"", dest);
-       for (;;) {
-               tchar save;
-               int ret;
-               u64 ino;
-               u64 dev;
-
-               while (is_rp_path_separator(*p))
-                       p++;
-
-               save = *p;
-               *p = T('\0');
-               ret = os_get_ino_and_dev(dest, &ino, &dev);
-               *p = save;
-
-               if (ret) /* stat() failed before we got to the capture root---
-                           assume the link points outside it. */
-                       return NULL;
-
-               if (ino == capture_root_ino && dev == capture_root_dev) {
-                       /* Link points inside capture root.  Return abbreviated
-                        * path. */
-                       if (*p == T('\0'))
-                               *(p - 1) = OS_PREFERRED_PATH_SEPARATOR;
-                       while (p - 1 >= dest && is_rp_path_separator(*(p - 1)))
-                               p--;
-               #ifdef __WIN32__
-                       if (!is_rp_path_separator(dest[0])) {
-                               *--p = dest[1];
-                               *--p = dest[0];
-                       }
-               #endif
-                       wimlib_assert(p >= dest);
-                       return p;
-               }
-
-               if (*p == T('\0')) {
-                       /* Link points outside capture root. */
-                       return NULL;
-               }
-
-               do {
-                       p++;
-               } while (!is_rp_path_separator(*p) && *p != T('\0'));
-       }
-}
+#endif /* !__WIN32__ */