1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package gnu.inet.ftp;
24
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InterruptedIOException;
28 import java.io.OutputStream;
29 import java.net.Socket;
30 import java.net.SocketException;
31 import java.util.zip.InflaterInputStream;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35
36 /***
37 * This class implements an FTP-style data connection thread for GETing
38 * files/data passively. This class is used internally to the FtpClient class.
39 */
40 public class PassiveGetter extends Getter {
41
42 private PassiveConnection connection;
43
44 private Socket sock = null;
45
46 private final static Log log = LogFactory.getLog(PassiveGetter.class);
47
48 /***
49 * Create a new PassiveGetter instance with the given OutpuStream for data
50 * output and using the given PassiveParameters to connect to the server.
51 *
52 * @param out
53 * the OutputStream where retrieved data will be written
54 * @param connection
55 * the PassiveConnection to the server
56 */
57 public PassiveGetter(OutputStream out, PassiveConnection connection) {
58 super();
59
60 this.ostream = out;
61 this.connection = connection;
62 }
63
64
65
66
67
68 /***
69 * cancel a running transfer sets a flag and calls interrupt() can only be
70 * called once
71 */
72 public void cancel() {
73 if (!cancelled) {
74 cancelled = true;
75 interrupt();
76 if (sock != null && !sock.isClosed()) {
77 try {
78 log.debug("Setting socket to 0 lingering");
79 sock.setSoLinger(true, 0);
80 sock.close();
81 } catch (IOException e) {
82
83 }
84 }
85 }
86 }
87
88 /***
89 * get data from server using given parameters.
90 */
91 public void run() {
92 boolean signalClosure = false;
93
94 InputStream istream = null;
95 long amount = 0;
96 int buffer_size = 0;
97 byte buffer[] = new byte[BUFFER_SIZE];
98
99 PassiveParameters parameters = connection.getPassiveParameters();
100
101 try {
102
103 sock = connection.getSocket();
104 if (cancelled)
105 throw new InterruptedIOException("Transfer cancelled");
106 signalConnectionOpened(new ConnectionEvent(parameters
107 .getInetAddress(), parameters.getPort()));
108 signalClosure = true;
109 signalTransferStarted();
110
111 try {
112
113
114 switch (type) {
115 case FtpClientProtocol.TYPE_ASCII:
116 istream = new AsciiInputStream(sock.getInputStream());
117 break;
118 default:
119 istream = sock.getInputStream();
120 break;
121 }
122
123
124 switch (mode) {
125 case FtpClientProtocol.MODE_ZLIB:
126 istream = new InflaterInputStream(istream);
127 break;
128 case FtpClientProtocol.MODE_STREAM:
129 default:
130 break;
131 }
132
133 int len;
134 while (!cancelled && ((len = istream.read(buffer)) > 0)) {
135 ostream.write(buffer, 0, len);
136 amount += len;
137 buffer_size += len;
138 if (buffer_size >= BUFFER_SIZE) {
139 buffer_size = buffer_size % BUFFER_SIZE;
140 signalTransfered(amount);
141 }
142 yield();
143 }
144
145 ostream.flush();
146 } catch (InterruptedIOException iioe) {
147 if (!cancelled) {
148 log.error(iioe.getMessage(), iioe);
149 }
150 } catch (Exception e) {
151 log.error(e.getMessage(), e);
152 } finally {
153 log.debug("Closing inputstream");
154 if (istream != null) {
155 istream.close();
156 }
157 if (!sock.isClosed()) {
158 try {
159 log.debug("Setting socket to 0 lingering");
160 sock.setSoLinger(true, 0);
161 sock.close();
162 } catch (SocketException e) {
163
164 }
165 }
166 signalTransferCompleted();
167 }
168 } catch (Exception ee) {
169 signalConnectionFailed(ee);
170 log.error(ee.getMessage(), ee);
171 }
172 if (signalClosure == true) {
173 signalConnectionClosed(new ConnectionEvent(parameters
174 .getInetAddress(), parameters.getPort()));
175 }
176 sock = null;
177 }
178 }
179
180