Line 0
Link Here
|
|
|
1 |
/* |
2 |
* Copyright 2003-2005 The Apache Software Foundation |
3 |
* |
4 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
5 |
* you may not use this file except in compliance with the License. |
6 |
* You may obtain a copy of the License at |
7 |
* |
8 |
* http://www.apache.org/licenses/LICENSE-2.0 |
9 |
* |
10 |
* Unless required by applicable law or agreed to in writing, software |
11 |
* distributed under the License is distributed on an "AS IS" BASIS, |
12 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 |
* See the License for the specific language governing permissions and |
14 |
* limitations under the License. |
15 |
* |
16 |
*/ |
17 |
|
18 |
package org.apache.tools.ant.taskdefs.optional.ssh; |
19 |
|
20 |
import com.jcraft.jsch.Channel; |
21 |
import com.jcraft.jsch.Session; |
22 |
import com.jcraft.jsch.ChannelSftp; |
23 |
import com.jcraft.jsch.JSchException; |
24 |
import com.jcraft.jsch.SftpException; |
25 |
import com.jcraft.jsch.SftpProgressMonitor; |
26 |
import com.jcraft.jsch.SftpATTRS; |
27 |
|
28 |
import java.io.File; |
29 |
import java.io.IOException; |
30 |
import java.io.InputStream; |
31 |
import java.io.FileInputStream; |
32 |
import java.io.OutputStream; |
33 |
import java.util.List; |
34 |
import java.util.Iterator; |
35 |
|
36 |
public class ScpToMessageBySftp extends ScpToMessage/*AbstractSshMessage*/ { |
37 |
|
38 |
private File localFile; |
39 |
private String remotePath; |
40 |
private List directoryList; |
41 |
|
42 |
/** |
43 |
* Constructor for a local file to remote. |
44 |
* @param verbose if true do verbose logging |
45 |
* @param session the scp session to use |
46 |
* @param aLocalFile the local file |
47 |
* @param aRemotePath the remote path |
48 |
* @since Ant 1.6.2 |
49 |
*/ |
50 |
public ScpToMessageBySftp(boolean verbose, |
51 |
Session session, |
52 |
File aLocalFile, |
53 |
String aRemotePath) { |
54 |
this(verbose, session, aRemotePath); |
55 |
|
56 |
this.localFile = aLocalFile; |
57 |
} |
58 |
|
59 |
/** |
60 |
* Constructor for a local directories to remote. |
61 |
* @param verbose if true do verbose logging |
62 |
* @param session the scp session to use |
63 |
* @param aDirectoryList a list of directories |
64 |
* @param aRemotePath the remote path |
65 |
* @since Ant 1.6.2 |
66 |
*/ |
67 |
public ScpToMessageBySftp(boolean verbose, |
68 |
Session session, |
69 |
List aDirectoryList, |
70 |
String aRemotePath) { |
71 |
this(verbose, session, aRemotePath); |
72 |
|
73 |
this.directoryList = aDirectoryList; |
74 |
} |
75 |
|
76 |
/** |
77 |
* Constructor for ScpToMessage. |
78 |
* @param verbose if true do verbose logging |
79 |
* @param session the scp session to use |
80 |
* @param aRemotePath the remote path |
81 |
* @since Ant 1.6.2 |
82 |
*/ |
83 |
private ScpToMessageBySftp(boolean verbose, |
84 |
Session session, |
85 |
String aRemotePath) { |
86 |
super(verbose, session); |
87 |
this.remotePath = aRemotePath; |
88 |
} |
89 |
|
90 |
/** |
91 |
* Constructor for ScpToMessage. |
92 |
* @param session the scp session to use |
93 |
* @param aLocalFile the local file |
94 |
* @param aRemotePath the remote path |
95 |
*/ |
96 |
public ScpToMessageBySftp(Session session, |
97 |
File aLocalFile, |
98 |
String aRemotePath) { |
99 |
this(false, session, aLocalFile, aRemotePath); |
100 |
} |
101 |
|
102 |
/** |
103 |
* Constructor for ScpToMessage. |
104 |
* @param session the scp session to use |
105 |
* @param aDirectoryList a list of directories |
106 |
* @param aRemotePath the remote path |
107 |
*/ |
108 |
public ScpToMessageBySftp(Session session, |
109 |
List aDirectoryList, |
110 |
String aRemotePath) { |
111 |
this(false, session, aDirectoryList, aRemotePath); |
112 |
} |
113 |
|
114 |
/** |
115 |
* Carry out the transfer. |
116 |
* @throws IOException on i/o errors |
117 |
* @throws JSchException on errors detected by scp |
118 |
*/ |
119 |
public void execute() throws IOException, JSchException { |
120 |
if (directoryList != null) { |
121 |
doMultipleTransfer(); |
122 |
} |
123 |
if (localFile != null) { |
124 |
doSingleTransfer(); |
125 |
} |
126 |
log("done.\n"); |
127 |
} |
128 |
|
129 |
private void doSingleTransfer() throws IOException, JSchException { |
130 |
ChannelSftp channel = openSftpChannel(); |
131 |
try { |
132 |
channel.connect(); |
133 |
try{ |
134 |
sendFileToRemote(channel, localFile, remotePath); |
135 |
} |
136 |
catch(SftpException e){ |
137 |
throw new JSchException(e.toString()); |
138 |
} |
139 |
} finally { |
140 |
if (channel != null) { |
141 |
channel.disconnect(); |
142 |
} |
143 |
} |
144 |
} |
145 |
|
146 |
private void doMultipleTransfer() throws IOException, JSchException { |
147 |
ChannelSftp channel = openSftpChannel(); |
148 |
try { |
149 |
channel.connect(); |
150 |
|
151 |
try{ |
152 |
channel.cd(remotePath); |
153 |
for (Iterator i = directoryList.iterator(); i.hasNext();) { |
154 |
Directory current = (Directory) i.next(); |
155 |
sendDirectory(channel, current); |
156 |
} |
157 |
} |
158 |
catch(SftpException e){ |
159 |
throw new JSchException(e.toString()); |
160 |
} |
161 |
} finally { |
162 |
if (channel != null) { |
163 |
channel.disconnect(); |
164 |
} |
165 |
} |
166 |
} |
167 |
|
168 |
private void sendDirectory(ChannelSftp channel, |
169 |
Directory current) throws IOException, SftpException { |
170 |
for (Iterator fileIt = current.filesIterator(); fileIt.hasNext();) { |
171 |
sendFileToRemote(channel, (File) fileIt.next(), null); |
172 |
} |
173 |
for (Iterator dirIt = current.directoryIterator(); dirIt.hasNext();) { |
174 |
Directory dir = (Directory) dirIt.next(); |
175 |
sendDirectoryToRemote(channel, dir); |
176 |
} |
177 |
} |
178 |
|
179 |
private void sendDirectoryToRemote(ChannelSftp channel, |
180 |
Directory directory) throws IOException, SftpException { |
181 |
String dir=directory.getDirectory().getName(); |
182 |
try{ |
183 |
channel.stat(dir); |
184 |
} |
185 |
catch(SftpException e){ |
186 |
// dir does not exist. |
187 |
if(e.id==ChannelSftp.SSH_FX_NO_SUCH_FILE) |
188 |
channel.mkdir(dir); |
189 |
} |
190 |
channel.cd(dir); |
191 |
sendDirectory(channel, directory); |
192 |
channel.cd(".."); |
193 |
} |
194 |
|
195 |
private void sendFileToRemote(ChannelSftp channel, |
196 |
File localFile, |
197 |
String remotePath) throws IOException, SftpException { |
198 |
long filesize = localFile.length(); |
199 |
|
200 |
if(remotePath==null){ |
201 |
remotePath=localFile.getName(); |
202 |
} |
203 |
|
204 |
long startTime = System.currentTimeMillis(); |
205 |
long totalLength=filesize; |
206 |
|
207 |
// only track progress for files larger than 100kb in verbose mode |
208 |
boolean trackProgress = getVerbose() && filesize > 102400; |
209 |
|
210 |
ProgressMonitor monitor=null; |
211 |
if(trackProgress){ |
212 |
monitor=getProgressMonitor(); |
213 |
} |
214 |
|
215 |
try{ |
216 |
log("Sending: " + localFile.getName() + " : " + filesize); |
217 |
channel.put(localFile.getAbsolutePath(), remotePath, monitor); |
218 |
} |
219 |
finally { |
220 |
long endTime = System.currentTimeMillis(); |
221 |
// if(monitor!=null && monitor.getTotalLength()<totalLength){ |
222 |
// totalLength=monitor.getTotalLength(); |
223 |
// } |
224 |
logStats(startTime, endTime, (int)totalLength); |
225 |
} |
226 |
} |
227 |
public File getLocalFile() { |
228 |
return localFile; |
229 |
} |
230 |
|
231 |
public String getRemotePath() { |
232 |
return remotePath; |
233 |
} |
234 |
} |