1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.commons.ssh.ganymed;
17
18 import java.io.*;
19 import java.util.ArrayList;
20 import java.util.Iterator;
21 import java.util.List;
22
23 import net.sf.commons.ssh.SftpFile;
24 import net.sf.commons.ssh.SftpFileAttributes;
25 import net.sf.commons.ssh.SftpSession;
26 import net.sf.commons.ssh.SftpSessionOptions;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import ch.ethz.ssh2.SFTPv3Client;
32 import ch.ethz.ssh2.SFTPv3DirectoryEntry;
33 import ch.ethz.ssh2.SFTPv3FileAttributes;
34 import ch.ethz.ssh2.SFTPv3FileHandle;
35
36 /***
37 * @author Egor Ivanov (crackcraft at gmail dot com)
38 * @since 1.2
39 */
40 class GanymedSftpSession implements SftpSession {
41 static SftpFileAttributes convertFileAttributes(final SFTPv3FileAttributes a) {
42 return new SftpFileAttributes() {
43
44 public long getAccessedTime() {
45 return (a.atime != null) ? a.atime.longValue() : 0;
46 }
47
48 public long getGID() {
49 return (a.gid != null) ? a.gid.longValue() : 0;
50 }
51
52 public long getModifiedTime() {
53 return (a.mtime != null) ? a.mtime.longValue() : 0;
54 }
55
56 public long getPermissions() {
57 return (a.permissions != null) ? a.permissions.longValue() : 0;
58 }
59
60 public long getSize() {
61 return (a.size != null) ? a.size.longValue() : 0;
62 }
63
64 public long getUID() {
65 return (a.uid != null) ? a.uid.longValue() : 0;
66 }
67
68 public boolean isBlock() {
69 return (a.permissions != null)
70 && ((a.permissions.intValue() & 0xF000) == 0x1000);
71 }
72
73 public boolean isCharacter() {
74 return (a.permissions != null)
75 && ((a.permissions.intValue() & 0xF000) == 0x2000);
76 }
77
78 public boolean isDirectory() {
79 return a.isDirectory();
80 }
81
82 public boolean isFifo() {
83 return (a.permissions != null)
84 && ((a.permissions.intValue() & 0xF000) == 0x6000);
85 }
86
87 public boolean isFile() {
88 return a.isRegularFile();
89 }
90
91 public boolean isLink() {
92 return a.isSymlink();
93 }
94
95 public boolean isSocket() {
96 return (a.permissions != null)
97 && ((a.permissions.intValue() & 0xF000) == 0xC000);
98 }
99 };
100 }
101
102 private static List convertFileList(List files) {
103 ArrayList out = new ArrayList(files.size());
104 for (Iterator it = files.iterator(); it.hasNext();) {
105 final SFTPv3DirectoryEntry f = (SFTPv3DirectoryEntry) it.next();
106 out.add(new SftpFile() {
107 public String getAbsolutePath() {
108 return f.filename;
109 }
110
111 public SftpFileAttributes getAttributes() {
112 return convertFileAttributes(f.attributes);
113 }
114
115 public String getName() {
116 return (f.filename.lastIndexOf("/") < 0) ? f.filename
117 : f.filename
118 .substring(f.filename.lastIndexOf("/") + 1);
119 }
120 });
121 }
122 return out;
123 }
124
125 private final Log log = LogFactory.getLog(this.getClass());
126 private String lwd;
127 private String rwd;
128
129 private final SFTPv3Client sftp;
130
131 private int umask;
132
133 GanymedSftpSession(final SFTPv3Client sftp, SftpSessionOptions opts)
134 throws IOException {
135 log.trace("<init>");
136 this.sftp = sftp;
137 umask(opts.defaultPermissions);
138 cd((opts.remoteCurrentDirectory != null) ? opts.remoteCurrentDirectory
139 : "");
140 lcd((opts.localCurrentDirectory != null) ? opts.localCurrentDirectory
141 : "");
142 }
143
144 public void cd(String dir) throws IOException {
145 String rwd2 = sftp.canonicalPath(rpath(dir));
146 SFTPv3FileAttributes a = sftp.stat(rwd2);
147 if (!a.isDirectory()) {
148 throw new IOException(dir + " is not a directory");
149 }
150
151 rwd = rwd2;
152 }
153
154 public void chgrp(int gid, String path) throws IOException {
155 SFTPv3FileAttributes a = new SFTPv3FileAttributes();
156 a.gid = new Integer(gid);
157 sftp.setstat(rpath(path), a);
158 }
159
160 public void chmod(int permissions, String path) throws IOException {
161 SFTPv3FileAttributes a = new SFTPv3FileAttributes();
162 a.permissions = new Integer(permissions);
163 sftp.setstat(rpath(path), a);
164 }
165
166
167
168
169
170 public void chown(int uid, String path) throws IOException {
171 SFTPv3FileAttributes a = new SFTPv3FileAttributes();
172 a.uid = new Integer(uid);
173 sftp.setstat(rpath(path), a);
174 }
175
176 public void close() throws IOException {
177 sftp.close();
178 }
179
180 public void get(String path) throws IOException {
181 get(path, path);
182 }
183
184 public void get(String remote, OutputStream local) throws IOException {
185 SFTPv3FileHandle h = sftp.openFileRO(rpath(remote));
186 byte[] buff = new byte[32768];
187 long off = 0;
188 while (true) {
189 int res = sftp.read(h, off, buff, 0, buff.length);
190 if (res == -1) {
191 break;
192 }
193 if (res > 0) {
194 local.write(buff, 0, res);
195 off += res;
196 }
197
198 }
199 sftp.closeFile(h);
200 }
201
202 public void get(String remote, String local) throws IOException {
203 if ((local.lastIndexOf('/') == local.length() - 1)
204 || lpath(local).isDirectory()) {
205 int pos = remote.lastIndexOf('/');
206 String filename = (pos >= 0) ? remote.substring(pos + 1) : remote;
207 local = local + '/' + filename;
208 }
209 File f = lpath(local);
210 if (!f.exists()) {
211 f.getParentFile().mkdirs();
212 }
213 OutputStream os = new FileOutputStream(f);
214 try {
215 get(remote, os);
216 } finally {
217 os.close();
218 }
219 }
220
221 public String getAbsolutePath(String path) throws IOException {
222 return sftp.canonicalPath(rpath(path));
223 }
224
225 public boolean isClosed() throws IOException {
226 try {
227 sftp.stat(".");
228 } catch (IOException ex) {
229 return true;
230 }
231
232 return false;
233 }
234
235 public void lcd(String path) throws IOException {
236 File f = lpath(path);
237 if (!f.isDirectory()) {
238 throw new IOException(path + " is not a directory");
239 }
240 lwd = f.getCanonicalPath();
241 }
242
243 private File lpath(String path) {
244 File f = new File(path);
245 if (!f.isAbsolute()) {
246 f = new File(((lwd != null) ? lwd : ""), path);
247 }
248 return f;
249 }
250
251 public String lpwd() {
252 return lwd;
253 }
254
255 public List ls() throws IOException {
256 return ls(".");
257 }
258
259 public List ls(String path) throws IOException {
260 return convertFileList(sftp.ls(rpath(path)));
261 }
262
263 public void mkdir(String dir) throws IOException {
264 sftp.mkdir(rpath(dir), 0777 ^ umask);
265 }
266
267 public void put(InputStream in, String remote) throws IOException {
268 SFTPv3FileAttributes a = new SFTPv3FileAttributes();
269 a.permissions = new Integer(0777 ^ umask);
270 SFTPv3FileHandle h = sftp.createFileTruncate(rpath(remote), a);
271 byte[] buff = new byte[32768];
272 long off = 0;
273 while (true) {
274 int res = in.read(buff);
275 if (res == -1) {
276 break;
277 }
278 if (res > 0) {
279 sftp.write(h, off, buff, 0, res);
280 off += res;
281 }
282 }
283 sftp.closeFile(h);
284 }
285
286 public void put(String local) throws IOException {
287 put(local, local);
288 }
289
290 public void put(String local, String remote) throws IOException {
291 File f = lpath(local);
292 if (!f.exists() && !f.isFile()) {
293 throw new IOException("File not found " + f.getCanonicalPath());
294 }
295 if (remote.lastIndexOf('/') == remote.length() - 1) {
296 remote = remote + f.getName();
297 }
298 InputStream is = new FileInputStream(f);
299 try {
300 put(is, remote);
301 } finally {
302 is.close();
303 }
304 }
305
306 public String pwd() throws IOException {
307 return rpath("");
308 }
309
310
311
312
313
314
315 public void rename(String oldpath, String newpath) throws IOException {
316 sftp.mv(rpath(oldpath), rpath(newpath));
317 }
318
319 public void rm(String path) throws IOException {
320 SFTPv3FileAttributes a = sftp.stat(rpath(path));
321 if (a.isDirectory()) {
322 sftp.rmdir(rpath(path));
323 } else {
324 sftp.rm(rpath(path));
325 }
326 }
327
328 private String rpath(String path) throws IOException {
329 if (path.startsWith("/")) {
330 return path;
331 }
332 if (rwd == null) {
333 rwd = sftp.canonicalPath("");
334 }
335 return rwd + (rwd.endsWith("/") ? "" : "/") + path;
336 }
337
338 public SftpFileAttributes stat(String path) throws IOException {
339 return convertFileAttributes(sftp.stat(rpath(path)));
340 }
341
342 public void symlink(String path, String link) throws IOException {
343
344
345
346 sftp.createSymlink(path, rpath(link));
347 }
348
349 public void umask(int umask) {
350 this.umask = umask;
351 }
352 }