Mercurial > 510Connectbot
comparison src/ch/ethz/ssh2/SFTPv6Client.java @ 273:91a31873c42a ganymed
start conversion from trilead to ganymed
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 18 Jul 2014 11:21:46 -0700 |
parents | |
children | d2b303406d63 |
comparison
equal
deleted
inserted
replaced
272:ce2f4e397703 | 273:91a31873c42a |
---|---|
1 package ch.ethz.ssh2; | |
2 | |
3 import java.io.IOException; | |
4 import java.util.ArrayList; | |
5 import java.util.List; | |
6 | |
7 import ch.ethz.ssh2.log.Logger; | |
8 import ch.ethz.ssh2.packets.TypesReader; | |
9 import ch.ethz.ssh2.packets.TypesWriter; | |
10 import ch.ethz.ssh2.sftp.AceMask; | |
11 import ch.ethz.ssh2.sftp.ErrorCodes; | |
12 import ch.ethz.ssh2.sftp.OpenFlags; | |
13 import ch.ethz.ssh2.sftp.Packet; | |
14 | |
15 /** | |
16 * @version $Id: SFTPv6Client.java 151 2014-04-28 10:03:39Z dkocher@sudo.ch $ | |
17 */ | |
18 public class SFTPv6Client extends AbstractSFTPClient { | |
19 private static final Logger log = Logger.getLogger(SFTPv6Client.class); | |
20 | |
21 private PacketListener listener; | |
22 | |
23 public SFTPv6Client(Connection conn) throws IOException { | |
24 this(conn, new PacketListener() { | |
25 public void read(String packet) { | |
26 log.debug("Read packet " + packet); | |
27 } | |
28 | |
29 public void write(String packet) { | |
30 log.debug("Write packet " + packet); | |
31 } | |
32 }); | |
33 } | |
34 | |
35 public SFTPv6Client(Connection conn, PacketListener listener) throws IOException { | |
36 super(conn, 6, listener); | |
37 this.listener = listener; | |
38 } | |
39 | |
40 @Override | |
41 public SFTPv6FileAttributes fstat(SFTPFileHandle handle) throws IOException { | |
42 int req_id = generateNextRequestID(); | |
43 | |
44 TypesWriter tw = new TypesWriter(); | |
45 tw.writeString(handle.getHandle(), 0, handle.getHandle().length); | |
46 | |
47 sendMessage(Packet.SSH_FXP_FSTAT, req_id, tw.getBytes()); | |
48 | |
49 byte[] resp = receiveMessage(34000); | |
50 | |
51 TypesReader tr = new TypesReader(resp); | |
52 | |
53 int t = tr.readByte(); | |
54 listener.read(Packet.forName(t)); | |
55 | |
56 int rep_id = tr.readUINT32(); | |
57 if(rep_id != req_id) { | |
58 throw new RequestMismatchException(); | |
59 } | |
60 | |
61 if(t == Packet.SSH_FXP_ATTRS) { | |
62 return new SFTPv6FileAttributes(tr); | |
63 } | |
64 | |
65 if(t != Packet.SSH_FXP_STATUS) { | |
66 throw new PacketTypeException(t); | |
67 } | |
68 | |
69 int errorCode = tr.readUINT32(); | |
70 String errorMessage = tr.readString(); | |
71 listener.read(errorMessage); | |
72 throw new SFTPException(errorMessage, errorCode); | |
73 } | |
74 | |
75 private SFTPv6FileAttributes statBoth(String path, int statMethod) throws IOException { | |
76 int req_id = generateNextRequestID(); | |
77 | |
78 TypesWriter tw = new TypesWriter(); | |
79 tw.writeString(path, this.getCharset()); | |
80 | |
81 sendMessage(statMethod, req_id, tw.getBytes()); | |
82 | |
83 byte[] resp = receiveMessage(34000); | |
84 | |
85 TypesReader tr = new TypesReader(resp); | |
86 | |
87 int t = tr.readByte(); | |
88 listener.read(Packet.forName(t)); | |
89 | |
90 int rep_id = tr.readUINT32(); | |
91 if(rep_id != req_id) { | |
92 throw new RequestMismatchException(); | |
93 } | |
94 | |
95 if(t == Packet.SSH_FXP_ATTRS) { | |
96 return new SFTPv6FileAttributes(tr); | |
97 } | |
98 | |
99 if(t != Packet.SSH_FXP_STATUS) { | |
100 throw new PacketTypeException(t); | |
101 } | |
102 | |
103 int errorCode = tr.readUINT32(); | |
104 String errorMessage = tr.readString(); | |
105 listener.read(errorMessage); | |
106 throw new SFTPException(errorMessage, errorCode); | |
107 } | |
108 | |
109 @Override | |
110 public SFTPv6FileAttributes stat(String path) throws IOException { | |
111 return statBoth(path, Packet.SSH_FXP_STAT); | |
112 } | |
113 | |
114 @Override | |
115 public SFTPv6FileAttributes lstat(String path) throws IOException { | |
116 return statBoth(path, Packet.SSH_FXP_LSTAT); | |
117 } | |
118 | |
119 | |
120 private List<SFTPv6DirectoryEntry> scanDirectory(byte[] handle) throws IOException { | |
121 List<SFTPv6DirectoryEntry> files = new ArrayList<SFTPv6DirectoryEntry>(); | |
122 | |
123 while(true) { | |
124 int req_id = generateNextRequestID(); | |
125 | |
126 TypesWriter tw = new TypesWriter(); | |
127 tw.writeString(handle, 0, handle.length); | |
128 | |
129 sendMessage(Packet.SSH_FXP_READDIR, req_id, tw.getBytes()); | |
130 | |
131 byte[] resp = receiveMessage(34000); | |
132 | |
133 TypesReader tr = new TypesReader(resp); | |
134 | |
135 int t = tr.readByte(); | |
136 listener.read(Packet.forName(t)); | |
137 int rep_id = tr.readUINT32(); | |
138 if(rep_id != req_id) { | |
139 throw new RequestMismatchException(); | |
140 } | |
141 if(t == Packet.SSH_FXP_NAME) { | |
142 int count = tr.readUINT32(); | |
143 if(log.isDebugEnabled()) { | |
144 log.debug(String.format("Parsing %d name entries", count)); | |
145 } | |
146 while(count > 0) { | |
147 SFTPv6DirectoryEntry file = new SFTPv6DirectoryEntry(); | |
148 file.filename = tr.readString(this.getCharset()); | |
149 listener.read(file.filename); | |
150 file.attributes = new SFTPv6FileAttributes(tr); | |
151 if(log.isDebugEnabled()) { | |
152 log.debug(String.format("Adding file %s", file)); | |
153 } | |
154 files.add(file); | |
155 count--; | |
156 } | |
157 continue; | |
158 } | |
159 if(t != Packet.SSH_FXP_STATUS) { | |
160 throw new PacketTypeException(t); | |
161 } | |
162 int errorCode = tr.readUINT32(); | |
163 if(errorCode == ErrorCodes.SSH_FX_EOF) { | |
164 return files; | |
165 } | |
166 String errorMessage = tr.readString(); | |
167 listener.read(errorMessage); | |
168 throw new SFTPException(errorMessage, errorCode); | |
169 } | |
170 } | |
171 | |
172 @Override | |
173 public final SFTPFileHandle openDirectory(String path) throws IOException { | |
174 int req_id = generateNextRequestID(); | |
175 | |
176 TypesWriter tw = new TypesWriter(); | |
177 tw.writeString(path, this.getCharset()); | |
178 | |
179 sendMessage(Packet.SSH_FXP_OPENDIR, req_id, tw.getBytes()); | |
180 | |
181 byte[] resp = receiveMessage(34000); | |
182 | |
183 TypesReader tr = new TypesReader(resp); | |
184 | |
185 int t = tr.readByte(); | |
186 listener.read(Packet.forName(t)); | |
187 | |
188 int rep_id = tr.readUINT32(); | |
189 if(rep_id != req_id) { | |
190 throw new RequestMismatchException(); | |
191 } | |
192 | |
193 if(t == Packet.SSH_FXP_HANDLE) { | |
194 return new SFTPFileHandle(this, tr.readByteString()); | |
195 } | |
196 | |
197 if(t != Packet.SSH_FXP_STATUS) { | |
198 throw new PacketTypeException(t); | |
199 } | |
200 | |
201 int errorCode = tr.readUINT32(); | |
202 String errorMessage = tr.readString(); | |
203 listener.read(errorMessage); | |
204 throw new SFTPException(errorMessage, errorCode); | |
205 } | |
206 | |
207 /** | |
208 * List the contents of a directory. | |
209 * | |
210 * @param dirName See the {@link SFTPv6Client comment} for the class for more details. | |
211 * @return A Vector containing {@link SFTPv6DirectoryEntry} objects. | |
212 * @throws IOException | |
213 */ | |
214 @Override | |
215 public List<SFTPv6DirectoryEntry> ls(String dirName) throws IOException { | |
216 SFTPFileHandle handle = openDirectory(dirName); | |
217 List<SFTPv6DirectoryEntry> result = scanDirectory(handle.getHandle()); | |
218 closeFile(handle); | |
219 return result; | |
220 } | |
221 | |
222 /** | |
223 * Create a file and open it for reading and writing. | |
224 * Same as {@link #createFile(String, SFTPFileAttributes) createFile(fileName, null)}. | |
225 * | |
226 * @param filename See the {@link SFTPv6Client comment} for the class for more details. | |
227 * @return a SFTPFileHandle handle | |
228 * @throws IOException | |
229 */ | |
230 @Override | |
231 public SFTPFileHandle createFile(String filename) throws IOException { | |
232 return createFile(filename, new SFTPv6FileAttributes()); | |
233 } | |
234 | |
235 /** | |
236 * Create a file and open it for reading and writing. | |
237 * You can specify the default attributes of the file (the server may or may | |
238 * not respect your wishes). | |
239 * | |
240 * @param filename See the {@link SFTPv6Client comment} for the class for more details. | |
241 * @param attr may be <code>null</code> to use server defaults. Probably only | |
242 * the <code>uid</code>, <code>gid</code> and <code>permissions</code> | |
243 * (remember the server may apply a umask) entries of the {@link SFTPFileHandle} | |
244 * structure make sense. You need only to set those fields where you want | |
245 * to override the server's defaults. | |
246 * @return a SFTPFileHandle handle | |
247 * @throws IOException | |
248 */ | |
249 @Override | |
250 public SFTPFileHandle createFile(String filename, SFTPFileAttributes attr) throws IOException { | |
251 return openFile(filename, OpenFlags.SSH_FXF_CREATE_NEW, attr); | |
252 } | |
253 | |
254 @Override | |
255 public SFTPFileHandle openFile(String filename, int flags) throws IOException { | |
256 return this.openFile(filename, flags, new SFTPv6FileAttributes()); | |
257 } | |
258 | |
259 @Override | |
260 public SFTPFileHandle openFile(String filename, int flags, SFTPFileAttributes attr) throws IOException { | |
261 int req_id = generateNextRequestID(); | |
262 | |
263 TypesWriter tw = new TypesWriter(); | |
264 tw.writeString(filename, this.getCharset()); | |
265 tw.writeUINT32(AceMask.ACE4_READ_DATA | AceMask.ACE4_READ_ATTRIBUTES | AceMask.ACE4_READ_ACL | AceMask.ACE4_READ_NAMED_ATTRS | |
266 | AceMask.ACE4_WRITE_DATA | AceMask.ACE4_APPEND_DATA | AceMask.ACE4_WRITE_ATTRIBUTES | AceMask.ACE4_WRITE_ACL | AceMask.ACE4_WRITE_NAMED_ATTRS); | |
267 tw.writeUINT32(flags); | |
268 | |
269 tw.writeBytes(attr.toBytes()); | |
270 | |
271 sendMessage(Packet.SSH_FXP_OPEN, req_id, tw.getBytes()); | |
272 | |
273 byte[] resp = receiveMessage(34000); | |
274 | |
275 TypesReader tr = new TypesReader(resp); | |
276 | |
277 int t = tr.readByte(); | |
278 listener.read(Packet.forName(t)); | |
279 | |
280 int rep_id = tr.readUINT32(); | |
281 if(rep_id != req_id) { | |
282 throw new RequestMismatchException(); | |
283 } | |
284 | |
285 if(t == Packet.SSH_FXP_HANDLE) { | |
286 return new SFTPFileHandle(this, tr.readByteString()); | |
287 } | |
288 | |
289 if(t != Packet.SSH_FXP_STATUS) { | |
290 throw new PacketTypeException(t); | |
291 } | |
292 | |
293 int errorCode = tr.readUINT32(); | |
294 String errorMessage = tr.readString(); | |
295 listener.read(errorMessage); | |
296 throw new SFTPException(errorMessage, errorCode); | |
297 } | |
298 | |
299 @Override | |
300 public void createSymlink(String src, String target) throws IOException { | |
301 int req_id = generateNextRequestID(); | |
302 | |
303 TypesWriter tw = new TypesWriter(); | |
304 // new-link-path | |
305 tw.writeString(src, this.getCharset()); | |
306 // existing-path | |
307 tw.writeString(target, this.getCharset()); | |
308 tw.writeBoolean(true); | |
309 | |
310 sendMessage(Packet.SSH_FXP_LINK, req_id, tw.getBytes()); | |
311 | |
312 expectStatusOKMessage(req_id); | |
313 } | |
314 | |
315 @Override | |
316 public void createHardlink(String src, String target) throws IOException { | |
317 int req_id = generateNextRequestID(); | |
318 | |
319 TypesWriter tw = new TypesWriter(); | |
320 // new-link-path | |
321 tw.writeString(src, this.getCharset()); | |
322 // existing-path | |
323 tw.writeString(target, this.getCharset()); | |
324 tw.writeBoolean(false); | |
325 | |
326 sendMessage(Packet.SSH_FXP_LINK, req_id, tw.getBytes()); | |
327 | |
328 expectStatusOKMessage(req_id); | |
329 } | |
330 } |