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