1 //////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Zhou Xiao-wei, Apr. 2007.
3 // Copyright (C) Wang Cong, Apr. 2007.
4 // See AUTHORS and CREDITS to learn more.
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation.
8 // See COPYING to learn more.
9 //////////////////////////////////////////////////////////////////////////
15 * This class is for FTP connection.
16 * Extends XylTelnetConnection.
17 * @author WANG Cong, Zhou Xiao-Wei
20 public class XylFTPConnection
extends XylTelnetConnection
{
23 *The size of reader's buffer.
25 private final int RDBUF_SIZE
= 1024;
28 *The size of writer's buffer.
30 private final int WRBUF_SIZE
= 1024;
33 *The status of FTP connection.
36 // 0 for not connected
37 // 1 for connected but not login
38 // 2 for login and no data transfer
39 // 3 for login and getting data down
40 // 4 for login and putting data up
43 *Presents the mode (active or passive) of FTP connection.
46 //1 for passive, 0 for active, defaults to 1. ;)
49 *Gets the line separator used by local system.
51 private byte[] LineSeparator
= System
.getProperty("line.separator").getBytes();
54 *Presents the mode (ascii or binary) of transfer files.
56 private int TransferMode
;
57 //1 for ascii, 0 for binary, defaults to 0. ;)
60 *Constructs a LocalFile for data storage.
62 private String LocalFile
;
63 // Empty string for this means stdout. ;)
66 *The data connection socket.
68 private Socket DataSocket
;
71 *The sever data socket, used by active mode.
73 private ServerSocket DataServerSocket
;
78 private BufferedInputStream FTPInStream
;
83 private BufferedOutputStream FTPOutStream
;
86 *Initializes some values.
95 DataServerSocket
= null;
99 *Gets status of current FTP connection.
100 *@return the status of connection
102 public int GetStatus(){
107 *Sets status of the connection.
110 public void SetStatus(int NewStatus
){
115 *Get Mode of tranfer files.
116 *@return the mode of transfer files
118 public int GetTransferMode(){
123 *Sets TransferMode of transfer files.
124 *@param NewTransferMode New Transfer Mode
126 public void SetTransferMode(int NewTransferMode
){
127 TransferMode
= NewTransferMode
;
131 *Sets the LocalFile name.
134 public void SetLocalFile(String FileName
){
135 LocalFile
= FileName
;
139 *Tests whether the mode is passive
141 public boolean IsPassive(){
148 *Sets the passive mode.
150 public void SetPassive(){
155 *Sets the active mode.
157 public void SetActive(){
162 *Prepares for active data connection.
164 public void ReadyForActive() throws Exception
{
166 if(-1 == ReturnSelfPort())
167 throw new XylFTPException("Port is unavailable.");
168 DataServerSocket
= new ServerSocket(ReturnSelfPort());
169 DataServerSocket
.setSoTimeout(Timeout
/2);//Hmm, short is better.
170 } catch(Exception e
) {
176 *Opens the data connection in active mode.
178 *@throws Exception on opening dataconnection error
180 public void OpenDataConnection() throws Exception
{
182 DataSocket
= DataServerSocket
.accept();
183 } catch(Exception e
) {
190 *Opens the data connection in passive mode.
191 *@param Port the port of server
192 *@param Host the IP of server
194 *@throws Exception on opening DataConnection error
196 public void OpenDataConnection(String Host
, int Port
) throws Exception
{
198 DataSocket
= new Socket(Host
, Port
);
199 DataSocket
.setSoTimeout(Timeout
);
200 } catch (Exception e
) {
207 *Closes the data connection.
208 *@see XylFTPException
209 *@throws XylFTPException on closing DataConnection error
211 public void CloseDataConnection() throws Exception
{
213 if(DataServerSocket
!= null) {
214 DataServerSocket
.close();
219 *Uploads a file in active mode.
220 *@throws XylFTPException on sending file error
221 *@see XylFTPException
223 public void SendFileActive() throws Exception
{
225 byte [] buf
= new byte[WRBUF_SIZE
];
228 throw new XylFTPException("You are not in active mode!");
230 if (LocalFile
.equals("")) {
232 throw new XylFTPException("Can't send unnamed file!");
234 FTPInStream
= new BufferedInputStream(new FileInputStream(LocalFile
));
236 FTPOutStream
= new BufferedOutputStream(DataSocket
.getOutputStream());
238 if (TransferMode
==1) {
239 int separatorPos
= 0;
240 while ((bytesRead
= FTPInStream
.read(buf
, 0, WRBUF_SIZE
)) > 0) {
241 for (int i
= 0; i
< bytesRead
; i
++) {
242 boolean found
= true;
244 for (; separatorPos
< LineSeparator
.length
245 && i
+separatorPos
< bytesRead
;
246 skip
++, separatorPos
++) {
247 if (buf
[i
+separatorPos
] != LineSeparator
[separatorPos
]) {
252 if (found
) { // either found match or run out of buffer
253 if (separatorPos
== LineSeparator
.length
) {
254 // found line separator
255 FTPOutStream
.write('\r');
256 FTPOutStream
.write('\n');
258 //skip over bytes that match
261 // reached end of buffer && matching so far
265 FTPOutStream
.write(buf
[i
]);
269 } else if (TransferMode
==0) {
270 while ((bytesRead
= FTPInStream
.read(buf
, 0, WRBUF_SIZE
)) > 0) {
271 FTPOutStream
.write(buf
, 0, bytesRead
);
274 throw new XylFTPException("panic", 0, "No such mode!");
276 FTPOutStream
.flush();
277 FTPOutStream
.close();
281 *Uploads a file in passive mode.
282 *@throws XylFTPException on sending file error
283 *@see XylFTPException
285 public void SendFilePassive() throws Exception
{
287 byte [] buf
= new byte[WRBUF_SIZE
];
290 throw new XylFTPException("You are not in passive mode!");
292 if (LocalFile
.equals("")) {
294 throw new XylFTPException("Can't send unnamed file!");
296 FTPInStream
= new BufferedInputStream(new FileInputStream(LocalFile
));
298 FTPOutStream
= new BufferedOutputStream(DataSocket
.getOutputStream());
299 if (TransferMode
==1) {
300 int separatorPos
= 0;
301 while ((bytesRead
= FTPInStream
.read(buf
, 0, WRBUF_SIZE
)) > 0) {
302 for (int i
= 0; i
< bytesRead
; i
++) {
303 boolean found
= true;
305 for (; separatorPos
< LineSeparator
.length
306 && i
+separatorPos
< bytesRead
;
307 skip
++, separatorPos
++) {
308 if (buf
[i
+separatorPos
] != LineSeparator
[separatorPos
]) {
313 if (found
) { // either found match or run out of buffer
314 if (separatorPos
== LineSeparator
.length
) {
315 // found line separator
316 FTPOutStream
.write('\r');
317 FTPOutStream
.write('\n');
319 //skip over bytes that match
322 // reached end of buffer && matching so far
326 FTPOutStream
.write(buf
[i
]);
330 } else if (TransferMode
==0) {
331 while ((bytesRead
= FTPInStream
.read(buf
, 0, WRBUF_SIZE
)) > 0) {
332 FTPOutStream
.write(buf
, 0, bytesRead
);
335 throw new XylFTPException("panic", 0, "No such mode!");
337 FTPOutStream
.flush();
338 FTPOutStream
.close();
343 *Downloads a file in active mode.
344 *@throws XylFTPException on getting file error
345 *@see XylFTPException
347 public void GetFileActive() throws Exception
{
349 byte [] buf
= new byte[RDBUF_SIZE
];
352 throw new XylFTPException("You are not in active mode!");
354 if (LocalFile
.equals("")) {
355 FTPOutStream
= new BufferedOutputStream((OutputStream
)System
.out
);
357 FTPOutStream
= new BufferedOutputStream(new FileOutputStream(LocalFile
));
359 FTPInStream
= new BufferedInputStream(DataSocket
.getInputStream());
361 if (TransferMode
==1) {
362 boolean crFound
= false;
363 while ((bytesRead
= FTPInStream
.read(buf
, 0, RDBUF_SIZE
)) > 0) {
364 boolean lfFound
= false;
365 for (int i
= 0; i
< bytesRead
; i
++) {
366 lfFound
= buf
[i
] == '\n';
369 FTPOutStream
.write(LineSeparator
, 0,
370 LineSeparator
.length
);
372 FTPOutStream
.write('\r');
375 crFound
= buf
[i
] == '\r';
376 if (!lfFound
&& !crFound
) {
377 FTPOutStream
.write(buf
[i
]);
381 } else if (TransferMode
==0) {
382 while ((bytesRead
= FTPInStream
.read(buf
, 0, RDBUF_SIZE
)) > 0) {
383 FTPOutStream
.write(buf
, 0, bytesRead
);
386 throw new XylFTPException("panic", 0, "No such mode!");
388 FTPOutStream
.flush();
389 if (!LocalFile
.equals("")) //We can NOT close the stdout.
390 FTPOutStream
.close();
395 *Downloads a file in passive mode.
396 *@throws XylFTPException on getting file error
397 *@see XylFTPException
399 public void GetFilePassive() throws Exception
{
401 byte [] buf
= new byte[RDBUF_SIZE
];
404 throw new XylFTPException("You are not in passive mode!");
406 if (LocalFile
.equals("")) {
407 FTPOutStream
= new BufferedOutputStream((OutputStream
)System
.out
);
409 FTPOutStream
= new BufferedOutputStream(new FileOutputStream(LocalFile
));
411 FTPInStream
= new BufferedInputStream(DataSocket
.getInputStream());
412 if (TransferMode
==1) {
413 boolean crFound
= false;
414 while ((bytesRead
= FTPInStream
.read(buf
, 0, RDBUF_SIZE
)) > 0) {
415 boolean lfFound
= false;
416 for (int i
= 0; i
< bytesRead
; i
++) {
417 lfFound
= buf
[i
] == '\n';
420 FTPOutStream
.write(LineSeparator
, 0,
421 LineSeparator
.length
);
423 FTPOutStream
.write('\r');
426 crFound
= buf
[i
] == '\r';
427 if (!lfFound
&& !crFound
) {
428 FTPOutStream
.write(buf
[i
]);
432 } else if (TransferMode
==0) {
433 while ((bytesRead
= FTPInStream
.read(buf
, 0, RDBUF_SIZE
)) > 0) {
434 FTPOutStream
.write(buf
, 0, bytesRead
);
437 throw new XylFTPException("panic", 0, "No such mode!");
439 FTPOutStream
.flush();
440 if (!LocalFile
.equals("")) //We can NOT close the stdout.
441 FTPOutStream
.close();