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