ASF Bugzilla – Attachment 18147 Details for
Bug 39373
scp task does not work for some sshd, which does not scp1 protocol.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
a patch to use sftp protocol in scp task.
diff-1 (text/plain), 20.11 KB, created by
Atsuhiko Yamanaka
on 2006-04-21 01:37:34 UTC
(
hide
)
Description:
a patch to use sftp protocol in scp task.
Filename:
MIME Type:
Creator:
Atsuhiko Yamanaka
Created:
2006-04-21 01:37:34 UTC
Size:
20.11 KB
patch
obsolete
>diff -Naur ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java >--- ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java 2005-10-13 04:42:41.000000000 +0000 >+++ ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java 2006-04-13 09:21:52.000000000 +0000 >@@ -21,6 +21,10 @@ > import com.jcraft.jsch.ChannelExec; > import com.jcraft.jsch.JSchException; > import com.jcraft.jsch.Session; >+import com.jcraft.jsch.ChannelSftp; >+import com.jcraft.jsch.SftpATTRS; >+import com.jcraft.jsch.SftpException; >+import com.jcraft.jsch.SftpProgressMonitor; > > import java.io.IOException; > import java.io.OutputStream; >@@ -75,6 +79,17 @@ > } > > /** >+ * Open an ssh sftp channel. >+ * @return the channel >+ * @throws JSchException on error >+ */ >+ protected ChannelSftp openSftpChannel() throws JSchException { >+ ChannelSftp channel = (ChannelSftp) session.openChannel("sftp"); >+ >+ return channel; >+ } >+ >+ /** > * Send an ack. > * @param out the output stream to use > * @throws IOException on error >@@ -213,4 +228,32 @@ > return percent; > } > >+ private ProgressMonitor monitor=null; >+ >+ ProgressMonitor getProgressMonitor(){ >+ if(monitor==null)monitor=new ProgressMonitor(); >+ return monitor; >+ } >+ class ProgressMonitor implements SftpProgressMonitor{ >+ long initFileSize=0; >+ long totalLength=0; >+ int percentTransmitted = 0; >+ public void init(int op, String src, String dest, long max){ >+ initFileSize=max; >+ totalLength=0; >+ percentTransmitted = 0; >+ } >+ public boolean count(long len){ >+ totalLength+=len; >+ percentTransmitted = trackProgress(initFileSize, >+ totalLength, >+ percentTransmitted); >+ return true; >+ } >+ public void end(){ >+ } >+ public long getTotalLength(){ >+ return totalLength; >+ } >+ }; > } >diff -Naur ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java >--- ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java 2005-10-13 04:42:41.000000000 +0000 >+++ ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java 2006-04-17 07:23:20.000000000 +0000 >@@ -44,6 +44,7 @@ > private String toUri; > private List fileSets = null; > private boolean isFromRemote, isToRemote; >+ private boolean isSftp = false; > > /** > * Sets the file to be transferred. This can either be a remote >@@ -142,6 +143,15 @@ > } > > /** >+ * Setting this to true to use sftp protocol. >+ * >+ * @param yesOrNo if true sftp protocol will be used. >+ */ >+ public void setSftp(boolean yesOrNo) { >+ isSftp=yesOrNo; >+ } >+ >+ /** > * Adds a FileSet tranfer to remote host. NOTE: Either > * addFileSet() or setFile() are required. But, not both. > * >@@ -213,10 +223,19 @@ > Session session = null; > try { > session = openSession(); >- ScpFromMessage message = >- new ScpFromMessage(getVerbose(), session, file, >- getProject().resolveFile(toPath), >- fromSshUri.endsWith("*")); >+ ScpFromMessage message = null; >+ if(!isSftp){ >+ message = >+ new ScpFromMessage(getVerbose(), session, file, >+ getProject().resolveFile(toPath), >+ fromSshUri.endsWith("*")); >+ } >+ else{ >+ message = >+ new ScpFromMessageBySftp(getVerbose(), session, file, >+ getProject().resolveFile(toPath), >+ fromSshUri.endsWith("*")); >+ } > log("Receiving file: " + file); > message.setLogListener(this); > message.execute(); >@@ -243,8 +262,15 @@ > } > if (!list.isEmpty()) { > session = openSession(); >- ScpToMessage message = new ScpToMessage(getVerbose(), session, >- list, file); >+ ScpToMessage message = null; >+ if(!isSftp){ >+ message = new ScpToMessage(getVerbose(), session, >+ list, file); >+ } >+ else{ >+ message = new ScpToMessageBySftp(getVerbose(), session, >+ list, file); >+ } > message.setLogListener(this); > message.execute(); > } >@@ -262,9 +288,17 @@ > Session session = null; > try { > session = openSession(); >- ScpToMessage message = >- new ScpToMessage(getVerbose(), session, >- getProject().resolveFile(fromPath), file); >+ ScpToMessage message = null; >+ if(!isSftp){ >+ message = >+ new ScpToMessage(getVerbose(), session, >+ getProject().resolveFile(fromPath), file); >+ } >+ else{ >+ message = >+ new ScpToMessageBySftp(getVerbose(), session, >+ getProject().resolveFile(fromPath), file); >+ } > message.setLogListener(this); > message.execute(); > } finally { >diff -Naur ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java >--- ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java 2005-10-13 04:42:41.000000000 +0000 >+++ ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java 2006-04-13 09:22:50.000000000 +0000 >@@ -41,6 +41,24 @@ > private boolean isRecursive = false; > > /** >+ * Constructor for ScpFromMessage >+ * @param session the ssh session to use >+ */ >+ public ScpFromMessage(Session session) { >+ super(session); >+ } >+ >+ /** >+ * Constructor for ScpFromMessage >+ * @param verbose if true do verbose logging >+ * @param session the ssh session to use >+ * @since Ant 1.6.2 >+ */ >+ public ScpFromMessage(boolean verbose, Session session) { >+ super(verbose, session); >+ } >+ >+ /** > * Constructor for ScpFromMessage. > * @param verbose if true log extra information > * @param session the Scp session to use >diff -Naur ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java >--- ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java 1970-01-01 00:00:00.000000000 +0000 >+++ ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java 2006-04-13 09:21:34.000000000 +0000 >@@ -0,0 +1,177 @@ >+/* >+ * Copyright 2003-2005 The Apache Software Foundation >+ * >+ * Licensed under the Apache License, Version 2.0 (the "License"); >+ * you may not use this file except in compliance with the License. >+ * You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ * >+ */ >+ >+package org.apache.tools.ant.taskdefs.optional.ssh; >+ >+import java.io.File; >+import java.io.IOException; >+import java.io.EOFException; >+import java.io.InputStream; >+import java.io.OutputStream; >+import java.io.FileOutputStream; >+import java.io.ByteArrayOutputStream; >+ >+import com.jcraft.jsch.JSchException; >+import com.jcraft.jsch.Session; >+import com.jcraft.jsch.Channel; >+import com.jcraft.jsch.ChannelSftp; >+import com.jcraft.jsch.SftpException; >+import com.jcraft.jsch.SftpATTRS; >+import com.jcraft.jsch.SftpProgressMonitor; >+ >+/** >+ * A helper object representing an scp download. >+ */ >+public class ScpFromMessageBySftp extends ScpFromMessage { >+ >+ private String remoteFile; >+ private File localFile; >+ private boolean isRecursive = false; >+ private boolean verbose = false; >+ >+ >+ /** >+ * 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 >+ * @since Ant 1.6.2 >+ */ >+ public ScpFromMessageBySftp(boolean verbose, >+ Session session, >+ String aRemoteFile, >+ File aLocalFile, >+ boolean recursive) { >+ super(verbose, session); >+ this.verbose = verbose; >+ this.remoteFile = aRemoteFile; >+ this.localFile = aLocalFile; >+ this.isRecursive = recursive; >+ } >+ >+ /** >+ * Constructor for ScpFromMessageBySftp. >+ * @param session the Scp session to use >+ * @param aRemoteFile the remote file name >+ * @param aLocalFile the local file >+ * @param recursive if true use recursion >+ */ >+ public ScpFromMessageBySftp(Session session, >+ String aRemoteFile, >+ File aLocalFile, >+ boolean recursive) { >+ this(false, session, aRemoteFile, aLocalFile, recursive); >+ } >+ >+ /** >+ * Carry out the transfer. >+ * @throws IOException on i/o errors >+ * @throws JSchException on errors detected by scp >+ */ >+ public void execute() throws IOException, JSchException { >+ ChannelSftp channel = openSftpChannel(); >+ try { >+ channel.connect(); >+ try { >+ SftpATTRS attrs=channel.stat(remoteFile); >+ if(attrs.isDir() && !remoteFile.endsWith("/")){ >+ remoteFile=remoteFile+"/"; >+ } >+ } catch(SftpException ee) { >+ } >+ getDir(channel, remoteFile, localFile); >+ } catch(SftpException e) { >+ throw new JSchException(e.toString()); >+ } finally { >+ if (channel != null) { >+ channel.disconnect(); >+ } >+ } >+ log("done\n"); >+ } >+ >+ private void getDir(ChannelSftp channel, >+ String remoteFile, >+ File localFile) throws IOException, SftpException { >+ String pwd=remoteFile; >+ if(remoteFile.lastIndexOf('/')!=-1){ >+ if(remoteFile.length()>1) >+ pwd=remoteFile.substring(0, remoteFile.lastIndexOf('/')); >+ } >+ channel.cd(pwd); >+ if(!localFile.exists()){ >+ localFile.mkdirs(); >+ } >+ java.util.Vector files=channel.ls(remoteFile); >+ for(int i=0; i<files.size(); i++){ >+ ChannelSftp.LsEntry le=(ChannelSftp.LsEntry)files.elementAt(i); >+ String name=le.getFilename(); >+ if(le.getAttrs().isDir()){ >+ if(name.equals(".") || name.equals("..")){ >+ continue; >+ } >+ getDir(channel, >+ channel.pwd()+"/"+name+"/", >+ new File(localFile, le.getFilename())); >+ } >+ else{ >+ getFile(channel, le, localFile); >+ } >+ } >+ channel.cd(".."); >+ } >+ >+ private void getFile(ChannelSftp channel, >+ ChannelSftp.LsEntry le, >+ File localFile) throws IOException, SftpException { >+ String remoteFile=le.getFilename(); >+ if(!localFile.exists()){ >+ String path=localFile.getAbsolutePath(); >+ int i=0; >+ if((i=path.lastIndexOf(File.pathSeparator))!=-1){ >+ if(path.length()>File.pathSeparator.length()) >+ new File(path.substring(0, i)).mkdirs(); >+ } >+ } >+ >+ if(localFile.isDirectory()){ >+ localFile=new File(localFile, remoteFile); >+ } >+ >+ long startTime = System.currentTimeMillis(); >+ long totalLength=le.getAttrs().getSize(); >+ >+ ProgressMonitor monitor=null; >+ boolean trackProgress = getVerbose() && totalLength > 102400; >+ if(trackProgress){ >+ monitor=getProgressMonitor(); >+ } >+ try{ >+ log("Receiving: " + remoteFile + " : " + le.getAttrs().getSize()); >+ channel.get(remoteFile, localFile.getAbsolutePath(), monitor); >+ } >+ finally{ >+ long endTime = System.currentTimeMillis(); >+// if(monitor!=null && monitor.getTotalLength()<totalLength){ >+// totalLength=monitor.getTotalLength(); >+// } >+ logStats(startTime, endTime, (int)totalLength); >+ } >+ } >+} >diff -Naur ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java >--- ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java 2005-10-13 04:42:41.000000000 +0000 >+++ ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java 2006-04-13 09:22:41.000000000 +0000 >@@ -40,6 +40,24 @@ > private List directoryList; > > /** >+ * Constructor for ScpToMessage >+ * @param session the ssh session to use >+ */ >+ public ScpToMessage(Session session) { >+ super(session); >+ } >+ >+ /** >+ * Constructor for ScpToMessage >+ * @param verbose if true do verbose logging >+ * @param session the ssh session to use >+ * @since Ant 1.6.2 >+ */ >+ public ScpToMessage(boolean verbose, Session session) { >+ super(verbose, session); >+ } >+ >+ /** > * Constructor for a local file to remote. > * @param verbose if true do verbose logging > * @param session the scp session to use >diff -Naur ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java >--- ant/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java 1970-01-01 00:00:00.000000000 +0000 >+++ ant.new/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java 2006-04-13 09:22:10.000000000 +0000 >@@ -0,0 +1,234 @@ >+/* >+ * Copyright 2003-2005 The Apache Software Foundation >+ * >+ * Licensed under the Apache License, Version 2.0 (the "License"); >+ * you may not use this file except in compliance with the License. >+ * You may obtain a copy of the License at >+ * >+ * http://www.apache.org/licenses/LICENSE-2.0 >+ * >+ * Unless required by applicable law or agreed to in writing, software >+ * distributed under the License is distributed on an "AS IS" BASIS, >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ * >+ */ >+ >+package org.apache.tools.ant.taskdefs.optional.ssh; >+ >+import com.jcraft.jsch.Channel; >+import com.jcraft.jsch.Session; >+import com.jcraft.jsch.ChannelSftp; >+import com.jcraft.jsch.JSchException; >+import com.jcraft.jsch.SftpException; >+import com.jcraft.jsch.SftpProgressMonitor; >+import com.jcraft.jsch.SftpATTRS; >+ >+import java.io.File; >+import java.io.IOException; >+import java.io.InputStream; >+import java.io.FileInputStream; >+import java.io.OutputStream; >+import java.util.List; >+import java.util.Iterator; >+ >+public class ScpToMessageBySftp extends ScpToMessage/*AbstractSshMessage*/ { >+ >+ private File localFile; >+ private String remotePath; >+ private List directoryList; >+ >+ /** >+ * 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 ScpToMessageBySftp(boolean verbose, >+ Session session, >+ File aLocalFile, >+ String aRemotePath) { >+ this(verbose, session, aRemotePath); >+ >+ this.localFile = aLocalFile; >+ } >+ >+ /** >+ * 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 ScpToMessageBySftp(boolean verbose, >+ Session session, >+ List aDirectoryList, >+ String aRemotePath) { >+ this(verbose, session, aRemotePath); >+ >+ 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 >+ */ >+ private ScpToMessageBySftp(boolean verbose, >+ Session session, >+ String aRemotePath) { >+ super(verbose, session); >+ this.remotePath = aRemotePath; >+ } >+ >+ /** >+ * Constructor for ScpToMessage. >+ * @param session the scp session to use >+ * @param aLocalFile the local file >+ * @param aRemotePath the remote path >+ */ >+ public ScpToMessageBySftp(Session session, >+ File aLocalFile, >+ String aRemotePath) { >+ this(false, session, aLocalFile, aRemotePath); >+ } >+ >+ /** >+ * Constructor for ScpToMessage. >+ * @param session the scp session to use >+ * @param aDirectoryList a list of directories >+ * @param aRemotePath the remote path >+ */ >+ public ScpToMessageBySftp(Session session, >+ List aDirectoryList, >+ String aRemotePath) { >+ this(false, session, aDirectoryList, aRemotePath); >+ } >+ >+ /** >+ * Carry out the transfer. >+ * @throws IOException on i/o errors >+ * @throws JSchException on errors detected by scp >+ */ >+ public void execute() throws IOException, JSchException { >+ if (directoryList != null) { >+ doMultipleTransfer(); >+ } >+ if (localFile != null) { >+ doSingleTransfer(); >+ } >+ log("done.\n"); >+ } >+ >+ private void doSingleTransfer() throws IOException, JSchException { >+ ChannelSftp channel = openSftpChannel(); >+ try { >+ channel.connect(); >+ try{ >+ sendFileToRemote(channel, localFile, remotePath); >+ } >+ catch(SftpException e){ >+ throw new JSchException(e.toString()); >+ } >+ } finally { >+ if (channel != null) { >+ channel.disconnect(); >+ } >+ } >+ } >+ >+ private void doMultipleTransfer() throws IOException, JSchException { >+ ChannelSftp channel = openSftpChannel(); >+ try { >+ channel.connect(); >+ >+ try{ >+ channel.cd(remotePath); >+ for (Iterator i = directoryList.iterator(); i.hasNext();) { >+ Directory current = (Directory) i.next(); >+ sendDirectory(channel, current); >+ } >+ } >+ catch(SftpException e){ >+ throw new JSchException(e.toString()); >+ } >+ } finally { >+ if (channel != null) { >+ channel.disconnect(); >+ } >+ } >+ } >+ >+ private void sendDirectory(ChannelSftp channel, >+ Directory current) throws IOException, SftpException { >+ for (Iterator fileIt = current.filesIterator(); fileIt.hasNext();) { >+ sendFileToRemote(channel, (File) fileIt.next(), null); >+ } >+ for (Iterator dirIt = current.directoryIterator(); dirIt.hasNext();) { >+ Directory dir = (Directory) dirIt.next(); >+ sendDirectoryToRemote(channel, dir); >+ } >+ } >+ >+ private void sendDirectoryToRemote(ChannelSftp channel, >+ Directory directory) throws IOException, SftpException { >+ String dir=directory.getDirectory().getName(); >+ try{ >+ channel.stat(dir); >+ } >+ catch(SftpException e){ >+ // dir does not exist. >+ if(e.id==ChannelSftp.SSH_FX_NO_SUCH_FILE) >+ channel.mkdir(dir); >+ } >+ channel.cd(dir); >+ sendDirectory(channel, directory); >+ channel.cd(".."); >+ } >+ >+ private void sendFileToRemote(ChannelSftp channel, >+ File localFile, >+ String remotePath) throws IOException, SftpException { >+ long filesize = localFile.length(); >+ >+ if(remotePath==null){ >+ remotePath=localFile.getName(); >+ } >+ >+ long startTime = System.currentTimeMillis(); >+ long totalLength=filesize; >+ >+ // only track progress for files larger than 100kb in verbose mode >+ boolean trackProgress = getVerbose() && filesize > 102400; >+ >+ ProgressMonitor monitor=null; >+ if(trackProgress){ >+ monitor=getProgressMonitor(); >+ } >+ >+ try{ >+ log("Sending: " + localFile.getName() + " : " + filesize); >+ channel.put(localFile.getAbsolutePath(), remotePath, monitor); >+ } >+ finally { >+ long endTime = System.currentTimeMillis(); >+// if(monitor!=null && monitor.getTotalLength()<totalLength){ >+// totalLength=monitor.getTotalLength(); >+// } >+ logStats(startTime, endTime, (int)totalLength); >+ } >+ } >+ public File getLocalFile() { >+ return localFile; >+ } >+ >+ public String getRemotePath() { >+ return remotePath; >+ } >+} >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 39373
:
18147
|
18186
|
18251
|
18921