diff --git a/WHATSNEW b/WHATSNEW index ee0c1e978..9a95ccb64 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -54,6 +54,11 @@ Other changes: * added Orion support to ejbjar Github Pull Request #33 + * Bugzilla Report 58589 - SCP task, when configured to use SFTP + protocol, now preserves last modified timestamp on files that + it uploads, if the preserveLastModified attribute is set to + true for that task + Changes from Ant 1.10.0 TO Ant 1.10.1 ===================================== diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java index e68f38d0f..71ea26d33 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java @@ -349,7 +349,7 @@ public class Scp extends SSHBase { list, file, preserveLastModified); } else { message = new ScpToMessageBySftp(getVerbose(), session, - list, file); + list, file, preserveLastModified); } message.setLogListener(this); if (fileMode != null) { @@ -384,7 +384,7 @@ public class Scp extends SSHBase { message = new ScpToMessageBySftp(getVerbose(), session, getProject().resolveFile(fromPath), - file); + file, preserveLastModified); } message.setLogListener(this); if (fileMode != null) { diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java index a1177c417..360b18d58 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java @@ -39,6 +39,7 @@ public class ScpToMessageBySftp extends ScpToMessage/*AbstractSshMessage*/ { private File localFile; private final String remotePath; private List directoryList; + private final boolean preserveLastModified; /** * Constructor for a local file to remote. @@ -52,11 +53,31 @@ public class ScpToMessageBySftp extends ScpToMessage/*AbstractSshMessage*/ { final Session session, final File aLocalFile, final String aRemotePath) { - this(verbose, session, aRemotePath); + this(verbose, session, aLocalFile, aRemotePath, false); + + } + + /** + * Constructor for a local file to remote. + * @param verbose if true do verbose logging + * @param session the scp session to use + * @param aLocalFile the local file + * @param aRemotePath the remote path + * @param preserveLastModified True if the last modified time needs to be preserved + * on the transferred files. False otherwise. + * @since Ant 1.9.10 + */ + public ScpToMessageBySftp(final boolean verbose, + final Session session, + final File aLocalFile, + final String aRemotePath, + final boolean preserveLastModified) { + this(verbose, session, aRemotePath, preserveLastModified); this.localFile = aLocalFile; } + /** * Constructor for a local directories to remote. * @param verbose if true do verbose logging @@ -69,23 +90,45 @@ public class ScpToMessageBySftp extends ScpToMessage/*AbstractSshMessage*/ { final Session session, final List aDirectoryList, final String aRemotePath) { - this(verbose, session, aRemotePath); + this(verbose, session, aDirectoryList, aRemotePath, false); + } + + /** + * Constructor for a local directories to remote. + * @param verbose if true do verbose logging + * @param session the scp session to use + * @param aDirectoryList a list of directories + * @param aRemotePath the remote path + * @param preserveLastModified True if the last modified time needs to be preserved + * on the transferred files. False otherwise. + * @since Ant 1.9.10 + */ + public ScpToMessageBySftp(final boolean verbose, + final Session session, + final List aDirectoryList, + final String aRemotePath, + final boolean preserveLastModified) { + this(verbose, session, aRemotePath, preserveLastModified); this.directoryList = aDirectoryList; } + /** * Constructor for ScpToMessage. * @param verbose if true do verbose logging * @param session the scp session to use * @param aRemotePath the remote path - * @since Ant 1.6.2 + * @param preserveLastModified True if the last modified time needs to be preserved + * on the transferred files. False otherwise. */ private ScpToMessageBySftp(final boolean verbose, final Session session, - final String aRemotePath) { + final String aRemotePath, + final boolean preserveLastModified) { super(verbose, session); this.remotePath = aRemotePath; + this.preserveLastModified = preserveLastModified; } /** @@ -263,6 +306,14 @@ public class ScpToMessageBySftp extends ScpToMessage/*AbstractSshMessage*/ { log("Setting file mode '" + Integer.toOctalString(getFileMode()) + "' on remote path " + transferredFileRemotePath); } channel.chmod(getFileMode(), transferredFileRemotePath); + if (getPreserveLastModified()) { + // set the last modified time (seconds since epoch) on the transferred file + final int lastModifiedTime = (int) (localFile.lastModified() / 1000L); + if (this.getVerbose()) { + log("Setting last modified time on remote path " + transferredFileRemotePath + " to " + lastModifiedTime); + } + channel.setMtime(transferredFileRemotePath, lastModifiedTime); + } } finally { if (this.getVerbose()) { final long endTime = System.currentTimeMillis(); @@ -288,4 +339,14 @@ public class ScpToMessageBySftp extends ScpToMessage/*AbstractSshMessage*/ { public String getRemotePath() { return remotePath; } + + /** + * Returns true if the last modified time needs to be preserved on the + * file(s) that get transferred. Returns false otherwise. + * + * @return + */ + public boolean getPreserveLastModified() { + return this.preserveLastModified; + } }