1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs.provider.sftp;
18
19 import com.jcraft.jsch.ChannelSftp;
20 import com.jcraft.jsch.JSchException;
21 import com.jcraft.jsch.Session;
22 import com.jcraft.jsch.SftpException;
23 import org.apache.commons.vfs.FileName;
24 import org.apache.commons.vfs.FileObject;
25 import org.apache.commons.vfs.FileSystem;
26 import org.apache.commons.vfs.FileSystemException;
27 import org.apache.commons.vfs.FileSystemOptions;
28 import org.apache.commons.vfs.UserAuthenticationData;
29 import org.apache.commons.vfs.util.UserAuthenticatorUtils;
30 import org.apache.commons.vfs.provider.AbstractFileSystem;
31 import org.apache.commons.vfs.provider.GenericFileName;
32
33 import java.io.IOException;
34 import java.util.Collection;
35
36 /***
37 * Represents the files on an SFTP server.
38 *
39 * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
40 * @version $Revision: 480428 $ $Date: 2006-11-29 07:15:24 +0100 (Mi, 29 Nov 2006) $
41 */
42 public class SftpFileSystem
43 extends AbstractFileSystem
44 implements FileSystem
45 {
46
47 private Session session;
48
49 private ChannelSftp idleChannel;
50
51 protected SftpFileSystem(final GenericFileName rootName,
52 final Session session,
53 final FileSystemOptions fileSystemOptions)
54 {
55 super(rootName, null, fileSystemOptions);
56 this.session = session;
57 }
58
59 protected void doCloseCommunicationLink()
60 {
61 if (idleChannel != null)
62 {
63 idleChannel.disconnect();
64 idleChannel = null;
65 }
66
67 if (session != null)
68 {
69 session.disconnect();
70 session = null;
71 }
72 }
73
74 /***
75 * Returns an SFTP channel to the server.
76 */
77 protected ChannelSftp getChannel() throws IOException
78 {
79 if (this.session == null)
80 {
81
82 Session session;
83 UserAuthenticationData authData = null;
84 try
85 {
86 final GenericFileName rootName = (GenericFileName) getRootName();
87
88 authData = UserAuthenticatorUtils.authenticate(getFileSystemOptions(), SftpFileProvider.AUTHENTICATOR_TYPES);
89
90 session = SftpClientFactory.createConnection(
91 rootName.getHostName(),
92 rootName.getPort(),
93 UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME, UserAuthenticatorUtils.toChar(rootName.getUserName())),
94 UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD, UserAuthenticatorUtils.toChar(rootName.getPassword())),
95 getFileSystemOptions());
96 }
97 catch (final Exception e)
98 {
99 throw new FileSystemException("vfs.provider.sftp/connect.error",
100 getRootName(),
101 e);
102 }
103 finally
104 {
105 UserAuthenticatorUtils.cleanup(authData);
106 }
107
108 this.session = session;
109 }
110
111 try
112 {
113
114 final ChannelSftp channel;
115 if (idleChannel != null)
116 {
117 channel = idleChannel;
118 idleChannel = null;
119 }
120 else
121 {
122 channel = (ChannelSftp) session.openChannel("sftp");
123 channel.connect();
124
125 Boolean userDirIsRoot = SftpFileSystemConfigBuilder.getInstance().getUserDirIsRoot(getFileSystemOptions());
126 String workingDirectory = getRootName().getPath();
127 if (workingDirectory != null && (userDirIsRoot == null || !userDirIsRoot.booleanValue()))
128 {
129 try
130 {
131 channel.cd(workingDirectory);
132 }
133 catch (SftpException e)
134 {
135 throw new FileSystemException("vfs.provider.sftp/change-work-directory.error", workingDirectory);
136 }
137 }
138 }
139
140 return channel;
141 }
142 catch (final JSchException e)
143 {
144 throw new FileSystemException("vfs.provider.sftp/connect.error",
145 getRootName(),
146 e);
147 }
148 }
149
150 /***
151 * Returns a channel to the pool.
152 */
153 protected void putChannel(final ChannelSftp channel)
154 {
155 if (idleChannel == null)
156 {
157
158 if (channel.isConnected() && !channel.isClosed())
159 {
160 idleChannel = channel;
161 }
162 }
163 else
164 {
165 channel.disconnect();
166 }
167 }
168
169 /***
170 * Adds the capabilities of this file system.
171 */
172 protected void addCapabilities(final Collection caps)
173 {
174 caps.addAll(SftpFileProvider.capabilities);
175 }
176
177 /***
178 * Creates a file object. This method is called only if the requested
179 * file is not cached.
180 */
181 protected FileObject createFile(final FileName name)
182 throws FileSystemException
183 {
184 return new SftpFileObject(name, this);
185 }
186
187 /***
188 * last mod time is only a int and in seconds, thus can be off by 999
189 *
190 * @return 1000
191 */
192 public double getLastModTimeAccuracy()
193 {
194 return 1000L;
195 }
196 }