Changes by: uvman
Update of /cvs/linux-ntfs/ntfsprogs/ntfsprogs
In directory delta357.server4you.de:/tmp/cvs-serv10673/ntfsprogs
Modified Files:
ntfscp.c
Log Message:
Hil: Allow ntfscp to create the destination file if it does not already exists by calling ntfs_create().
Index: ntfscp.c
===================================================================
RCS file: /cvs/linux-ntfs/ntfsprogs/ntfsprogs/ntfscp.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -p -r1.37 -r1.38
--- ntfscp.c 14 Aug 2006 03:52:56 -0000 1.37
+++ ntfscp.c 4 Oct 2006 00:47:04 -0000 1.38
@@ -3,6 +3,7 @@
*
* Copyright (c) 2004-2006 Yura Pakhuchiy
* Copyright (c) 2005 Anton Altaparmakov
+ * Copyright (c) 2006 Hil Liao
*
* This utility will overwrite files on NTFS volume.
*
@@ -43,6 +44,9 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
#include "types.h"
#include "attrib.h"
@@ -271,6 +275,34 @@ static void signal_handler(int arg __att
}
/**
+ * Create a regular file under the given directory inode
+ *
+ * It is a wrapper function to ntfs_create(...)
+ *
+ * Return: the created file inode
+ */
+static ntfs_inode *ntfs_new_file(ntfs_inode *dir_ni,
+ const char *filename)
+{
+ ntfschar *ufilename;
+ /* inode to the file that is being created */
+ ntfs_inode *ni;
+ int ufilename_len;
+
+ /* ntfs_mbstoucs(...) will allocate memory for ufilename if it's NULL */
+ ufilename = NULL;
+ ufilename_len = ntfs_mbstoucs(filename, &ufilename, 0);
+ if (ufilename_len == -1) {
+ ntfs_log_perror("ERROR: Failed to convert '%s' to unicode",
+ filename);
+ return NULL;
+ }
+ ni = ntfs_create(dir_ni, ufilename, ufilename_len, S_IFREG);
+ free(ufilename);
+ return ni;
+}
+
+/**
* main - Begin here
*
* Start from here.
@@ -352,26 +384,116 @@ int main(int argc, char *argv[])
} else
out = ntfs_pathname_to_inode(vol, NULL, opts.dest_file);
if (!out) {
- ntfs_log_perror("ERROR: Couldn't open destination file");
- goto close_src;
+ /* copy the file if the dest_file's parent dir can be opened */
+ char *parent_dirname;
+ char *filename;
+ ntfs_inode *dir_ni;
+ ntfs_inode *ni;
+ int dest_path_len;
+ char *dirname_last_whack;
+
+ filename = basename(opts.dest_file);
+ dest_path_len = strlen(opts.dest_file);
+ parent_dirname = strdup(opts.dest_file);
+ if (!parent_dirname) {
+ ntfs_log_perror("strdup() failed");
+ goto close_src;
+ }
+ dirname_last_whack = strrchr(parent_dirname, '/');
+ if (dirname_last_whack) {
+ dirname_last_whack[1] = '\0';
+ dir_ni = ntfs_pathname_to_inode(vol, NULL,
+ parent_dirname);
+ } else {
+ ntfs_log_verbose("Target path does not contain '/'. "
+ "Using root directory as parent.\n");
+ dir_ni = ntfs_inode_open(vol, FILE_root);
+ }
+ if (dir_ni) {
+ if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
+ /* Remove the last '/' for estetic reasons. */
+ dirname_last_whack[0] = '\0';
+ ntfs_log_error("The file '%s' already exists "
+ "and is not a directory. "
+ "Aborting.\n", parent_dirname);
+ free(parent_dirname);
+ ntfs_inode_close(dir_ni);
+ goto close_src;
+ }
+ ntfs_log_verbose("Creating a new file '%s' under '%s'"
+ "\n", filename, parent_dirname);
+ ni = ntfs_new_file(dir_ni, filename);
+ ntfs_inode_close(dir_ni);
+ if (!ni) {
+ ntfs_log_perror("Failed to create '%s' under "
+ "'%s'", filename,
+ parent_dirname);
+ free(parent_dirname);
+ goto close_src;
+ }
+ out = ni;
+ } else {
+ ntfs_log_perror("ERROR: Couldn't open '%s'",
+ parent_dirname);
+ free(parent_dirname);
+ goto close_src;
+ }
+ free(parent_dirname);
}
+ /* the destination file is a path */
if ((out->mrec->flags & MFT_RECORD_IS_DIRECTORY) && !opts.inode) {
- /*
- * @out is directory and it was specified by pathname, add
- * filename to path and try once again.
- */
char *filename;
- ntfs_inode *out_tmp;
+ char *overwrite_filename;
+ int overwrite_filename_len;
+ /* inode to the file that is being created */
+ ntfs_inode *ni;
+ /* inode to the directory to create the file */
+ ntfs_inode *dir_ni;
+ int filename_len;
+ int dest_dirname_len;
filename = basename(opts.src_file);
- out_tmp = ntfs_pathname_to_inode(vol, out, filename);
- ntfs_inode_close(out);
- out = out_tmp;
- if (!out) {
- ntfs_log_perror("ERROR: Failed to open destination "
- "file");
+ dir_ni = out;
+ filename_len = strlen(filename);
+ dest_dirname_len = strlen(opts.dest_file);
+ overwrite_filename_len = filename_len+dest_dirname_len+2;
+ overwrite_filename = malloc(overwrite_filename_len);
+ if (!overwrite_filename) {
+ ntfs_log_perror("ERROR: Failed to allocate %i bytes "
+ "memory for the overwrite filename",
+ overwrite_filename_len);
+ ntfs_inode_close(out);
goto close_src;
}
+ strcpy(overwrite_filename, opts.dest_file);
+ /* add '/' in the end of dest_dirname if there is not one there */
+ if (opts.dest_file[dest_dirname_len-1] != '/') {
+ strcat(overwrite_filename, "/");
+ }
+ strcat(overwrite_filename, filename);
+ ni = ntfs_pathname_to_inode(vol, NULL, overwrite_filename);
+ /* Does a file with the same name exist in the dest dir? */
+ if (ni) {
+ ntfs_log_verbose("Destination path has a file with "
+ "the same name\nOverwriting the file "
+ "'%s'\n", overwrite_filename);
+ ntfs_inode_close(out);
+ out = ni;
+ } else {
+ ntfs_log_verbose("Creating a new file '%s' under '%s'\n",
+ filename, opts.dest_file);
+ ni = ntfs_new_file(dir_ni, filename);
+ ntfs_inode_close(dir_ni);
+ if (!ni) {
+ ntfs_log_perror("ERROR: Failed to create the "
+ "destination file under '%s'",
+ opts.dest_file);
+ free(overwrite_filename);
+ goto close_src;
+ }
+ out = ni;
+ }
+ free(overwrite_filename);
}
attr_name = ntfs_str2ucs(opts.attr_name, &attr_name_len);
|