1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.waarp.ftp.client;
19
20 import it.sauronsoftware.ftp4j.FTPAbortedException;
21 import it.sauronsoftware.ftp4j.FTPClient;
22 import it.sauronsoftware.ftp4j.FTPCommunicationListener;
23 import it.sauronsoftware.ftp4j.FTPConnector;
24 import it.sauronsoftware.ftp4j.FTPDataTransferException;
25 import it.sauronsoftware.ftp4j.FTPException;
26 import it.sauronsoftware.ftp4j.FTPFile;
27 import it.sauronsoftware.ftp4j.FTPIllegalReplyException;
28 import it.sauronsoftware.ftp4j.FTPListParseException;
29 import it.sauronsoftware.ftp4j.FTPReply;
30
31 import java.io.File;
32 import java.io.IOException;
33 import java.net.SocketException;
34 import java.security.KeyManagementException;
35 import java.security.NoSuchAlgorithmException;
36 import java.security.SecureRandom;
37 import java.security.cert.X509Certificate;
38
39 import javax.net.ssl.SSLContext;
40 import javax.net.ssl.SSLSocketFactory;
41 import javax.net.ssl.TrustManager;
42 import javax.net.ssl.X509TrustManager;
43
44 import org.waarp.common.logging.WaarpLogger;
45 import org.waarp.common.logging.WaarpLoggerFactory;
46
47
48
49
50
51
52
53 public class WaarpFtp4jClient {
54
55
56
57 private static final WaarpLogger logger = WaarpLoggerFactory.getLogger(WaarpFtp4jClient.class);
58
59 String server = null;
60 int port = 21;
61 String user = null;
62 String pwd = null;
63 String acct = null;
64 int timeout;
65 int keepalive;
66 boolean isPassive = false;
67 int ssl = 0;
68 protected FTPClient ftpClient = null;
69 protected String result = null;
70 private boolean binaryTransfer = true;
71
72
73
74
75
76
77
78
79
80
81
82 public WaarpFtp4jClient(String server, int port,
83 String user, String pwd, String acct, boolean isPassive, int ssl, int keepalive,
84 int timeout) {
85 this.server = server;
86 this.port = port;
87 this.user = user;
88 this.pwd = pwd;
89 this.acct = acct;
90 this.isPassive = isPassive;
91 this.ssl = ssl;
92 this.keepalive = keepalive;
93 this.timeout = timeout;
94 this.ftpClient = new FTPClient();
95 if (this.ssl != 0) {
96
97 TrustManager[] trustManager = new TrustManager[] { new X509TrustManager() {
98 public X509Certificate[] getAcceptedIssuers() {
99 return null;
100 }
101
102 public void checkClientTrusted(X509Certificate[] certs, String authType) {
103 }
104
105 public void checkServerTrusted(X509Certificate[] certs, String authType) {
106 }
107 } };
108 SSLContext sslContext = null;
109 try {
110 sslContext = SSLContext.getInstance("SSL");
111 sslContext.init(null, trustManager, new SecureRandom());
112 } catch (NoSuchAlgorithmException e) {
113 throw new IllegalArgumentException("Bad algorithm", e);
114 } catch (KeyManagementException e) {
115 throw new IllegalArgumentException("Bad KeyManagement", e);
116 }
117 SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
118 this.ftpClient.setSSLSocketFactory(sslSocketFactory);
119 if (this.ssl < 0) {
120 this.ftpClient.setSecurity(FTPClient.SECURITY_FTPS);
121 } else {
122 this.ftpClient.setSecurity(FTPClient.SECURITY_FTPES);
123 }
124 } else {
125 this.ftpClient = new FTPClient();
126 }
127 if (timeout > 0) {
128 System.setProperty("ftp4j.activeDataTransfer.acceptTimeout", "" + timeout);
129 }
130 System.setProperty("ftp4j.activeDataTransfer.hostAddress", "127.0.0.1");
131
132 this.ftpClient.addCommunicationListener(new FTPCommunicationListener() {
133 public void sent(String arg0) {
134 logger.debug("Command: " + arg0);
135 }
136
137 public void received(String arg0) {
138 logger.debug("Answer: " + arg0);
139 }
140 });
141 FTPConnector connector = this.ftpClient.getConnector();
142 connector.setCloseTimeout(timeout);
143 connector.setReadTimeout(timeout);
144 connector.setUseSuggestedAddressForDataConnections(true);
145 }
146
147
148
149
150 public String getResult() {
151 return result;
152 }
153
154
155
156
157
158
159 public boolean connect() {
160 result = null;
161 boolean isActive = false;
162 try {
163 try {
164 this.ftpClient.connect(this.server, this.port);
165 } catch (SocketException e) {
166 result = "Connection in error";
167 logger.error(result, e);
168 return false;
169 } catch (IOException e) {
170 result = "Connection in error";
171 logger.error(result, e);
172 return false;
173 } catch (IllegalStateException e) {
174 result = "Connection in error";
175 logger.error(result, e);
176 return false;
177 } catch (FTPIllegalReplyException e) {
178 result = "Connection in error";
179 logger.error(result, e);
180 return false;
181 } catch (FTPException e) {
182 result = "Connection in error";
183 logger.error(result, e);
184 return false;
185 }
186 try {
187 if (this.acct == null) {
188
189 this.ftpClient.login(this.user, this.pwd);
190 } else {
191 this.ftpClient.login(this.user, this.pwd, this.acct);
192 }
193 } catch (IOException e) {
194 result = "Login in error";
195 logger.error(result, e);
196 return false;
197 } catch (IllegalStateException e) {
198 this.logout();
199 result = "Login in error";
200 logger.error(result);
201 return false;
202 } catch (FTPIllegalReplyException e) {
203 this.logout();
204 result = "Login in error";
205 logger.error(result);
206 return false;
207 } catch (FTPException e) {
208 this.logout();
209 result = "Login in error";
210 logger.error(result);
211 return false;
212 }
213 try {
214 this.ftpClient.setType(FTPClient.TYPE_BINARY);
215 } catch (IllegalArgumentException e1) {
216 result = "Set BINARY in error";
217 logger.error(result, e1);
218 return false;
219 }
220 changeMode(isPassive);
221 if (keepalive > 0) {
222 this.ftpClient.setAutoNoopTimeout(keepalive);
223 }
224 isActive = true;
225 return true;
226 } finally {
227 if ((!isActive) && !this.ftpClient.isPassive()) {
228 this.disconnect();
229 }
230 }
231 }
232
233
234
235
236 public void logout() {
237 this.ftpClient.setAutoNoopTimeout(0);
238 logger.debug("QUIT");
239 if (this.executeCommand("QUIT") == null) {
240 try {
241 this.ftpClient.logout();
242 } catch (IOException e) {
243
244 } catch (IllegalStateException e) {
245
246 } catch (FTPIllegalReplyException e) {
247
248 } catch (FTPException e) {
249
250 } finally {
251 if (!this.ftpClient.isPassive()) {
252 disconnect();
253 }
254 }
255 }
256 }
257
258
259
260
261 public void disconnect() {
262 this.ftpClient.setAutoNoopTimeout(0);
263 try {
264 this.ftpClient.disconnect(false);
265 } catch (IOException e) {
266 logger.debug("Disconnection in error", e);
267 } catch (IllegalStateException e) {
268 logger.debug("Disconnection in error", e);
269 } catch (FTPIllegalReplyException e) {
270 logger.debug("Disconnection in error", e);
271 } catch (FTPException e) {
272 logger.debug("Disconnection in error", e);
273 }
274 }
275
276
277
278
279
280
281
282 public boolean makeDir(String newDir) {
283 result = null;
284 try {
285 this.ftpClient.createDirectory(newDir);
286 return true;
287 } catch (IOException e) {
288 result = "MKDIR in error";
289 logger.info(result, e);
290 return false;
291 } catch (IllegalStateException e) {
292 result = "MKDIR in error";
293 logger.info(result, e);
294 return false;
295 } catch (FTPIllegalReplyException e) {
296 result = "MKDIR in error";
297 logger.info(result, e);
298 return false;
299 } catch (FTPException e) {
300 result = "MKDIR in error";
301 logger.info(result, e);
302 return false;
303 }
304 }
305
306
307
308
309
310
311
312 public boolean changeDir(String newDir) {
313 result = null;
314 try {
315 this.ftpClient.changeDirectory(newDir);
316 return true;
317 } catch (IOException e) {
318 result = "CHDIR in error";
319 logger.info(result, e);
320 return false;
321 } catch (IllegalStateException e) {
322 result = "CHDIR in error";
323 logger.info(result, e);
324 return false;
325 } catch (FTPIllegalReplyException e) {
326 result = "CHDIR in error";
327 logger.info(result, e);
328 return false;
329 } catch (FTPException e) {
330 result = "CHDIR in error";
331 logger.info(result, e);
332 return false;
333 }
334 }
335
336
337
338
339
340
341
342 public boolean changeFileType(boolean binaryTransfer1) {
343 result = null;
344 this.binaryTransfer = binaryTransfer1;
345 try {
346 if (this.binaryTransfer) {
347 this.ftpClient.setType(FTPClient.TYPE_BINARY);
348 } else {
349 this.ftpClient.setType(FTPClient.TYPE_TEXTUAL);
350 }
351 return true;
352 } catch (IllegalArgumentException e) {
353 result = "FileType in error";
354 logger.warn(result, e);
355 return false;
356 }
357 }
358
359
360
361
362
363
364 public void changeMode(boolean passive) {
365 this.isPassive = passive;
366 this.ftpClient.setPassive(passive);
367 }
368
369
370
371
372
373
374
375
376
377
378
379
380 public boolean transferFile(String local, String remote, int getStoreOrAppend) {
381 result = null;
382 try {
383 if (getStoreOrAppend > 0) {
384 File from = new File(local);
385 result = "Cannot finalize store like operation";
386 logger.debug("Will STOR: " + from);
387 try {
388 if (getStoreOrAppend == 1) {
389 this.ftpClient.upload(from, new DataTimeOutListener(ftpClient, timeout,
390 "STOR", local));
391 } else {
392
393 this.ftpClient.append(from, new DataTimeOutListener(ftpClient, timeout,
394 "APPE", local));
395 }
396 result = null;
397 } catch (IllegalStateException e) {
398 logger.error(result, e);
399 return false;
400 } catch (FTPIllegalReplyException e) {
401 logger.error(result, e);
402 return false;
403 } catch (FTPException e) {
404 logger.error(result, e);
405 return false;
406 } catch (FTPDataTransferException e) {
407 logger.error(result, e);
408 return false;
409 } catch (FTPAbortedException e) {
410 logger.error(result, e);
411 return false;
412 }
413 return true;
414 } else {
415 result = "Cannot finalize retrieve like operation";
416 if (local == null) {
417
418 NullOutputStream nullOutputStream = new NullOutputStream();
419 logger.debug("Will DLD nullStream: " + remote);
420 try {
421 this.ftpClient.download(remote, nullOutputStream, 0,
422 new DataTimeOutListener(ftpClient, timeout, "RETR", remote));
423 result = null;
424 } catch (IllegalStateException e) {
425 logger.error(result, e);
426 return false;
427 } catch (FTPIllegalReplyException e) {
428 logger.error(result, e);
429 return false;
430 } catch (FTPException e) {
431 logger.error(result, e);
432 return false;
433 } catch (FTPDataTransferException e) {
434 logger.error(result, e);
435 return false;
436 } catch (FTPAbortedException e) {
437 logger.error(result, e);
438 return false;
439 }
440 } else {
441 logger.debug("Will DLD to local: " + remote + " into " + local);
442 File to = new File(local);
443 try {
444 this.ftpClient.download(remote, to, new DataTimeOutListener(ftpClient,
445 timeout, "RETR", local));
446 result = null;
447 } catch (IllegalStateException e) {
448 logger.error(result, e);
449 return false;
450 } catch (FTPIllegalReplyException e) {
451 logger.error(result, e);
452 return false;
453 } catch (FTPException e) {
454 logger.error(result, e);
455 return false;
456 } catch (FTPDataTransferException e) {
457 logger.error(result, e);
458 return false;
459 } catch (FTPAbortedException e) {
460 logger.error(result, e);
461 return false;
462 }
463 }
464 return true;
465 }
466 } catch (IOException e) {
467 result = "Cannot finalize operation";
468 logger.error(result, e);
469 return false;
470 }
471 }
472
473
474
475
476
477 public String[] listFiles() {
478 try {
479 FTPFile[] list = this.ftpClient.list();
480 String[] results = new String[list.length];
481 int i = 0;
482 for (FTPFile file : list) {
483 results[i] = file.toString();
484 i++;
485 }
486 return results;
487 } catch (IOException e) {
488 result = "Cannot finalize transfer operation";
489 logger.error(result, e);
490 return null;
491 } catch (IllegalStateException e) {
492 result = "Cannot finalize transfer operation";
493 logger.error(result, e);
494 return null;
495 } catch (FTPIllegalReplyException e) {
496 result = "Cannot finalize transfer operation";
497 logger.error(result, e);
498 return null;
499 } catch (FTPException e) {
500 result = "Cannot finalize transfer operation";
501 logger.error(result, e);
502 return null;
503 } catch (FTPDataTransferException e) {
504 result = "Cannot finalize transfer operation";
505 logger.error(result, e);
506 return null;
507 } catch (FTPAbortedException e) {
508 result = "Cannot finalize transfer operation";
509 logger.error(result, e);
510 return null;
511 } catch (FTPListParseException e) {
512 result = "Cannot finalize transfer operation";
513 logger.error(result, e);
514 return null;
515 }
516 }
517
518
519
520
521
522
523 public boolean featureEnabled(String feature) {
524 try {
525 FTPReply reply = this.ftpClient.sendCustomCommand("FEAT");
526 String[] msg = reply.getMessages();
527 for (String string : msg) {
528 if (string.contains(feature.toUpperCase())) {
529 return true;
530 }
531 }
532 return false;
533 } catch (IOException e) {
534 result = "Cannot execute operation Feature";
535 logger.error(result, e);
536 return false;
537 } catch (IllegalStateException e) {
538 result = "Cannot execute operation Feature";
539 logger.error(result, e);
540 return false;
541 } catch (FTPIllegalReplyException e) {
542 result = "Cannot execute operation Feature";
543 logger.error(result, e);
544 return false;
545 }
546 }
547
548
549
550
551
552
553 public String[] executeCommand(String params) {
554 result = null;
555 try {
556 logger.debug(params);
557 FTPReply reply = this.ftpClient.sendCustomCommand(params);
558 if (!reply.isSuccessCode()) {
559 result = reply.toString();
560 return null;
561 }
562 return reply.getMessages();
563 } catch (IOException e) {
564 result = "Cannot execute operation Site";
565 logger.error(result, e);
566 return null;
567 } catch (IllegalStateException e) {
568 result = "Cannot execute operation Site";
569 logger.error(result, e);
570 return null;
571 } catch (FTPIllegalReplyException e) {
572 result = "Cannot execute operation Site";
573 logger.error(result, e);
574 return null;
575 }
576 }
577
578
579
580
581
582
583
584 public String[] executeSiteCommand(String params) {
585 result = null;
586 try {
587 logger.debug("SITE " + params);
588 FTPReply reply = this.ftpClient.sendSiteCommand(params);
589 if (!reply.isSuccessCode()) {
590 result = reply.toString();
591 return null;
592 }
593 return reply.getMessages();
594 } catch (IOException e) {
595 result = "Cannot execute operation Site";
596 logger.error(result, e);
597 return null;
598 } catch (IllegalStateException e) {
599 result = "Cannot execute operation Site";
600 logger.error(result, e);
601 return null;
602 } catch (FTPIllegalReplyException e) {
603 result = "Cannot execute operation Site";
604 logger.error(result, e);
605 return null;
606 }
607 }
608
609 }