xref: /OK3568_Linux_fs/buildroot/package/ntfs-3g/0001-ntfscp-Support-directory-copy.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From 34ed66f2bc913b70cae217fd32cc3cba050069c4 Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Sat, 29 Dec 2018 17:33:48 +0800
4Subject: [PATCH] ntfscp: Support directory copy
5
6Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
7---
8 ntfsprogs/ntfscp.c | 45 ++++++++++++++++++++++++++++++++-------------
9 1 file changed, 32 insertions(+), 13 deletions(-)
10
11diff --git a/ntfsprogs/ntfscp.c b/ntfsprogs/ntfscp.c
12index 19303b6..6f9180a 100644
13--- a/ntfsprogs/ntfscp.c
14+++ b/ntfsprogs/ntfscp.c
15@@ -798,19 +798,20 @@ static int preallocate(ntfs_attr *na, s64 new_size)
16 }
17
18 /**
19- * Create a regular file under the given directory inode
20+ * Create a file under the given directory inode
21  *
22  * It is a wrapper function to ntfs_create(...)
23  *
24  * Return:  the created file inode
25  */
26 static ntfs_inode *ntfs_new_file(ntfs_inode *dir_ni,
27-			  const char *filename)
28+			  const char *filename, mode_t typemode)
29 {
30 	ntfschar *ufilename;
31 	/* inode to the file that is being created */
32 	ntfs_inode *ni;
33 	int ufilename_len;
34+	mode_t type = typemode & ~07777;
35
36 	/* ntfs_mbstoucs(...) will allocate memory for ufilename if it's NULL */
37 	ufilename = NULL;
38@@ -820,7 +821,7 @@ static ntfs_inode *ntfs_new_file(ntfs_inode *dir_ni,
39 					filename);
40 		return NULL;
41 	}
42-	ni = ntfs_create(dir_ni, const_cpu_to_le32(0), ufilename, ufilename_len, S_IFREG);
43+	ni = ntfs_create(dir_ni, const_cpu_to_le32(0), ufilename, ufilename_len, type);
44 	free(ufilename);
45 	return ni;
46 }
47@@ -852,6 +853,8 @@ int main(int argc, char *argv[])
48 #ifdef HAVE_WINDOWS_H
49 	char *unix_name;
50 #endif
51+	struct stat fst;
52+	int created = 0;
53
54 	ntfs_log_set_handler(ntfs_log_handler_stderr);
55
56@@ -892,14 +895,11 @@ int main(int argc, char *argv[])
57 		goto umount;
58 	}
59
60-	{
61-		struct stat fst;
62-		if (stat(opts.src_file, &fst) == -1) {
63-			ntfs_log_perror("ERROR: Couldn't stat source file");
64-			goto umount;
65-		}
66-		new_size = fst.st_size;
67+	if (stat(opts.src_file, &fst) == -1) {
68+		ntfs_log_perror("ERROR: Couldn't stat source file");
69+		goto umount;
70 	}
71+	new_size = fst.st_size;
72 	ntfs_log_verbose("New file size: %lld\n", (long long)new_size);
73
74 	in = fopen(opts.src_file, "r");
75@@ -960,6 +960,8 @@ int main(int argc, char *argv[])
76 			ntfs_log_verbose("Target path does not contain '/'. "
77 					"Using root directory as parent.\n");
78 			dir_ni = ntfs_inode_open(vol, FILE_root);
79+			free(parent_dirname);
80+			dirname_last_whack = parent_dirname = strdup("/");
81 		}
82 		if (dir_ni) {
83 			if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
84@@ -974,7 +976,7 @@ int main(int argc, char *argv[])
85 			}
86 			ntfs_log_verbose("Creating a new file '%s' under '%s'"
87 					 "\n", filename, parent_dirname);
88-			ni = ntfs_new_file(dir_ni, filename);
89+			ni = ntfs_new_file(dir_ni, filename, fst.st_mode);
90 			ntfs_inode_close(dir_ni);
91 			if (!ni) {
92 				ntfs_log_perror("Failed to create '%s' under "
93@@ -984,6 +986,7 @@ int main(int argc, char *argv[])
94 				goto close_src;
95 			}
96 			out = ni;
97+			created = 1;
98 		} else {
99 			ntfs_log_perror("ERROR: Couldn't open '%s'",
100 					parent_dirname);
101@@ -993,7 +996,8 @@ int main(int argc, char *argv[])
102 		free(parent_dirname);
103 	}
104 	/* The destination is a directory. */
105-	if ((out->mrec->flags & MFT_RECORD_IS_DIRECTORY) && !opts.inode) {
106+	if (!created && (out->mrec->flags & MFT_RECORD_IS_DIRECTORY)
107+	   && !opts.inode) {
108 		char *filename;
109 		char *overwrite_filename;
110 		int overwrite_filename_len;
111@@ -1027,6 +1031,16 @@ int main(int argc, char *argv[])
112 		ni = ntfs_pathname_to_inode(vol, dir_ni, overwrite_filename);
113 		/* Does a file with the same name exist in the dest dir? */
114 		if (ni) {
115+			if (S_ISDIR(fst.st_mode)
116+			   || ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
117+				ntfs_log_verbose("Destination path has a file"
118+						" with the same name\nCannot"
119+						" overwriting the file '%s'\n",
120+						overwrite_filename);
121+				ntfs_inode_close(out);
122+				free(overwrite_filename);
123+				goto close_src;
124+			}
125 			ntfs_log_verbose("Destination path has a file with "
126 					"the same name\nOverwriting the file "
127 					"'%s'\n", overwrite_filename);
128@@ -1035,7 +1049,7 @@ int main(int argc, char *argv[])
129 		} else {
130 			ntfs_log_verbose("Creating a new file '%s' under "
131 					"'%s'\n", filename, opts.dest_file);
132-			ni = ntfs_new_file(dir_ni, filename);
133+			ni = ntfs_new_file(dir_ni, filename, fst.st_mode);
134 			ntfs_inode_close(dir_ni);
135 			if (!ni) {
136 				ntfs_log_perror("ERROR: Failed to create the "
137@@ -1077,6 +1091,11 @@ int main(int argc, char *argv[])
138 		}
139 	}
140
141+	if (S_ISDIR(fst.st_mode)) {
142+		result = 0;
143+		goto close_attr;
144+	}
145+
146 	ntfs_log_verbose("Old file size: %lld\n", (long long)na->data_size);
147 	if (opts.minfragments && NAttrCompressed(na)) {
148 		ntfs_log_info("Warning : Cannot avoid fragmentation"
149--
1502.20.1
151
152