From f9ca81a4768e06e2a01b555640173b5ec09fc4c8 Mon Sep 17 00:00:00 2001
From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Date: Fri, 9 Feb 2024 16:14:27 +0100
Subject: Fixup extaction paths for rdsquashfs on Windows

 - If we generate a manifest file, use the fix-path function to
   produce a fixed up, actual name as the source path.
 - When unpacking, create files for the fixed up, actual name.

There is no need to touch gensquashfs, if the manifest file is used
to re-pack the stuff, the original paths are used and the files are
source from the fixed-up paths.

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
---
 bin/rdsquashfs/describe.c       | 20 ++++++++++++++++++--
 bin/rdsquashfs/fill_files.c     | 21 +++++++++++++++++----
 bin/rdsquashfs/restore_fstree.c | 23 ++++++++++++++++++++++-
 3 files changed, 57 insertions(+), 7 deletions(-)

(limited to 'bin')

diff --git a/bin/rdsquashfs/describe.c b/bin/rdsquashfs/describe.c
index 8c0fb16..0ac5cb6 100644
--- a/bin/rdsquashfs/describe.c
+++ b/bin/rdsquashfs/describe.c
@@ -6,7 +6,7 @@
  */
 #include "rdsquashfs.h"
 
-static int print_name(const sqfs_tree_node_t *n, bool dont_escape)
+static int print_name(const sqfs_tree_node_t *n, bool source_path)
 {
 	char *start, *ptr, *name;
 	int ret;
@@ -23,7 +23,23 @@ static int print_name(const sqfs_tree_node_t *n, bool dont_escape)
 		return -1;
 	}
 
-	if (dont_escape || (strchr(name, ' ') == NULL &&
+#if defined(_WIN32) || defined(__WINDOWS__)
+	if (source_path) {
+		char *fixed = fix_win32_filename(name);
+		sqfs_free(name);
+
+		if (fixed == NULL) {
+			fputs(stderr, "out of memor!\n");
+			return -1;
+		}
+
+		fputs(fixed, stdout);
+		free(fixed);
+		return 0;
+	}
+#endif
+
+	if (source_path || (strchr(name, ' ') == NULL &&
 			    strchr(name, '"') == NULL)) {
 		fputs(name, stdout);
 	} else {
diff --git a/bin/rdsquashfs/fill_files.c b/bin/rdsquashfs/fill_files.c
index 660ef1b..73b90e3 100644
--- a/bin/rdsquashfs/fill_files.c
+++ b/bin/rdsquashfs/fill_files.c
@@ -73,10 +73,8 @@ static int add_file(const sqfs_tree_node_t *node)
 		new_sz = max_files ? max_files * 2 : 256;
 		new = realloc(files, sizeof(files[0]) * new_sz);
 
-		if (new == NULL) {
-			perror("expanding file list");
-			return -1;
-		}
+		if (new == NULL)
+			goto fail_oom;
 
 		files = new;
 		max_files = new_sz;
@@ -94,10 +92,25 @@ static int add_file(const sqfs_tree_node_t *node)
 		return -1;
 	}
 
+#if defined(_WIN32) || defined(__WINDOWS__)
+	{
+		char *fixed = fix_win32_filename(path);
+		sqfs_free(path);
+
+		if (fixed == NULL)
+			goto fail_oom;
+
+		path = fixed;
+	}
+#endif
+
 	files[num_files].path = path;
 	files[num_files].inode = node->inode;
 	num_files++;
 	return 0;
+fail_oom:
+	fputs(stderr, "add_file: out of memor!\n");
+	return -1;
 }
 
 static void clear_file_list(void)
diff --git a/bin/rdsquashfs/restore_fstree.c b/bin/rdsquashfs/restore_fstree.c
index bfe5d86..0c68b3a 100644
--- a/bin/rdsquashfs/restore_fstree.c
+++ b/bin/rdsquashfs/restore_fstree.c
@@ -10,10 +10,18 @@
 static int create_node(const sqfs_tree_node_t *n, const char *name, int flags)
 {
 	WCHAR *wpath;
+	char *fixed;
 	HANDLE fh;
 	(void)flags;
 
-	wpath = path_to_windows(name);
+	fixed = fix_win32_filename(name);
+	if (fixed == NULL) {
+		fputs("create_node: out of memory!\n", stderr);
+		return -1;
+	}
+
+	wpath = path_to_windows(fixed);
+	free(fixed);
 	if (wpath == NULL)
 		return -1;
 
@@ -243,6 +251,19 @@ static int set_attribs(sqfs_xattr_reader_t *xattr,
 	ret = canonicalize_name(path);
 	assert(ret == 0);
 
+#if defined(_WIN32) || defined(__WINDOWS__)
+	{
+		char *fixed = fix_win32_filename(path);
+		if (fixed == NULL) {
+			sqfs_perror(path, "fixing Windows path",
+				    SQFS_ERROR_ALLOC);
+			sqfs_free(path);
+			return -1;
+		}
+		path = fixed;
+	}
+#endif
+
 #ifdef HAVE_SYS_XATTR_H
 	if ((flags & UNPACK_SET_XATTR) && xattr != NULL) {
 		if (set_xattr(path, xattr, n))
-- 
cgit v1.2.3