You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bo...@apache.org on 2008/07/16 10:07:45 UTC

svn commit: r677187 - in /ant/core/trunk: ./ docs/manual/OptionalTasks/ src/main/org/apache/tools/ant/taskdefs/optional/ssh/

Author: bodewig
Date: Wed Jul 16 01:07:44 2008
New Revision: 677187

URL: http://svn.apache.org/viewvc?rev=677187&view=rev
Log:
Add preservelastmodified to scp.  PR 33939.  Based on patch by Sandra Metz.

Modified:
    ant/core/trunk/CONTRIBUTORS
    ant/core/trunk/WHATSNEW
    ant/core/trunk/contributors.xml
    ant/core/trunk/docs/manual/OptionalTasks/scp.html
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java

Modified: ant/core/trunk/CONTRIBUTORS
URL: http://svn.apache.org/viewvc/ant/core/trunk/CONTRIBUTORS?rev=677187&r1=677186&r2=677187&view=diff
==============================================================================
Binary files - no diff available.

Modified: ant/core/trunk/WHATSNEW
URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=677187&r1=677186&r2=677187&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Wed Jul 16 01:07:44 2008
@@ -168,6 +168,10 @@
  * <sshexec> now supports input in a way similar to <exec>
    Bugzilla report 39197.
 
+ * <scp> can now preserve the file modification time when downloading
+   files.
+   Bugzilla Issue 33939.
+
 Changes from Ant 1.7.0 TO Ant 1.7.1
 =============================================
 

Modified: ant/core/trunk/contributors.xml
URL: http://svn.apache.org/viewvc/ant/core/trunk/contributors.xml?rev=677187&r1=677186&r2=677187&view=diff
==============================================================================
--- ant/core/trunk/contributors.xml (original)
+++ ant/core/trunk/contributors.xml Wed Jul 16 01:07:44 2008
@@ -956,6 +956,10 @@
     <last>Ruby</last>
   </name>
   <name>
+    <first>Sandra</first>
+    <last>Metz</last>
+  </name>
+  <name>
     <first>Scott</first>
     <last>Carlson</last>
   </name>

Modified: ant/core/trunk/docs/manual/OptionalTasks/scp.html
URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/OptionalTasks/scp.html?rev=677187&r1=677186&r2=677187&view=diff
==============================================================================
--- ant/core/trunk/docs/manual/OptionalTasks/scp.html (original)
+++ ant/core/trunk/docs/manual/OptionalTasks/scp.html Wed Jul 16 01:07:44 2008
@@ -174,6 +174,15 @@
     server that doesn't support scp1. <em>since Ant 1.7</em></td>
     <td valign="top" align="center">No; defaults to false.</td>
   </tr>
+  <tr>
+    <td valign="top">preserveLastModified</td>
+    <td valign="top">Determines whether the last modification
+    timestamp of downloaded files is preserved.  It only works when
+    transferring from a remote to a local system and probably doesn't
+    work with a server that doesn't support SSH2.  <em>since Ant
+    1.8.0</em></td>
+    <td valign="top" align="center">No; defaults to false.</td>
+  </tr>
 </table>
 <h3>Parameters specified as nested elements</h3>
 

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java?rev=677187&r1=677186&r2=677187&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java Wed Jul 16 01:07:44 2008
@@ -49,6 +49,7 @@
 
     private String fromUri;
     private String toUri;
+    private boolean preserveLastModified = false;
     private List fileSets = null;
     private boolean isFromRemote, isToRemote;
     private boolean isSftp = false;
@@ -117,6 +118,15 @@
     }
 
     /**
+     * Sets flag to determine if file timestamp from
+     * remote system is to be preserved during copy.
+     * @since Ant 1.8.0
+     */
+    public void setPreservelastmodified(boolean yesOrNo) {
+    	this.preserveLastModified = yesOrNo;
+    }    
+
+    /**
      * Similiar to {@link #setTodir setTodir} but explicitly states
      * that the directory is a remote.
      * @param aToUri a string representing the target of the copy.
@@ -231,12 +241,14 @@
                 message =
                     new ScpFromMessage(getVerbose(), session, file,
                                        getProject().resolveFile(toPath),
-                                       fromSshUri.endsWith("*"));
+                                       fromSshUri.endsWith("*"),
+                                       preserveLastModified);
             } else {
                 message =
                     new ScpFromMessageBySftp(getVerbose(), session, file,
                                              getProject().resolveFile(toPath),
-                                             fromSshUri.endsWith("*"));
+                                             fromSshUri.endsWith("*"),
+                                             preserveLastModified);
             }
             log("Receiving file: " + file);
             message.setLogListener(this);

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java?rev=677187&r1=677186&r2=677187&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java Wed Jul 16 01:07:44 2008
@@ -27,7 +27,11 @@
 import java.io.ByteArrayOutputStream;
 import com.jcraft.jsch.JSchException;
 import com.jcraft.jsch.Session;
+import com.jcraft.jsch.SftpATTRS;
+import com.jcraft.jsch.SftpException;
 import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelSftp;
+import org.apache.tools.ant.util.FileUtils;
 
 /**
  * A helper object representing an scp download.
@@ -41,6 +45,7 @@
     private String remoteFile;
     private File localFile;
     private boolean isRecursive = false;
+    private boolean preserveLastModified = false;
 
     /**
      * Constructor for ScpFromMessage
@@ -74,10 +79,7 @@
                           String aRemoteFile,
                           File aLocalFile,
                           boolean recursive) {
-        super(verbose, session);
-        this.remoteFile = aRemoteFile;
-        this.localFile = aLocalFile;
-        this.isRecursive = recursive;
+        this(false, session, aRemoteFile, aLocalFile, recursive, false);
     }
 
     /**
@@ -95,6 +97,30 @@
     }
 
     /**
+     * Constructor for ScpFromMessage.
+     * @param verbose if true log extra information
+     * @param session the Scp session to use
+     * @param aRemoteFile the remote file name
+     * @param aLocalFile  the local file
+     * @param recursive   if true use recursion (-r option to scp)
+     * @param preservceLastModified whether to preserve file
+     * modification times
+     * @since Ant 1.8.0
+     */
+    public ScpFromMessage(boolean verbose,
+                          Session session,
+                          String aRemoteFile,
+                          File aLocalFile,
+                          boolean recursive,
+                          boolean preserveLastModified) {
+        super(verbose, session);
+        this.remoteFile = aRemoteFile;
+        this.localFile = aLocalFile;
+        this.isRecursive = recursive;
+        this.preserveLastModified = preserveLastModified;
+    }
+
+    /**
      * Carry out the transfer.
      * @throws IOException on i/o errors
      * @throws JSchException on errors detected by scp
@@ -123,9 +149,14 @@
         log("done\n");
     }
 
+    protected boolean getPreserveLastModified() {
+        return preserveLastModified;
+    }
+
     private void startRemoteCpProtocol(InputStream in,
                                        OutputStream out,
-                                       File localFile) throws IOException {
+                                       File localFile)
+        throws IOException, JSchException {
         File startFile = localFile;
         while (true) {
             // C0644 filesize filename - header for a regular file
@@ -147,7 +178,7 @@
                 parseAndFetchFile(serverResponse, startFile, out, in);
             } else if (serverResponse.charAt(0) == 'D') {
                 startFile = parseAndCreateDirectory(serverResponse,
-                        startFile);
+                                                    startFile);
                 sendAck(out);
             } else if (serverResponse.charAt(0) == 'E') {
                 startFile = startFile.getParentFile();
@@ -178,7 +209,8 @@
     private void parseAndFetchFile(String serverResponse,
                                    File localFile,
                                    OutputStream out,
-                                   InputStream in) throws IOException {
+                                   InputStream in)
+        throws IOException, JSchException  {
         int start = 0;
         int end = serverResponse.indexOf(" ", start + 1);
         start = end + 1;
@@ -197,7 +229,8 @@
     private void fetchFile(File localFile,
                             long filesize,
                             OutputStream out,
-                            InputStream in) throws IOException {
+                           InputStream in)
+        throws IOException, JSchException {
         byte[] buf = new byte[BUFFER_SIZE];
         sendAck(out);
 
@@ -241,6 +274,37 @@
             fos.flush();
             fos.close();
         }
+
+        if (getPreserveLastModified()) {
+            setLastModified(localFile);
+        }
     }
 
+    private void setLastModified(File localFile) throws JSchException {
+        SftpATTRS fileAttributes = null;
+        String remotePath = null;
+        ChannelSftp channel = openSftpChannel();
+        channel.connect();
+        try {
+            fileAttributes = channel.lstat(remoteDir(remoteFile)
+                                           + localFile.getName());
+        } catch (SftpException e) {
+            throw new JSchException("failed to stat remote file", e);
+        }
+        FileUtils.getFileUtils().setFileLastModified(localFile,
+                                                     ((long) fileAttributes
+                                                      .getMTime())
+                                                     * 1000);
+    }
+
+    /**
+     * returns the directory part of the remote file, if any.
+     */
+    private static String remoteDir(String remoteFile) {
+        int index = remoteFile.lastIndexOf("/");
+        if (index < 0) {
+            index = remoteFile.lastIndexOf("\\");
+        }
+        return index > -1 ? remoteFile.substring(0, index + 1) : "";
+    }
 }

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java?rev=677187&r1=677186&r2=677187&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java Wed Jul 16 01:07:44 2008
@@ -28,6 +28,8 @@
 import com.jcraft.jsch.SftpATTRS;
 import com.jcraft.jsch.SftpProgressMonitor;
 
+import org.apache.tools.ant.util.FileUtils;
+
 /**
  * A helper object representing an scp download.
  */
@@ -54,11 +56,7 @@
                                 String aRemoteFile,
                                 File aLocalFile,
                                 boolean recursive) {
-        super(verbose, session);
-        this.verbose = verbose;
-        this.remoteFile = aRemoteFile;
-        this.localFile = aLocalFile;
-        this.isRecursive = recursive;
+        this(verbose, session, aRemoteFile, aLocalFile, recursive, false);
     }
 
     /**
@@ -76,6 +74,31 @@
     }
 
     /**
+     * Constructor for ScpFromMessageBySftp.
+     * @param verbose if true log extra information
+     * @param session the Scp session to use
+     * @param aRemoteFile the remote file name
+     * @param aLocalFile  the local file
+     * @param recursive   if true use recursion
+     * @param preservceLastModified whether to preserve file
+     * modification times
+     * @since Ant 1.8.0
+     */
+    public ScpFromMessageBySftp(boolean verbose,
+                                Session session,
+                                String aRemoteFile,
+                                File aLocalFile,
+                                boolean recursive,
+                                boolean preserveLastModified) {
+        super(verbose, session, aRemoteFile, aLocalFile, recursive,
+              preserveLastModified);
+        this.verbose = verbose;
+        this.remoteFile = aRemoteFile;
+        this.localFile = aLocalFile;
+        this.isRecursive = recursive;
+    }
+
+    /**
      * Carry out the transfer.
      * @throws IOException on i/o errors
      * @throws JSchException on errors detected by scp
@@ -171,5 +194,11 @@
             long endTime = System.currentTimeMillis();
             logStats(startTime, endTime, (int) totalLength);
         }
+        if (getPreserveLastModified()) {
+            FileUtils.getFileUtils().setFileLastModified(localFile,
+                                                         ((long) le.getAttrs()
+                                                          .getMTime())
+                                                         * 1000);
+        }
     }
 }



Re: svn commit: r677187 - in /ant/core/trunk: ./ docs/manual/OptionalTasks/ src/main/org/apache/tools/ant/taskdefs/optional/ssh/

Posted by Stefan Bodewig <bo...@apache.org>.
On Wed, 16 Jul 2008, <bo...@apache.org> wrote:

> Add preservelastmodified to scp.  PR 33939.  Based on patch by
> Sandra Metz.

As was to be expected, applying a three year old patch involved
fiddling around a bit, in particular when the implementation has
added support for an additional protocol (sftp).  

The sftp code is based on (sophisticated?) guesswork and some manual
testing 8-)

The attribute only applies to downloading files, I don't know enough
about SSH or JSch to make it work the other way around.

I will note that there are enhancement requests to the effect of
chmod'ing remote files as well, which may be addressed together with
fixing the timestamp on the remote side.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org