annotate src/ch/ethz/ssh2/AbstractSFTPClient.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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
273
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
1 package ch.ethz.ssh2;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
2
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
3 import java.io.BufferedOutputStream;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
4 import java.io.IOException;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
5 import java.io.InputStream;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
6 import java.io.OutputStream;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
7 import java.net.SocketException;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
8 import java.nio.charset.Charset;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
9 import java.nio.charset.UnsupportedCharsetException;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
10 import java.util.HashMap;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
11 import java.util.Map;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
12
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
13 import ch.ethz.ssh2.channel.Channel;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
14 import ch.ethz.ssh2.log.Logger;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
15 import ch.ethz.ssh2.packets.TypesReader;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
16 import ch.ethz.ssh2.packets.TypesWriter;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
17 import ch.ethz.ssh2.sftp.AttribFlags;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
18 import ch.ethz.ssh2.sftp.ErrorCodes;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
19 import ch.ethz.ssh2.sftp.Packet;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
20 import ch.ethz.ssh2.util.StringEncoder;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
21
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
22 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
23 * @version $Id: AbstractSFTPClient.java 151 2014-04-28 10:03:39Z dkocher@sudo.ch $
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
24 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
25 public abstract class AbstractSFTPClient implements SFTPClient {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
26
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
27 private static final Logger log = Logger.getLogger(SFTPv3Client.class);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
28
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
29 private Session sess;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
30
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
31 private InputStream is;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
32 private OutputStream os;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
33
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
34 private int next_request_id = 1000;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
35
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
36 private String charset;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
37
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
38 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
39 * Parallel read requests maximum size.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
40 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
41 private static final int DEFAULT_MAX_PARALLELISM = 64;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
42
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
43 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
44 * Parallel read requests.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
45 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
46 private int parallelism = DEFAULT_MAX_PARALLELISM;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
47
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
48 public void setRequestParallelism(int parallelism) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
49 this.parallelism = Math.min(parallelism, DEFAULT_MAX_PARALLELISM);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
50 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
51
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
52 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
53 * Mapping request ID to request.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
54 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
55 private Map<Integer, OutstandingReadRequest> pendingReadQueue
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
56 = new HashMap<Integer, OutstandingReadRequest>();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
57
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
58 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
59 * Mapping request ID to request.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
60 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
61 private Map<Integer, OutstandingStatusRequest> pendingStatusQueue
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
62 = new HashMap<Integer, OutstandingStatusRequest>();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
63
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
64 private PacketListener listener;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
65
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
66 protected AbstractSFTPClient(final Connection conn, final int version, final PacketListener listener) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
67 this.listener = listener;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
68
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
69 log.debug("Opening session and starting SFTP subsystem.");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
70 sess = conn.openSession();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
71 sess.startSubSystem("sftp");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
72
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
73 is = sess.getStdout();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
74 os = new BufferedOutputStream(sess.getStdin(), 2048);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
75
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
76 init(version);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
77
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
78 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
79
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
80 private void init(final int client_version) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
81 // Send SSH_FXP_INIT with client version
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
82
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
83 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
84 tw.writeUINT32(client_version);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
85 sendMessage(Packet.SSH_FXP_INIT, 0, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
86
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
87 /* Receive SSH_FXP_VERSION */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
88
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
89 log.debug("Waiting for SSH_FXP_VERSION...");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
90 TypesReader tr = new TypesReader(receiveMessage(34000)); /* Should be enough for any reasonable server */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
91
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
92 int t = tr.readByte();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
93 listener.read(Packet.forName(t));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
94
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
95 if(t != Packet.SSH_FXP_VERSION) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
96 log.warning(String.format("The server did not send a SSH_FXP_VERSION but %d", t));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
97 throw new PacketTypeException(t);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
98 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
99
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
100 final int protocol_version = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
101
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
102 log.debug("SSH_FXP_VERSION: protocol_version = " + protocol_version);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
103 if(protocol_version != client_version) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
104 throw new IOException(String.format("Server protocol version %d does not match %d",
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
105 protocol_version, client_version));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
106 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
107 // Both parties should from then on adhere to particular version of the protocol
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
108
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
109 // Read and save extensions (if any) for later use
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
110 while(tr.remain() != 0) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
111 String name = tr.readString();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
112 listener.read(name);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
113 byte[] value = tr.readByteString();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
114 log.debug(String.format("SSH_FXP_VERSION: extension: %s = '%s'", name, StringEncoder.GetString(value)));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
115 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
116 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
117
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
118 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
119 * Queries the channel state
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
120 *
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
121 * @return True if the underlying session is in open state
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
122 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
123 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
124 public boolean isConnected() {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
125 return sess.getState() == Channel.STATE_OPEN;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
126 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
127
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
128 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
129 * Close this SFTP session. NEVER forget to call this method to free up
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
130 * resources - even if you got an exception from one of the other methods.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
131 * Sometimes these other methods may throw an exception, saying that the
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
132 * underlying channel is closed (this can happen, e.g., if the other server
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
133 * sent a close message.) However, as long as you have not called the
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
134 * <code>close()</code> method, you are likely wasting resources.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
135 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
136 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
137 public void close() {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
138 sess.close();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
139 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
140
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
141 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
142 * Set the charset used to convert between Java Unicode Strings and byte encodings
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
143 * used by the server for paths and file names.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
144 *
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
145 * @param charset the name of the charset to be used or <code>null</code> to use UTF-8.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
146 * @throws java.io.IOException
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
147 * @see #getCharset()
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
148 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
149 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
150 public void setCharset(String charset) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
151 if(charset == null) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
152 this.charset = null;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
153 return;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
154 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
155 try {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
156 Charset.forName(charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
157 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
158 catch(UnsupportedCharsetException e) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
159 throw new IOException("This charset is not supported", e);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
160 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
161 this.charset = charset;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
162 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
163
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
164 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
165 * The currently used charset for filename encoding/decoding.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
166 *
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
167 * @return The name of the charset (<code>null</code> if UTF-8 is used).
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
168 * @see #setCharset(String)
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
169 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
170 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
171 public String getCharset() {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
172 return charset;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
173 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
174
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
175 public abstract SFTPFileHandle openFile(String fileName, int flags, SFTPFileAttributes attr) throws IOException;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
176
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
177 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
178 public void mkdir(String dirName, int posixPermissions) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
179 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
180
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
181 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
182 tw.writeString(dirName, this.getCharset());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
183 tw.writeUINT32(AttribFlags.SSH_FILEXFER_ATTR_PERMISSIONS);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
184 tw.writeUINT32(posixPermissions);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
185
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
186 sendMessage(Packet.SSH_FXP_MKDIR, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
187
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
188 expectStatusOKMessage(req_id);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
189 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
190
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
191 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
192 public void rm(String fileName) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
193 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
194
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
195 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
196 tw.writeString(fileName, this.getCharset());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
197
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
198 sendMessage(Packet.SSH_FXP_REMOVE, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
199
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
200 expectStatusOKMessage(req_id);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
201 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
202
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
203 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
204 public void rmdir(String dirName) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
205 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
206
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
207 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
208 tw.writeString(dirName, this.getCharset());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
209
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
210 sendMessage(Packet.SSH_FXP_RMDIR, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
211
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
212 expectStatusOKMessage(req_id);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
213 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
214
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
215 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
216 public void mv(String oldPath, String newPath) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
217 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
218
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
219 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
220 tw.writeString(oldPath, this.getCharset());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
221 tw.writeString(newPath, this.getCharset());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
222
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
223 sendMessage(Packet.SSH_FXP_RENAME, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
224
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
225 expectStatusOKMessage(req_id);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
226 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
227
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
228 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
229 public String readLink(String path) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
230 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
231
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
232 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
233 tw.writeString(path, charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
234
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
235 sendMessage(Packet.SSH_FXP_READLINK, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
236
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
237 byte[] resp = receiveMessage(34000);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
238
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
239 TypesReader tr = new TypesReader(resp);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
240
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
241 int t = tr.readByte();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
242 listener.read(Packet.forName(t));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
243
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
244 int rep_id = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
245 if(rep_id != req_id) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
246 throw new RequestMismatchException();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
247 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
248
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
249 if(t == Packet.SSH_FXP_NAME) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
250 int count = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
251
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
252 if(count != 1) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
253 throw new PacketTypeException(t);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
254 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
255
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
256 return tr.readString(charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
257 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
258
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
259 if(t != Packet.SSH_FXP_STATUS) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
260 throw new PacketTypeException(t);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
261 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
262
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
263 int errorCode = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
264 String errorMessage = tr.readString();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
265 listener.read(errorMessage);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
266 throw new SFTPException(errorMessage, errorCode);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
267 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
268
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
269 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
270 public void setstat(String path, SFTPFileAttributes attr) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
271 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
272
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
273 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
274 tw.writeString(path, charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
275 tw.writeBytes(attr.toBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
276
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
277 sendMessage(Packet.SSH_FXP_SETSTAT, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
278
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
279 expectStatusOKMessage(req_id);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
280 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
281
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
282 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
283 public void fsetstat(SFTPFileHandle handle, SFTPFileAttributes attr) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
284 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
285
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
286 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
287 tw.writeString(handle.getHandle(), 0, handle.getHandle().length);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
288 tw.writeBytes(attr.toBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
289
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
290 sendMessage(Packet.SSH_FXP_FSETSTAT, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
291
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
292 expectStatusOKMessage(req_id);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
293 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
294
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
295 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
296 public void createSymlink(String src, String target) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
297 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
298
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
299 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
300 tw.writeString(src, charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
301 tw.writeString(target, charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
302
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
303 sendMessage(Packet.SSH_FXP_SYMLINK, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
304
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
305 expectStatusOKMessage(req_id);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
306 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
307
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
308 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
309 public void createHardlink(String src, String target) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
310 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
311
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
312 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
313 tw.writeString("hardlink@openssh.com", charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
314 tw.writeString(target, charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
315 tw.writeString(src, charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
316
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
317 sendMessage(Packet.SSH_FXP_EXTENDED, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
318
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
319 expectStatusOKMessage(req_id);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
320 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
321
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
322 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
323 public String canonicalPath(String path) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
324 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
325
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
326 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
327 tw.writeString(path, charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
328
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
329 sendMessage(Packet.SSH_FXP_REALPATH, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
330
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
331 byte[] resp = receiveMessage(34000);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
332
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
333 TypesReader tr = new TypesReader(resp);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
334
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
335 int t = tr.readByte();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
336 listener.read(Packet.forName(t));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
337
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
338 int rep_id = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
339 if(rep_id != req_id) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
340 throw new RequestMismatchException();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
341 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
342
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
343 if(t == Packet.SSH_FXP_NAME) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
344 int count = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
345
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
346 if(count != 1) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
347 throw new PacketFormatException("The server sent an invalid SSH_FXP_NAME packet.");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
348 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
349 final String name = tr.readString(charset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
350 listener.read(name);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
351 return name;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
352 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
353
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
354 if(t != Packet.SSH_FXP_STATUS) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
355 throw new PacketTypeException(t);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
356 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
357
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
358 int errorCode = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
359 String errorMessage = tr.readString();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
360 listener.read(errorMessage);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
361 throw new SFTPException(errorMessage, errorCode);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
362 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
363
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
364 private void sendMessage(int type, int requestId, byte[] msg, int off, int len) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
365 if(log.isDebugEnabled()) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
366 log.debug(String.format("Send message of type %d with request id %d", type, requestId));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
367 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
368 listener.write(Packet.forName(type));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
369
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
370 int msglen = len + 1;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
371
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
372 if(type != Packet.SSH_FXP_INIT) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
373 msglen += 4;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
374 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
375
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
376 os.write(msglen >> 24);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
377 os.write(msglen >> 16);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
378 os.write(msglen >> 8);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
379 os.write(msglen);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
380 os.write(type);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
381
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
382 if(type != Packet.SSH_FXP_INIT) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
383 os.write(requestId >> 24);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
384 os.write(requestId >> 16);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
385 os.write(requestId >> 8);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
386 os.write(requestId);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
387 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
388
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
389 os.write(msg, off, len);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
390 os.flush();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
391 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
392
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
393 protected void sendMessage(int type, int requestId, byte[] msg) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
394 sendMessage(type, requestId, msg, 0, msg.length);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
395 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
396
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
397 private void readBytes(byte[] buff, int pos, int len) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
398 while(len > 0) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
399 int count = is.read(buff, pos, len);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
400 if(count < 0) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
401 throw new SocketException("Unexpected end of stream.");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
402 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
403 len -= count;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
404 pos += count;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
405 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
406 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
407
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
408 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
409 * Read a message and guarantee that the <b>contents</b> is not larger than
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
410 * <code>maxlen</code> bytes.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
411 * <p/>
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
412 * Note: receiveMessage(34000) actually means that the message may be up to 34004
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
413 * bytes (the length attribute preceding the contents is 4 bytes).
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
414 *
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
415 * @param maxlen
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
416 * @return the message contents
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
417 * @throws IOException
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
418 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
419 protected byte[] receiveMessage(int maxlen) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
420 byte[] msglen = new byte[4];
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
421
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
422 readBytes(msglen, 0, 4);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
423
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
424 int len = (((msglen[0] & 0xff) << 24) | ((msglen[1] & 0xff) << 16) | ((msglen[2] & 0xff) << 8) | (msglen[3] & 0xff));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
425
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
426 if((len > maxlen) || (len <= 0)) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
427 throw new PacketFormatException(String.format("Illegal SFTP packet length %d", len));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
428 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
429
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
430 byte[] msg = new byte[len];
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
431
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
432 readBytes(msg, 0, len);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
433
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
434 return msg;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
435 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
436
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
437 protected int generateNextRequestID() {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
438 synchronized(this) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
439 return next_request_id++;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
440 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
441 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
442
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
443 protected void closeHandle(byte[] handle) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
444 int req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
445
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
446 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
447 tw.writeString(handle, 0, handle.length);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
448
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
449 sendMessage(Packet.SSH_FXP_CLOSE, req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
450
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
451 expectStatusOKMessage(req_id);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
452 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
453
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
454 private void readStatus() throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
455 byte[] resp = receiveMessage(34000);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
456
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
457 TypesReader tr = new TypesReader(resp);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
458 int t = tr.readByte();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
459 listener.read(Packet.forName(t));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
460
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
461 // Search the pending queue
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
462 OutstandingStatusRequest status = pendingStatusQueue.remove(tr.readUINT32());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
463 if(null == status) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
464 throw new RequestMismatchException();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
465 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
466
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
467 // Evaluate the answer
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
468 if(t == Packet.SSH_FXP_STATUS) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
469 // In any case, stop sending more packets
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
470 int code = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
471 if(log.isDebugEnabled()) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
472 String[] desc = ErrorCodes.getDescription(code);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
473 log.debug("Got SSH_FXP_STATUS (" + status.req_id + ") (" + ((desc != null) ? desc[0] : "UNKNOWN") + ")");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
474 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
475 if(code == ErrorCodes.SSH_FX_OK) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
476 return;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
477 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
478 String msg = tr.readString();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
479 listener.read(msg);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
480 throw new SFTPException(msg, code);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
481 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
482 throw new PacketTypeException(t);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
483 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
484
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
485 private void readPendingReadStatus() throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
486 byte[] resp = receiveMessage(34000);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
487
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
488 TypesReader tr = new TypesReader(resp);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
489 int t = tr.readByte();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
490 listener.read(Packet.forName(t));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
491
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
492 // Search the pending queue
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
493 OutstandingReadRequest status = pendingReadQueue.remove(tr.readUINT32());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
494 if(null == status) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
495 throw new RequestMismatchException();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
496 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
497
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
498 // Evaluate the answer
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
499 if(t == Packet.SSH_FXP_STATUS) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
500 // In any case, stop sending more packets
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
501 int code = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
502 if(log.isDebugEnabled()) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
503 String[] desc = ErrorCodes.getDescription(code);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
504 log.debug("Got SSH_FXP_STATUS (" + status.req_id + ") (" + ((desc != null) ? desc[0] : "UNKNOWN") + ")");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
505 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
506 if(code == ErrorCodes.SSH_FX_OK) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
507 return;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
508 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
509 if(code == ErrorCodes.SSH_FX_EOF) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
510 return;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
511 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
512 String msg = tr.readString();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
513 listener.read(msg);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
514 throw new SFTPException(msg, code);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
515 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
516 throw new PacketTypeException(t);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
517 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
518
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
519 protected void expectStatusOKMessage(int id) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
520 byte[] resp = receiveMessage(34000);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
521
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
522 TypesReader tr = new TypesReader(resp);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
523
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
524 int t = tr.readByte();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
525 listener.read(Packet.forName(t));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
526
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
527 int rep_id = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
528 if(rep_id != id) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
529 throw new RequestMismatchException();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
530 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
531
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
532 if(t != Packet.SSH_FXP_STATUS) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
533 throw new PacketTypeException(t);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
534 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
535
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
536 int errorCode = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
537
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
538 if(errorCode == ErrorCodes.SSH_FX_OK) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
539 return;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
540 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
541 String errorMessage = tr.readString();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
542 listener.read(errorMessage);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
543 throw new SFTPException(errorMessage, errorCode);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
544 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
545
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
546 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
547 public void closeFile(SFTPFileHandle handle) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
548 while(!pendingReadQueue.isEmpty()) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
549 this.readPendingReadStatus();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
550 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
551 while(!pendingStatusQueue.isEmpty()) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
552 this.readStatus();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
553 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
554 closeHandle(handle.getHandle());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
555 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
556
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
557 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
558 public int read(SFTPFileHandle handle, long fileOffset, byte[] dst, int dstoff, int len) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
559 boolean errorOccured = false;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
560 int remaining = len * parallelism;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
561 //int clientOffset = dstoff;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
562
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
563 long serverOffset = fileOffset;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
564 for(OutstandingReadRequest r : pendingReadQueue.values()) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
565 // Server offset should take pending requests into account.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
566 serverOffset += r.len;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
567 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
568
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
569 while(true) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
570 // Stop if there was an error and no outstanding request
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
571 if((pendingReadQueue.size() == 0) && errorOccured) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
572 break;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
573 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
574
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
575 // Send as many requests as we are allowed to
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
576 while(pendingReadQueue.size() < parallelism) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
577 if(errorOccured) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
578 break;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
579 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
580 // Send the next read request
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
581 OutstandingReadRequest req = new OutstandingReadRequest();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
582 req.req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
583 req.serverOffset = serverOffset;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
584 req.len = (remaining > len) ? len : remaining;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
585 req.buffer = dst;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
586 req.dstOffset = dstoff;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
587
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
588 serverOffset += req.len;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
589 //clientOffset += req.len;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
590 remaining -= req.len;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
591
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
592 sendReadRequest(req.req_id, handle, req.serverOffset, req.len);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
593
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
594 pendingReadQueue.put(req.req_id, req);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
595 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
596 if(pendingReadQueue.size() == 0) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
597 break;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
598 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
599
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
600 // Receive a single answer
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
601 byte[] resp = receiveMessage(34000);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
602 TypesReader tr = new TypesReader(resp);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
603
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
604 int t = tr.readByte();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
605 listener.read(Packet.forName(t));
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
606
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
607 // Search the pending queue
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
608 OutstandingReadRequest req = pendingReadQueue.remove(tr.readUINT32());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
609 if(null == req) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
610 throw new RequestMismatchException();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
611 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
612 // Evaluate the answer
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
613 if(t == Packet.SSH_FXP_STATUS) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
614 /* In any case, stop sending more packets */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
615
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
616 int code = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
617 String msg = tr.readString();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
618 listener.read(msg);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
619
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
620 if(log.isDebugEnabled()) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
621 String[] desc = ErrorCodes.getDescription(code);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
622 log.debug("Got SSH_FXP_STATUS (" + req.req_id + ") (" + ((desc != null) ? desc[0] : "UNKNOWN") + ")");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
623 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
624 // Flag to read all pending requests but don't send any more.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
625 errorOccured = true;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
626 if(pendingReadQueue.isEmpty()) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
627 if(ErrorCodes.SSH_FX_EOF == code) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
628 return -1;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
629 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
630 throw new SFTPException(msg, code);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
631 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
632 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
633 else if(t == Packet.SSH_FXP_DATA) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
634 // OK, collect data
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
635 int readLen = tr.readUINT32();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
636
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
637 if((readLen < 0) || (readLen > req.len)) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
638 throw new PacketFormatException("The server sent an invalid length field in a SSH_FXP_DATA packet.");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
639 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
640
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
641 if(log.isDebugEnabled()) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
642 log.debug("Got SSH_FXP_DATA (" + req.req_id + ") " + req.serverOffset + "/" + readLen
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
643 + " (requested: " + req.len + ")");
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
644 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
645
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
646 // Read bytes into buffer
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
647 tr.readBytes(req.buffer, req.dstOffset, readLen);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
648
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
649 if(readLen < req.len) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
650 /* Send this request packet again to request the remaing data in this slot. */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
651 req.req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
652 req.serverOffset += readLen;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
653 req.len -= readLen;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
654
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
655 log.debug("Requesting again: " + req.serverOffset + "/" + req.len);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
656 sendReadRequest(req.req_id, handle, req.serverOffset, req.len);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
657
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
658 pendingReadQueue.put(req.req_id, req);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
659 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
660 return readLen;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
661 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
662 else {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
663 throw new PacketTypeException(t);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
664 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
665 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
666 // Should never reach here.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
667 throw new SFTPException("No EOF reached", -1);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
668 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
669
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
670 private void sendReadRequest(int id, SFTPFileHandle handle, long offset, int len) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
671 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
672 tw.writeString(handle.getHandle(), 0, handle.getHandle().length);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
673 tw.writeUINT64(offset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
674 tw.writeUINT32(len);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
675
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
676 sendMessage(Packet.SSH_FXP_READ, id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
677 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
678
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
679 @Override
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
680 public void write(SFTPFileHandle handle, long fileOffset, byte[] src, int srcoff, int len) throws IOException {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
681 while(len > 0) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
682 int writeRequestLen = len;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
683
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
684 if(writeRequestLen > 32768) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
685 writeRequestLen = 32768;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
686 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
687
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
688 // Send the next write request
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
689 OutstandingStatusRequest req = new OutstandingStatusRequest();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
690 req.req_id = generateNextRequestID();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
691
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
692 TypesWriter tw = new TypesWriter();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
693 tw.writeString(handle.getHandle(), 0, handle.getHandle().length);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
694 tw.writeUINT64(fileOffset);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
695 tw.writeString(src, srcoff, writeRequestLen);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
696
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
697 sendMessage(Packet.SSH_FXP_WRITE, req.req_id, tw.getBytes());
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
698
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
699 pendingStatusQueue.put(req.req_id, req);
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
700
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
701 // Only read next status if parallelism reached
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
702 while(pendingStatusQueue.size() >= parallelism) {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
703 this.readStatus();
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
704 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
705 fileOffset += writeRequestLen;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
706 srcoff += writeRequestLen;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
707 len -= writeRequestLen;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
708 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
709 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
710
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
711
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
712 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
713 * A read is divided into multiple requests sent sequentially before
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
714 * reading any status from the server
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
715 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
716 private static class OutstandingReadRequest {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
717 int req_id;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
718 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
719 * Read offset to request on server starting at the file offset for the first request.
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
720 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
721 long serverOffset;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
722 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
723 * Length of requested data
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
724 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
725 int len;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
726 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
727 * Offset in destination buffer
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
728 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
729 int dstOffset;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
730 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
731 * Temporary buffer
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
732 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
733 byte[] buffer;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
734 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
735
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
736 /**
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
737 * A read is divided into multiple requests sent sequentially before
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
738 * reading any status from the server
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
739 */
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
740 private static final class OutstandingStatusRequest {
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
741 int req_id;
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
742 }
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
743
91a31873c42a start conversion from trilead to ganymed
Carl Byington <carl@five-ten-sg.com>
parents:
diff changeset
744 }