Browse Source

preserveLastModified for scp uploads

Contributed by J. Hoffmann
master
Stefan Bodewig 9 years ago
parent
commit
881a0ff79e
2 changed files with 69 additions and 12 deletions
  1. +5
    -4
      src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
  2. +64
    -8
      src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java

+ 5
- 4
src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java View File

@@ -124,8 +124,8 @@ public class Scp extends SSHBase {
} }


/** /**
* Sets flag to determine if file timestamp from
* remote system is to be preserved during copy.
* Sets flag to determine if file timestamp
* is to be preserved during copy.
* @since Ant 1.8.0 * @since Ant 1.8.0
*/ */
public void setPreservelastmodified(final boolean yesOrNo) { public void setPreservelastmodified(final boolean yesOrNo) {
@@ -340,7 +340,7 @@ public class Scp extends SSHBase {
ScpToMessage message = null; ScpToMessage message = null;
if (!isSftp) { if (!isSftp) {
message = new ScpToMessage(getVerbose(), session, message = new ScpToMessage(getVerbose(), session,
list, file);
list, file, preserveLastModified);
} else { } else {
message = new ScpToMessageBySftp(getVerbose(), session, message = new ScpToMessageBySftp(getVerbose(), session,
list, file); list, file);
@@ -372,7 +372,8 @@ public class Scp extends SSHBase {
if (!isSftp) { if (!isSftp) {
message = message =
new ScpToMessage(getVerbose(), session, new ScpToMessage(getVerbose(), session,
getProject().resolveFile(fromPath), file);
getProject().resolveFile(fromPath), file,
preserveLastModified);
} else { } else {
message = message =
new ScpToMessageBySftp(getVerbose(), session, new ScpToMessageBySftp(getVerbose(), session,


+ 64
- 8
src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java View File

@@ -44,6 +44,7 @@ public class ScpToMessage extends AbstractSshMessage {
private String remotePath; private String remotePath;
private List directoryList; private List directoryList;
private Integer fileMode, dirMode; private Integer fileMode, dirMode;
private boolean preserveLastModified;


/** /**
* Constructor for ScpToMessage * Constructor for ScpToMessage
@@ -69,15 +70,17 @@ public class ScpToMessage extends AbstractSshMessage {
* @param session the scp session to use * @param session the scp session to use
* @param aLocalFile the local file * @param aLocalFile the local file
* @param aRemotePath the remote path * @param aRemotePath the remote path
* @since Ant 1.6.2
* @param preserveLastModified whether to preserve the last modified timestamps
* @since Ant 1.9.7
*/ */
public ScpToMessage(final boolean verbose, public ScpToMessage(final boolean verbose,
final Session session, final Session session,
final File aLocalFile, final File aLocalFile,
final String aRemotePath) {
final String aRemotePath,
final boolean preserveLastModified) {
this(verbose, session, aRemotePath); this(verbose, session, aRemotePath);

this.localFile = aLocalFile; this.localFile = aLocalFile;
this.preserveLastModified = preserveLastModified;
} }


/** /**
@@ -86,15 +89,47 @@ public class ScpToMessage extends AbstractSshMessage {
* @param session the scp session to use * @param session the scp session to use
* @param aDirectoryList a list of directories * @param aDirectoryList a list of directories
* @param aRemotePath the remote path * @param aRemotePath the remote path
* @since Ant 1.6.2
* @param preserveLastModified whether to preserve the last modified timestamps
* @since Ant 1.9.7
*/ */
public ScpToMessage(final boolean verbose, public ScpToMessage(final boolean verbose,
final Session session, final Session session,
final List aDirectoryList, final List aDirectoryList,
final String aRemotePath) {
final String aRemotePath,
final boolean preserveLastModified) {
this(verbose, session, aRemotePath); this(verbose, session, aRemotePath);

this.directoryList = aDirectoryList; this.directoryList = aDirectoryList;
this.preserveLastModified = preserveLastModified;
}

/**
* 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
* @since Ant 1.6.2
*/
public ScpToMessage(final boolean verbose,
final Session session,
final File aLocalFile,
final String aRemotePath) {
this(verbose, session, aLocalFile, 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
* @since Ant 1.6.2
*/
public ScpToMessage(final boolean verbose,
final Session session,
final List aDirectoryList,
final String aRemotePath) {
this(verbose, session, aDirectoryList, aRemotePath, false);
} }


/** /**
@@ -152,7 +187,7 @@ public class ScpToMessage extends AbstractSshMessage {
} }


private void doSingleTransfer() throws IOException, JSchException { private void doSingleTransfer() throws IOException, JSchException {
final String cmd = "scp -t " + remotePath;
final String cmd = "scp -t " + (getPreserveLastModified() ? "-p " : "") + remotePath;
final Channel channel = openExecChannel(cmd); final Channel channel = openExecChannel(cmd);
try { try {


@@ -171,7 +206,10 @@ public class ScpToMessage extends AbstractSshMessage {
} }


private void doMultipleTransfer() throws IOException, JSchException { private void doMultipleTransfer() throws IOException, JSchException {
final Channel channel = openExecChannel("scp -r -d -t " + remotePath);
final Channel channel =
openExecChannel("scp -r -d -t "
+ (getPreserveLastModified() ? "-p " : "")
+ remotePath);
try { try {
final OutputStream out = channel.getOutputStream(); final OutputStream out = channel.getOutputStream();
final InputStream in = channel.getInputStream(); final InputStream in = channel.getInputStream();
@@ -226,6 +264,16 @@ public class ScpToMessage extends AbstractSshMessage {
final OutputStream out) throws IOException { final OutputStream out) throws IOException {
// send "C0644 filesize filename", where filename should not include '/' // send "C0644 filesize filename", where filename should not include '/'
final long filesize = localFile.length(); final long filesize = localFile.length();

if (getPreserveLastModified()) {
String command = "T" + (localFile.lastModified() / 1000) + " 0";
command += " " + (localFile.lastModified() / 1000) + " 0\n";
out.write(command.getBytes());
out.flush();

waitForAck(in);
}

String command = "C0"; String command = "C0";
command += Integer.toOctalString(getFileMode()); command += Integer.toOctalString(getFileMode());
command += " " + filesize + " "; command += " " + filesize + " ";
@@ -328,4 +376,12 @@ public class ScpToMessage extends AbstractSshMessage {
return dirMode != null ? dirMode.intValue() : DEFAULT_DIR_MODE; return dirMode != null ? dirMode.intValue() : DEFAULT_DIR_MODE;
} }


/**
* Whether to preserve the last modified time.
* @since Ant 1.9.7
*/
public boolean getPreserveLastModified() {
return preserveLastModified;
}

} }

Loading…
Cancel
Save