From a951ed7f61ff7505315a2c5fc9a2734e751a0d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Fri, 1 Jun 2018 16:18:51 +0200 Subject: [PATCH] Added an option to ntfscp to copy the modification time When using option -t the modification timestamp is copied by ntfscp --- ntfsprogs/ntfscp.8.in | 4 ++++ ntfsprogs/ntfscp.c | 26 +++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ntfsprogs/ntfscp.8.in b/ntfsprogs/ntfscp.8.in index bf5127ba..67973331 100644 --- a/ntfsprogs/ntfscp.8.in +++ b/ntfsprogs/ntfscp.8.in @@ -59,6 +59,10 @@ Show a list of options with a brief description of each one. \fB\-q\fR, \fB\-\-quiet\fR Suppress some debug/warning/error messages. .TP +\fB\-t\fR, \fB\-\-timestamp\fR +Copy the modification time of source_file to destination. This is +not compatible with \fB\-\-attr\-name\fR and \fB\-\-attribute\fR. +.TP \fB\-V\fR, \fB\-\-version\fR Show the version number, copyright and license .BR ntfscp . diff --git a/ntfsprogs/ntfscp.c b/ntfsprogs/ntfscp.c index 24381b46..726e6471 100644 --- a/ntfsprogs/ntfscp.c +++ b/ntfsprogs/ntfscp.c @@ -58,6 +58,7 @@ #include "debug.h" /* #include "version.h" */ #include "logging.h" +#include "ntfstime.h" #include "misc.h" struct options { @@ -69,6 +70,7 @@ struct options { int quiet; /* Less output */ int verbose; /* Extra output */ int minfragments; /* Do minimal fragmentation */ + int timestamp; /* Copy the modification time */ int noaction; /* Do not write to disk */ ATTR_TYPES attribute; /* Write to this attribute. */ int inode; /* Treat dest_file as inode number. */ @@ -129,6 +131,7 @@ static void usage(void) " -N, --attr-name NAME Write to attribute with this name\n" " -n, --no-action Do not write to disk\n" " -q, --quiet Less output\n" + " -t, --timestamp Copy the modification time\n" " -V, --version Version information\n" " -v, --verbose More output\n\n", EXEC_NAME); @@ -146,7 +149,7 @@ static void usage(void) */ static int parse_options(int argc, char **argv) { - static const char *sopt = "-a:ifh?mN:no:qVv"; + static const char *sopt = "-a:ifh?mN:no:qtVv"; static const struct option lopt[] = { { "attribute", required_argument, NULL, 'a' }, { "inode", no_argument, NULL, 'i' }, @@ -156,6 +159,7 @@ static int parse_options(int argc, char **argv) { "attr-name", required_argument, NULL, 'N' }, { "no-action", no_argument, NULL, 'n' }, { "quiet", no_argument, NULL, 'q' }, + { "timestamp", no_argument, NULL, 't' }, { "version", no_argument, NULL, 'V' }, { "verbose", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } @@ -175,6 +179,7 @@ static int parse_options(int argc, char **argv) opts.attr_name = NULL; opts.inode = 0; opts.attribute = AT_DATA; + opts.timestamp = 0; opterr = 0; /* We'll handle the errors, thank you. */ @@ -235,6 +240,9 @@ static int parse_options(int argc, char **argv) opts.quiet++; ntfs_log_clear_levels(NTFS_LOG_LEVEL_QUIET); break; + case 't': + opts.timestamp++; + break; case 'V': ver++; break; @@ -284,6 +292,12 @@ static int parse_options(int argc, char **argv) "at the same time.\n"); err++; } + if (opts.timestamp + && (opts.attr_name || (opts.attribute != AT_DATA))) { + ntfs_log_error("Setting --timestamp is only possible" + " with unname data attribute.\n"); + err++; + } } if (ver) @@ -822,6 +836,7 @@ static ntfs_inode *ntfs_new_file(ntfs_inode *dir_ni, int main(int argc, char *argv[]) { FILE *in; + struct stat st; ntfs_volume *vol; ntfs_inode *out; ntfs_attr *na; @@ -1136,6 +1151,15 @@ int main(int argc, char *argv[]) free(buf); close_attr: ntfs_attr_close(na); + if (opts.timestamp) { + if (!fstat(fileno(in),&st)) { + out->last_data_change_time = st.st_mtime*10000000LL + + NTFS_TIME_OFFSET; + ntfs_inode_update_times(out, 0); + } else { + ntfs_log_error("Failed to get the time stamp.\n"); + } + } close_dst: while (ntfs_inode_close(out) && !opts.noaction) { if (errno != EBUSY) {