comparison app/src/main/java/ch/ethz/ssh2/SFTPv6Client.java @ 438:d29cce60f393

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