source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 10.9 KB
Line 
1/*
2 * Copyright 2003-2004 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
18package org.apache.tools.ant.taskdefs.optional.ssh;
19
20import com.jcraft.jsch.JSchException;
21import com.jcraft.jsch.Session;
22
23import java.io.IOException;
24import java.io.File;
25
26import java.util.List;
27import java.util.LinkedList;
28import java.util.Iterator;
29import java.util.ArrayList;
30
31import org.apache.tools.ant.BuildException;
32import org.apache.tools.ant.DirectoryScanner;
33import org.apache.tools.ant.Project;
34import org.apache.tools.ant.types.FileSet;
35
36/**
37 * Ant task for sending files to remote machine over ssh/scp.
38 *
39 * @since Ant 1.6
40 */
41public class Scp extends SSHBase {
42
43 private String fromUri;
44 private String toUri;
45 private List fileSets = null;
46 private boolean isFromRemote, isToRemote;
47
48 /**
49 * Sets the file to be transferred. This can either be a remote
50 * file or a local file. Remote files take the form:<br>
51 * <i>user:password@host:/directory/path/file.example</i><br>
52 * Files to transfer can also include a wildcard to include all
53 * files in a remote directory. For example:<br>
54 * <i>user:password@host:/directory/path/*</i><br>
55 * @param aFromUri a string representing the file to transfer.
56 */
57 public void setFile(String aFromUri) {
58 this.fromUri = aFromUri;
59 this.isFromRemote = isRemoteUri(this.fromUri);
60 }
61
62 /**
63 * Sets the location where files will be transferred to.
64 * This can either be a remote directory or a local directory.
65 * Remote directories take the form of:<br>
66 * <i>user:password@host:/directory/path/</i><br>
67 * This parameter is required.
68
69 * @param aToUri a string representing the target of the copy.
70 */
71 public void setTodir(String aToUri) {
72 this.toUri = aToUri;
73 this.isToRemote = isRemoteUri(this.toUri);
74 }
75
76 /**
77 * Similiar to {@link #setFile setFile} but explicitly states that
78 * the file is a local file. This is the only way to specify a
79 * local file with a @ character.
80 * @since Ant 1.6.2
81 */
82 public void setLocalFile(String aFromUri) {
83 this.fromUri = aFromUri;
84 this.isFromRemote = false;
85 }
86
87 /**
88 * Similiar to {@link #setFile setFile} but explicitly states that
89 * the file is a remote file.
90 * @since Ant 1.6.2
91 */
92 public void setRemoteFile(String aFromUri) {
93 this.fromUri = aFromUri;
94 this.isFromRemote = true;
95 }
96
97 /**
98 * Similiar to {@link #setTodir setTodir} but explicitly states
99 * that the directory is a local. This is the only way to specify
100 * a local directory with a @ character.
101 * @since Ant 1.6.2
102 */
103 public void setLocalTodir(String aToUri) {
104 this.toUri = aToUri;
105 this.isToRemote = false;
106 }
107
108 /**
109 * Similiar to {@link #setTodir setTodir} but explicitly states
110 * that the directory is a remote.
111 * @since Ant 1.6.2
112 */
113 public void setRemoteTodir(String aToUri) {
114 this.toUri = aToUri;
115 this.isToRemote = true;
116 }
117
118 /**
119 * Changes the file name to the given name while receiving it,
120 * only useful if receiving a single file.
121 * @since Ant 1.6.2
122 */
123 public void setLocalTofile(String aToUri) {
124 this.toUri = aToUri;
125 this.isToRemote = false;
126 }
127
128 /**
129 * Changes the file name to the given name while sending it,
130 * only useful if sending a single file.
131 * @since Ant 1.6.2
132 */
133 public void setRemoteTofile(String aToUri) {
134 this.toUri = aToUri;
135 this.isToRemote = true;
136 }
137
138 /**
139 * Adds a FileSet tranfer to remote host. NOTE: Either
140 * addFileSet() or setFile() are required. But, not both.
141 *
142 * @param set FileSet to send to remote host.
143 */
144 public void addFileset(FileSet set) {
145 if (fileSets == null) {
146 fileSets = new LinkedList();
147 }
148 fileSets.add(set);
149 }
150
151 public void init() throws BuildException {
152 super.init();
153 this.toUri = null;
154 this.fromUri = null;
155 this.fileSets = null;
156 }
157
158 public void execute() throws BuildException {
159 if (toUri == null) {
160 throw new BuildException("Either 'todir' or 'tofile' attribute "
161 + "is required.");
162 }
163
164 if (fromUri == null && fileSets == null) {
165 throw new BuildException("Either the 'file' attribute or one "
166 + "FileSet is required.");
167 }
168
169 try {
170 if (isFromRemote && !isToRemote) {
171 download(fromUri, toUri);
172 } else if (!isFromRemote && isToRemote) {
173 if (fileSets != null) {
174 upload(fileSets, toUri);
175 } else {
176 upload(fromUri, toUri);
177 }
178 } else if (isFromRemote && isToRemote) {
179 throw new BuildException("Copying from a remote server to a remote server is not supported.");
180 } else {
181 throw new BuildException("'todir' and 'file' attributes "
182 + "must have syntax like the following: "
183 + "user:password@host:/path");
184 }
185 } catch (Exception e) {
186 if (getFailonerror()) {
187 throw new BuildException(e);
188 } else {
189 log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
190 }
191 }
192 }
193
194 private void download(String fromSshUri, String toPath)
195 throws JSchException, IOException {
196 String file = parseUri(fromSshUri);
197
198 Session session = null;
199 try {
200 session = openSession();
201 ScpFromMessage message =
202 new ScpFromMessage(getVerbose(), session, file,
203 getProject().resolveFile(toPath),
204 fromSshUri.endsWith("*"));
205 log("Receiving file: " + file);
206 message.setLogListener(this);
207 message.execute();
208 } finally {
209 if (session != null) {
210 session.disconnect();
211 }
212 }
213 }
214
215 private void upload(List fileSet, String toSshUri)
216 throws IOException, JSchException {
217 String file = parseUri(toSshUri);
218
219 Session session = null;
220 try {
221 List list = new ArrayList(fileSet.size());
222 for (Iterator i = fileSet.iterator(); i.hasNext();) {
223 FileSet set = (FileSet) i.next();
224 Directory d = createDirectory(set);
225 if (d != null) {
226 list.add(d);
227 }
228 }
229 if (!list.isEmpty()) {
230 session = openSession();
231 ScpToMessage message = new ScpToMessage(getVerbose(), session,
232 list, file);
233 message.setLogListener(this);
234 message.execute();
235 }
236 } finally {
237 if (session != null) {
238 session.disconnect();
239 }
240 }
241 }
242
243 private void upload(String fromPath, String toSshUri)
244 throws IOException, JSchException {
245 String file = parseUri(toSshUri);
246
247 Session session = null;
248 try {
249 session = openSession();
250 ScpToMessage message =
251 new ScpToMessage(getVerbose(), session,
252 getProject().resolveFile(fromPath), file);
253 message.setLogListener(this);
254 message.execute();
255 } finally {
256 if (session != null) {
257 session.disconnect();
258 }
259 }
260 }
261
262 private String parseUri(String uri) {
263 int indexOfAt = uri.indexOf('@');
264 int indexOfColon = uri.indexOf(':');
265 if (indexOfColon > -1 && indexOfColon < indexOfAt) {
266 // user:password@host:/path notation
267 setUsername(uri.substring(0, indexOfColon));
268 setPassword(uri.substring(indexOfColon + 1, indexOfAt));
269 } else {
270 // no password, will require passphrase
271 setUsername(uri.substring(0, indexOfAt));
272 }
273
274 if (getUserInfo().getPassword() == null
275 && getUserInfo().getPassphrase() == null) {
276 throw new BuildException("neither password nor passphrase for user "
277 + getUserInfo().getName() + " has been "
278 + "given. Can't authenticate.");
279 }
280
281 int indexOfPath = uri.indexOf(':', indexOfAt + 1);
282 if (indexOfPath == -1) {
283 throw new BuildException("no remote path in " + uri);
284 }
285
286 setHost(uri.substring(indexOfAt + 1, indexOfPath));
287 String remotePath = uri.substring(indexOfPath + 1);
288 if (remotePath.equals("")) {
289 remotePath = ".";
290 }
291 return remotePath;
292 }
293
294 private boolean isRemoteUri(String uri) {
295 boolean isRemote = true;
296 int indexOfAt = uri.indexOf('@');
297 if (indexOfAt < 0) {
298 isRemote = false;
299 }
300 return isRemote;
301 }
302
303 private Directory createDirectory(FileSet set) {
304 DirectoryScanner scanner = set.getDirectoryScanner(getProject());
305 Directory root = new Directory(scanner.getBasedir());
306 String[] files = scanner.getIncludedFiles();
307 if (files.length != 0) {
308 for (int j = 0; j < files.length; j++) {
309 String[] path = Directory.getPath(files[j]);
310 Directory current = root;
311 File currentParent = scanner.getBasedir();
312 for (int i = 0; i < path.length; i++) {
313 File file = new File(currentParent, path[i]);
314 if (file.isDirectory()) {
315 current.addDirectory(new Directory(file));
316 current = current.getChild(file);
317 currentParent = current.getDirectory();
318 } else if (file.isFile()) {
319 current.addFile(file);
320 }
321 }
322 }
323 } else {
324 // skip
325 root = null;
326 }
327 return root;
328 }
329}
Note: See TracBrowser for help on using the repository browser.