Hil: Allow ntfscp to create the destination file if it does not already exists by calling ntfs_create().
parent
8cfa94abc3
commit
b7b4c98633
|
@ -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"
|
||||
|
@ -270,6 +274,34 @@ static void signal_handler(int arg __attribute__((unused)))
|
|||
caught_terminate++;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
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.
|
||||
*/
|
||||
/* copy the file if the dest_file's parent dir can be opened */
|
||||
char *parent_dirname;
|
||||
char *filename;
|
||||
ntfs_inode *out_tmp;
|
||||
ntfs_inode *dir_ni;
|
||||
ntfs_inode *ni;
|
||||
int dest_path_len;
|
||||
char *dirname_last_whack;
|
||||
|
||||
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");
|
||||
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) {
|
||||
char *filename;
|
||||
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);
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue