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 }