Mercurial > 510Connectbot
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 } |