KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jftp > net > FtpConnection


1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  */

16 package net.sf.jftp.net;
17
18
19 //***now all config files are imported
20
import java.io.BufferedReader JavaDoc;
21 import java.io.DataInputStream JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.InputStream JavaDoc;
25 import java.io.OutputStream JavaDoc;
26 import java.net.InetAddress JavaDoc;
27 import java.net.ServerSocket JavaDoc;
28 import java.net.UnknownHostException JavaDoc;
29 import java.util.Date JavaDoc;
30 import java.util.StringTokenizer JavaDoc;
31 import java.util.Vector JavaDoc;
32
33 import javax.swing.JLabel JavaDoc;
34 import javax.swing.JOptionPane JavaDoc;
35
36 import net.sf.jftp.config.LoadSet;
37 import net.sf.jftp.config.SaveSet;
38 import net.sf.jftp.config.Settings;
39 import net.sf.jftp.system.StringUtils;
40 import net.sf.jftp.system.logging.Log;
41
42
43 /**
44  * All control transactions are made here.
45  * See doc/FtpDownload.java for examples and note
46  * that this class is event-driven and not Exception-based!
47  * You might want to take a look at ConnectionListener, too.
48  *
49  * @author David Hansmann, hansmann.d@debitel.net
50  * @version 1.30+, June 2003
51  */

52 public class FtpConnection implements BasicConnection, FtpConstants
53 {
54     private static final boolean TESTMODE = false;
55
56     // everything starting with this will be treated
57
// as a negative response
58
private final static String JavaDoc NEGATIVE = "5";
59     private final static String JavaDoc NEGATIVE2 = "4";
60
61     // everything starting with this will be treated
62
// as a positive response
63
private final static String JavaDoc POSITIVE = "2";
64
65     // for resuming
66
private final static String JavaDoc PROCEED = "3"; //"350";
67
private final static char MORE_LINES_APPENDED = '-';
68
69     /** Internal download constant */
70     public final static String JavaDoc DOWNLOAD = "DOWNLOAD";
71
72     /** Internal upload constant */
73     public final static String JavaDoc UPLOAD = "UPLOAD";
74
75     /** Internal abort command constant */
76     public final static String JavaDoc ABOR = "ABOR";
77
78     //*** 1.44: if LIST is not set, then load it from advanced settings
79
//*** And if the file for it is not found, then create it
80
//*** with LIST -laL as the default
81
public static String JavaDoc LIST_DEFAULT = "LIST -laL";
82     public static String JavaDoc LIST = "default";
83     public final static String JavaDoc ASCII = "A";
84     public final static String JavaDoc BINARY = "I";
85     public final static String JavaDoc EBCDIC = "E";
86     public final static String JavaDoc L8 = "L 8";
87     public final static String JavaDoc STREAM = "S";
88     public final static String JavaDoc BLOCKED = "B";
89     public final static String JavaDoc COMPRESSED = "C";
90     private static boolean useStream = true;
91     private static boolean useBlocked = true;
92     private static boolean useCompressed = true;
93
94     // active ftp ports
95
private static int porta = 5; // 5 * 256 + 1 = 1281
96
private static int portb = 1;
97
98     //***
99

100     /**
101     * Used to determine the type of transfer.
102     */

103     public boolean hasUploaded = false;
104     public boolean work = true;
105     private boolean msg = true;
106     private boolean ok = true;
107     private String JavaDoc pwd = "";
108     private String JavaDoc initCWD = Settings.defaultDir;
109     private String JavaDoc[] loginAck = new String JavaDoc[]
110                                 {
111                                     FTP331_USER_OK_NEED_PASSWORD,
112                                     FTP230_LOGGED_IN
113                                 };
114     private String JavaDoc osType = "";
115     private String JavaDoc dataType;
116     private FtpTransfer lastTransfer = null;
117     private boolean modeStreamSet = false;
118     private DataConnection dcon = null;
119     private Vector JavaDoc listeners = new Vector JavaDoc();
120     private ConnectionHandler handler = new ConnectionHandler();
121
122     // directory downloaded to
123
private String JavaDoc localPath = null;
124
125     /** the host */
126     private String JavaDoc host = "";
127
128     /** the user */
129     private String JavaDoc username;
130
131     /** the password */
132     private String JavaDoc password;
133
134     /** the port */
135     private int port = 21;
136
137     /** the InputStream of the control connection */
138     private BufferedReader JavaDoc in;
139
140     /** the OutputStream of the control connection */
141     private JConnection jcon;
142
143     /** we are disconnected */
144     private boolean connected = false;
145     private boolean shortProgress = false;
146     private boolean isDirUpload = false;
147     private String JavaDoc baseFile;
148     private int fileCount;
149     private String JavaDoc typeNow = "";
150     private String JavaDoc crlf = null;
151
152     /**
153     * May contain date listing
154     */

155     public Vector JavaDoc dateVector = new Vector JavaDoc();
156     public Vector JavaDoc currentListing = new Vector JavaDoc();
157     public Vector JavaDoc currentFiles = new Vector JavaDoc();
158     public Vector JavaDoc currentSizes = new Vector JavaDoc();
159     public Vector JavaDoc currentPerms = new Vector JavaDoc();
160
161     /**
162     * Create an instance with a given host
163     *
164     * @param host The host to connect to
165     */

166     public FtpConnection(String JavaDoc host)
167     {
168         this.host = host;
169
170         File JavaDoc f = new File JavaDoc(".");
171         setLocalPath(f.getAbsolutePath());
172     }
173
174     /**
175     * Create an instance with a given host, port and initial remote working directory
176     *
177     * @param host The host to connect to
178     * @param port The port used for the control connection, usually 21
179     * @param initCWD The initial remote working directory
180     */

181     public FtpConnection(String JavaDoc host, int port, String JavaDoc initCWD)
182     {
183         this.host = host;
184         this.port = port;
185         this.initCWD = initCWD;
186
187         File JavaDoc f = new File JavaDoc(".");
188         setLocalPath(f.getAbsolutePath());
189     }
190
191     /**
192     * Connect to the server an log in.
193     *
194     * Does also fire directory update and connection initialized event if successful or
195     * connection failed event if failed.
196     *
197     * @param username The username
198     * @param password The password
199     * @param initCWD The initial remote working directory
200     * @param crlfx \n, \r, \r\n, CR, LF or CRLF - line break style of the server
201     * @return WRONG_LOGIN_DATA, OFFLINE, GENERIC_FAILED or LOGIN_OK status code
202     */

203     public FtpConnection(String JavaDoc host, int port, String JavaDoc initCWD, String JavaDoc crlfx)
204     {
205         this.host = host;
206         this.port = port;
207         this.initCWD = initCWD;
208     
209         if(crlfx != null) {
210             if(crlfx.equals("\n") || crlfx.equals("\r") || crlfx.equals("\r\n")) this.crlf = crlfx;
211             crlfx = crlfx.trim().toUpperCase();
212             if(crlfx.equals("LF")) this.crlf = "\n";
213             else if(crlfx.equals("CR")) this.crlf = "\r";
214             else if(crlfx.equals("CRLF")) this.crlf = "\r\n";
215         }
216         //Log.out("\n\nCRLF:---"+crlf+"---\n\n");
217

218         File JavaDoc f = new File JavaDoc(".");
219         setLocalPath(f.getAbsolutePath());
220     }
221
222     /**
223     * Connect to the server an log in.
224     *
225     * Does also fire directory update and connection initialized event if successful or
226     * connection failed event if failed.
227     *
228     * @param username The username
229     * @param password The password
230     * @return WRONG_LOGIN_DATA, OFFLINE, GENERIC_FAILED or LOGIN_OK status code
231     */

232     public int login(String JavaDoc username, String JavaDoc password)
233     {
234         this.username = username;
235         this.password = password;
236
237         int status = LOGIN_OK;
238
239         if(msg)
240         {
241             Log.debug("Connecting to " + host);
242         }
243
244         jcon = new JConnection(host, port);
245
246         if(jcon.isThere())
247         {
248             in = jcon.getReader();
249
250             if(getLine(POSITIVE) == null)//FTP220_SERVICE_READY) == null)
251
{
252                 ok = false;
253                 Log.debug("Server closed Connection, maybe too many users...");
254                 status = OFFLINE;
255             }
256
257             if(msg)
258             {
259                 Log.debug("Connection established...");
260             }
261
262             jcon.send(USER + " " + username);
263
264             if(!getLine(loginAck).startsWith(POSITIVE))//FTP230_LOGGED_IN))
265
{
266                 jcon.send(PASS + " " + password);
267
268                 if(success(POSITIVE))//FTP230_LOGGED_IN))
269
{
270                     if(msg)
271                     {
272                         Log.debug("Logged in...");
273                     }
274                 }
275                 else
276                 {
277                     Log.debug("Wrong password!");
278                     ok = false;
279                     status = WRONG_LOGIN_DATA;
280                 }
281             }
282
283             // end if(jcon)...
284
}
285         else
286         {
287             if(msg)
288             {
289                 Log.debug("FTP not available!");
290                 ok = false;
291                 status = GENERIC_FAILED;
292             }
293         }
294
295         if(ok)
296         {
297             connected = true;
298             system();
299
300             //if(getOsType().indexOf("MVS") < 0)
301
binary();
302
303             if(initCWD.trim().equals(Settings.defaultDir) ||
304                    !chdirNoRefresh(initCWD))
305             {
306                 //System.out.println("default dir...");
307
//if(!chdirNoRefresh(getPWD()))
308
//{
309
//System.out.println("FtpConnection should not do this...");
310
// if(!chdirNoRefresh("~"))
311
// {
312
// chdirNoRefresh("/");
313
// }
314
//}
315
updatePWD();
316             }
317
318             //Array of length 6 created, as that is maximum LoadSet size (need
319
//public variable with that constant there for it to refer to?)
320
String JavaDoc[] advSettings = new String JavaDoc[6];
321
322             if(getOsType().indexOf("OS/2") >= 0)
323             {
324                 LIST_DEFAULT = "LIST";
325             }
326
327             if(LIST.equals("default"))
328             {
329                 //just get the first item (somehow it knows first is the
330
//FTP list command)
331
advSettings = LoadSet.loadSet(Settings.adv_settings);
332
333                 //*** IF FILE NOT FOUND, CREATE IT AND SET IT TO LIST_DEFAULT
334
if(advSettings == null)
335                 {
336                     LIST = LIST_DEFAULT;
337
338                     SaveSet s = new SaveSet(Settings.adv_settings, LIST);
339                 }
340                 else
341                 {
342                     LIST = advSettings[0];
343
344                     if(LIST == null)
345                     {
346                         LIST = LIST_DEFAULT;
347                     }
348                 }
349             }
350
351             if(getOsType().indexOf("MVS") >= 0)
352             {
353                 LIST = "LIST";
354             }
355
356             //***
357
fireDirectoryUpdate(this);
358             fireConnectionInitialized(this);
359         }
360         else
361         {
362             fireConnectionFailed(this, new Integer JavaDoc(status).toString());
363         }
364
365         return status;
366     }
367
368     /**
369     * Sort the filesizes an return an array.
370     *
371     * The Array should be in sync with the other sort*-Methods
372     *
373     * @return An String-array of sizes containing the size or -1 if failed or 0 for directories
374     */

375     public String JavaDoc[] sortSize()
376     {
377         try
378         {
379             currentSizes.removeAllElements();
380             
381             for(int i=0; i<currentListing.size(); i++)
382             {
383                 String JavaDoc tmp = (String JavaDoc) currentListing.get(i);
384
385                 // ------------- VMS override -------------------
386
if(getOsType().indexOf("VMS") >= 0)
387                 {
388                     if(tmp.indexOf(";") < 0)
389                     {
390                         continue;
391                     }
392
393                     currentSizes.add("-1");
394
395                     continue;
396                 }
397
398                 // ------------- MVS override -------------------
399
if(getOsType().indexOf("MVS") >= 0)
400                 {
401                     if(tmp.startsWith("Volume") || (tmp.indexOf(" ") < 0))
402                     {
403                          continue;
404                     }
405
406                     currentSizes.add("-1");
407
408                     continue;
409                 }
410
411                 // ------------------------------------------------
412
else if(getOsType().indexOf("WINDOW") >= 0)
413                 {
414                     StringTokenizer JavaDoc to = new StringTokenizer JavaDoc(tmp, " ", false);
415
416                     if(to.countTokens() >= 4)
417                     {
418                         to.nextToken();
419                         to.nextToken();
420
421                         String JavaDoc size = to.nextToken();
422
423                         if(size.equals("<DIR>"))
424                         {
425                             currentSizes.add("0");
426                         }
427                         else
428                         {
429                             try
430                             {
431                                 Long.parseLong(size);
432                                 currentSizes.add(size);
433                             }
434                             catch(Exception JavaDoc ex)
435                             {
436                                 currentSizes.add("-1");
437                                 Log.out("WARNING: filesize can not be determined - value is " +
438                                         size);
439                             }
440                         }
441                     }
442                 }
443
444                 // ------------------------------------------------
445
else if(getOsType().indexOf("OS/2") >= 0)
446                 {
447                     StringTokenizer JavaDoc to = new StringTokenizer JavaDoc(tmp, " ", false);
448                     tmp = giveSize(to, 0);
449                     Log.out("OS/2 parser (size): " + tmp);
450                     currentSizes.add(tmp);
451                 }
452                 else
453                 {
454                     //Log.out("\n\nparser\n\n");
455
StringTokenizer JavaDoc to = new StringTokenizer JavaDoc(tmp, " ", false);
456
457                     if(to.countTokens() >= 8) // unix
458
{
459                         tmp = giveSize(to, 4);
460                         currentSizes.add(tmp);
461
462                         //Log.out(tmp);
463
}
464                     else if(to.countTokens() == 7) // unix, too
465
{
466                         Log.out("WARNING: 7 token backup size parser activated!");
467                         tmp = giveSize(to, 4);
468                         currentSizes.add(tmp);
469                     }
470                     else
471                     {
472                         Log.debug("cannot parse line: " + tmp);
473                     }
474                 }
475             }
476         }
477         catch(Exception JavaDoc ex)
478         {
479             Log.debug(ex.toString() + " @FtpConnection::sortSize#1");
480             return new String JavaDoc[0];
481         }
482
483         return toArray(currentSizes);
484     }
485
486     private String JavaDoc[] toArray(Vector JavaDoc in) {
487         String JavaDoc ret[] = new String JavaDoc[in.size()];
488         
489         for(int i=0; i<in.size(); i++) {
490             ret[i] = (String JavaDoc) in.get(i);
491         }
492         
493         return ret;
494     }
495     
496     /**
497     * Sort the permissions an return an array.
498     *
499     * The Array should be in sync with the other sort*-Methods
500     *
501     * @param file The file containing the raw server listing, usually Settings.ls_out
502     * @return An int-array of sizes containing W, R or DENIED for each file
503     */

504     public int[] getPermissions()
505     {
506         try
507         {
508             currentPerms.removeAllElements();
509             
510             for(int i=0; i<currentListing.size(); i++)
511             {
512                 String JavaDoc tmp = (String JavaDoc) currentListing.get(i);
513
514                 // ------------- VMS override -------------------
515
if(getOsType().indexOf("VMS") >= 0)
516                 {
517                     if(tmp.indexOf(";") < 0)
518                     {
519                         continue;
520                     }
521
522                     currentPerms.add("r");
523
524                     continue;
525                 }
526
527                 // ------------- MVS override -------------------
528
if(getOsType().indexOf("MVS") >= 0)
529                 {
530                     if(tmp.startsWith("Volume"))
531                     {
532                         continue;
533                     }
534
535                     currentPerms.add("r");
536
537                     continue;
538                 }
539
540                 // ------------------------------------------------
541

542                 StringTokenizer JavaDoc to = new StringTokenizer JavaDoc(tmp.trim(), " ", false);
543
544                 if(!(to.countTokens() > 3) ||
545                        (tmp.startsWith("/") && (tmp.indexOf("denied") > 0)))
546                 {
547                     continue;
548                 }
549
550                 tmp = to.nextToken();
551
552                 if(tmp.length() != 10)
553                 {
554                     //System.out.println(tmp + " - e");
555
return null; // exotic bug, hardlinks are not found or something ("/bin/ls: dir: no such file or directy" in ls output) - we have no permissions then
556
}
557
558                 char ur = tmp.charAt(1);
559                 char uw = tmp.charAt(2);
560                 char ar = tmp.charAt(7);
561                 char aw = tmp.charAt(8);
562
563                 to.nextToken();
564
565                 String JavaDoc user = to.nextToken();
566
567                 //System.out.println(""+ur+":"+ar+":"+tmp);
568
if(aw == 'w')
569                 {
570                     currentPerms.add("w");
571                 }
572                 else if(user.equals(username) && (uw == 'w'))
573                 {
574                     currentPerms.add("w");
575                 }
576                 else if(ar == 'r')
577                 {
578                     currentPerms.add("r");
579                 }
580                 else if(user.equals(username) && (ur == 'r'))
581                 {
582                     currentPerms.add("r");
583                 }
584                 else
585                 {
586                     //System.out.println(ur+":"+ar+":"+user+":"+username+":");
587
currentPerms.add("n");
588                 }
589             }
590         }
591         catch(Exception JavaDoc ex)
592         {
593             Log.debug(ex.toString() + " @FtpConnection::getPermissions#1");
594         }
595
596         int[] ret = new int[currentPerms.size()];
597         
598         for(int i=0; i<currentPerms.size(); i++) {
599             String JavaDoc fx = (String JavaDoc) currentPerms.get(i);
600             
601             if(fx.equals("w"))
602             {
603                 ret[i] = W;
604             }
605             else if(fx.equals("n"))
606             {
607                 ret[i] = DENIED;
608             }
609             else
610             {
611                 ret[i] = R;
612             }
613             //System.out.println(ret[i]);
614
}
615     
616         return ret;
617     }
618
619     /**
620     * Sort the filenames of the current working dir an return an array.
621     *
622     * The Array should be in sync with the other sort*-Methods
623     *
624     * @return An String-array of sizes containing the name of the file (symlinks are resolved)
625     */

626     public String JavaDoc[] sortLs()
627     {
628         try
629         {
630             boolean newUnixDateStyle = false;
631             dateVector = new Vector JavaDoc();
632             currentFiles.removeAllElements();
633             
634             for(int i=0; i<currentListing.size(); i++)
635             {
636                 String JavaDoc tmp = (String JavaDoc) currentListing.get(i);
637
638                 // ------------------- VMS override --------------------
639
if(getOsType().indexOf("VMS") >= 0)
640                 {
641                     int x = tmp.indexOf(";");
642
643                     if(x < 0)
644                     {
645                         continue;
646                     }
647
648                     tmp = tmp.substring(0, x);
649
650                     if(tmp.endsWith("DIR"))
651                     {
652                         currentFiles.add(tmp.substring(0, tmp.lastIndexOf(".")) +
653                                     "/");
654                     }
655                     else
656                     {
657                         currentFiles.add(tmp);
658                     }
659
660                     //Log.out("listing - (vms parser): " + tmp);
661

662                     continue;
663                 }
664                 else if(getOsType().indexOf("OS/2") >= 0)
665                 {
666                     StringTokenizer JavaDoc to2 = new StringTokenizer JavaDoc(tmp, " ", true);
667
668                     if(giveFile(to2, 2).indexOf("DIR") >= 0)
669                     {
670                         to2 = new StringTokenizer JavaDoc(tmp, " ", true);
671                         tmp = giveFile(to2, 5);
672                         tmp = tmp + "/";
673                     }
674                     else
675                     {
676                         to2 = new StringTokenizer JavaDoc(tmp, " ", true);
677
678                         if(giveFile(to2, 1).indexOf("DIR") >= 0)
679                         {
680                             //Log.out("OS/2 parser (DIRFIX): " + tmp);
681
to2 = new StringTokenizer JavaDoc(tmp, " ", true);
682                             tmp = giveFile(to2, 4);
683                             tmp = tmp + "/";
684                         }
685                         else
686                         {
687                             to2 = new StringTokenizer JavaDoc(tmp, " ", true);
688                             tmp = giveFile(to2, 4);
689                         }
690                     }
691
692                     Log.out("OS/2 parser: " + tmp);
693                     currentFiles.add(tmp);
694
695                     continue;
696                 }
697
698                 // -------------------------------------------------------
699
// ------------------- MVS override --------------------
700
if(getOsType().indexOf("MVS") >= 0)
701                 {
702                     if(tmp.startsWith("Volume") || (tmp.indexOf(" ") < 0))
703                     {
704                         Log.out("->" + tmp);
705
706                         continue;
707                     }
708
709                     String JavaDoc f = tmp.substring(tmp.lastIndexOf(" ")).trim();
710                     String JavaDoc isDir = tmp.substring(tmp.lastIndexOf(" ") - 5,
711                                                  tmp.lastIndexOf(" "));
712
713                     if(isDir.indexOf("PO") >= 0)
714                     {
715                         currentFiles.add(f + "/");
716                     }
717                     else
718                     {
719                         currentFiles.add(f);
720                     }
721
722                     Log.out("listing - (mvs parser): " + tmp + " -> " + f);
723                     continue;
724                 }
725                 else if(getOsType().indexOf("OS/2") >= 0)
726                 {
727                     StringTokenizer JavaDoc to2 = new StringTokenizer JavaDoc(tmp, " ", true);
728
729                     if(giveFile(to2, 2).indexOf("DIR") >= 0)
730                     {
731                         to2 = new StringTokenizer JavaDoc(tmp, " ", true);
732                         tmp = giveFile(to2, 5);
733                         tmp = tmp + "/";
734                     }
735                     else
736                     {
737                         to2 = new StringTokenizer JavaDoc(tmp, " ", true);
738
739                         if(giveFile(to2, 1).indexOf("DIR") >= 0)
740                         {
741                             //Log.out("OS/2 parser (DIRFIX): " + tmp);
742
to2 = new StringTokenizer JavaDoc(tmp, " ", true);
743                             tmp = giveFile(to2, 4);
744                             tmp = tmp + "/";
745                         }
746                         else
747                         {
748                             to2 = new StringTokenizer JavaDoc(tmp, " ", true);
749                             tmp = giveFile(to2, 4);
750                         }
751                     }
752
753                     Log.out("OS/2 parser: " + tmp);
754                     currentFiles.add(tmp);
755
756                     continue;
757                 }
758
759                 // -------------------------------------------------------
760
// ------------------- Unix, Windows and others -----
761
boolean isDir = false;
762                 boolean isLink = false;
763
764                 if(tmp.startsWith("d") || (tmp.indexOf("<DIR>") >= 0))
765                 {
766                     isDir = true;
767                 }
768
769                 if(tmp.startsWith("l"))
770                 {
771                     isLink = true;
772                 }
773
774                 if(tmp.startsWith("/") && (tmp.indexOf("denied") > 0))
775                 {
776                     continue;
777                 }
778
779                 StringTokenizer JavaDoc to = new StringTokenizer JavaDoc(tmp, " ", false);
780                 StringTokenizer JavaDoc to2 = new StringTokenizer JavaDoc(tmp, " ", true);
781
782                 int tokens = to.countTokens();
783
784                 //Log.out("listing: tokens: " + tokens + " - " + tmp);
785
boolean set = false;
786
787                 //-----preparsing-----
788
int lcount = 0;
789
790                 if(!newUnixDateStyle)
791                 {
792                     try
793                     {
794                         StringTokenizer JavaDoc tx = new StringTokenizer JavaDoc(tmp, " ", false);
795                         tx.nextToken();
796                         tx.nextToken();
797                         tx.nextToken();
798                         tx.nextToken();
799                         tx.nextToken();
800
801                         String JavaDoc date = tx.nextToken();
802                         int x = date.indexOf("-");
803                         int y = date.lastIndexOf("-");
804
805                         if(y > x)
806                         {
807                             Log.debug("Using new Unix date parser");
808                             newUnixDateStyle = true;
809                         }
810                     }
811                     catch(Exception JavaDoc ex)
812                     {
813                         Log.out("could not preparse line: " + tmp);
814                         lcount++;
815
816                         //ex.printStackTrace();
817
}
818                 }
819
820                 //--------------------
821
//Log.out("tmp: " + tmp);
822
if(newUnixDateStyle) // unix, too
823
{
824                     set = true;
825
826                     //Log.out("listing - (unix parser #2, token 7): " + tmp);
827
//------- date parser testing ---------
828
try
829                     {
830                         //Log.out(">>> date parser: " + tmp);
831
StringTokenizer JavaDoc to3 = new StringTokenizer JavaDoc(tmp, " ", true);
832                         String JavaDoc date = giveFile(to3, 5);
833                         String JavaDoc date2 = date.substring(date.indexOf("-") + 1);
834                         date2 = date2.substring(date.indexOf("-") + 2);
835
836                         //Log.out("date1: "+date+"/"+"date2: "+date2);
837
String JavaDoc t = date;
838                         String JavaDoc y = t.substring(0, t.indexOf("-"));
839                         String JavaDoc m = t.substring(t.indexOf("-") + 1,
840                                                t.indexOf("-") + 3);
841                         String JavaDoc m1 = t.substring(t.indexOf("-") + 1);
842                         String JavaDoc day = m1.substring(m1.indexOf("-") + 1,
843                                                   m1.indexOf("-") + 3);
844                         String JavaDoc h = date2.substring(0, date2.indexOf(":"));
845                         String JavaDoc min = date2.substring(date2.indexOf(":") + 1,
846                                                      date2.indexOf(":") + 3);
847
848                         //Log.out("day:"+day+"year:"+y+"mon:"+m+"hour:"+h+"m:"+min);
849
Date JavaDoc d = new Date JavaDoc();
850                         d.setDate(Integer.parseInt(day));
851                         d.setYear(Integer.parseInt(y));
852                         d.setMonth(Integer.parseInt(m) - 1);
853                         d.setHours(Integer.parseInt(h));
854                         d.setMinutes(Integer.parseInt(min));
855
856                         dateVector.add(d);
857
858                         //Log.out("+++ date: \"" + d.toString() + "\"");
859
}
860                     catch(Exception JavaDoc ex)
861                     {
862                         ex.printStackTrace();
863
864                         //set = false;
865
}
866
867                     // -----------------------------
868
tmp = giveFile(to2, 7);
869
870                     if(lcount > 1)
871                     {
872                         dateVector = new Vector JavaDoc();
873                     }
874                 }
875                 else if(tokens > 8) // unix
876
{
877                     set = true;
878                     tmp = giveFile(to2, 8);
879
880                     //Log.out("listing - (unix parser, token 8): " + tmp);
881
}
882                 else if(tokens > 3) // windows
883
{
884                     set = true;
885                     tmp = giveFile(to2, 3);
886
887                     if(tmp.startsWith("<error>"))
888                     {
889                         tmp = giveFile(to2, 4);
890
891                         //Log.out("listing - (windows parser, token 4): " + tmp);
892
}
893                     else
894                     {
895                         //Log.out("listing - (windows parser, token 3): " + tmp);
896
}
897                 }
898
899                 if(tmp.startsWith("<error>") || !set)
900                 {
901                     if(tokens < 3)
902                     {
903                         continue;
904                     }
905
906                     tmp = giveFile(to2, tokens);
907                     Log.out("listing - WARNING: listing style unknown, using last token as filename!");
908                     Log.out("listing - this may work but may also fail, filesizes and permissions will probably fail, too...");
909                     Log.out("listing - please send us a feature request with the serveraddress to let us support this listing style :)");
910                     Log.out("listing - (backup parser, token " + tokens +
911                             " ): " + tmp);
912                 }
913
914                 if(isDir)
915                 {
916                     tmp = tmp + "/";
917                 }
918                 else if(isLink)
919                 {
920                     tmp = tmp + "###";
921                 }
922
923                 currentFiles.add(tmp);
924                 // -------------------------------------------------------------
925
}
926
927             String JavaDoc[] files = toArray(currentFiles);
928
929             for(int i = 0; i < files.length; i++)
930             {
931                 files[i] = parseSymlink(files[i]);
932
933                 //System.out.println("> " + files[i]+":"+dateVector.elementAt(i));
934
//System.out.println("> " + files.length+":"+dateVector.size());
935
}
936
937             return files;
938         }
939         catch(Exception JavaDoc ex)
940         {
941             Log.debug(ex.toString() + " @FtpConnection::sortLs");
942             ex.printStackTrace();
943         }
944
945         //------- date parser test ------
946

947         /*
948         String[] x = (String[]) dateVector.toArray();
949         for(int i=0; i<x.length; i++)
950         {
951                 Log.out(":"+x[i]);
952         }
953         */

954
955         //-------------------------------
956
return new String JavaDoc[0];
957     }
958
959     /** get a filename */
960     private String JavaDoc giveFile(StringTokenizer JavaDoc to, int lev)
961     {
962         String JavaDoc t2 = null;
963
964         for(int i = 0; i < lev; i++)
965         {
966             if(to.hasMoreTokens())
967             {
968                 String JavaDoc t = to.nextToken();
969
970                 //Log.out("> "+t);
971
if(t.equals(" ") || t.equals("\t"))
972                 {
973                     // -
974

975                     /*
976                        while(to.hasMoreTokens())
977                        {
978                                t2 = to.nextToken();
979                            if(!t.equals(" ") && !t.equals("\t")) break;
980                        }
981                     */

982                     i--;
983                 }
984             }
985         }
986
987         String JavaDoc tmp = "<error>";
988
989         /*
990         if(t2 != null)
991         {
992                 tmp = t2;
993         }
994         */

995         while(tmp.equals(" ") || tmp.equals("\t") || tmp.equals("<error>"))
996         {
997             if(to.hasMoreTokens())
998             {
999                 tmp = to.nextToken();
1000            }
1001            else
1002            {
1003                break;
1004            }
1005        }
1006
1007        while(to.hasMoreTokens())
1008        {
1009            tmp = tmp + to.nextToken();
1010        }
1011
1012        //Log.out(">>> "+tmp);
1013
return tmp;
1014    }
1015
1016    /** get a filesize */
1017    private String JavaDoc giveSize(StringTokenizer JavaDoc to, int lev)
1018    {
1019        for(int i = 0; i < lev; i++)
1020        {
1021            if(to.hasMoreTokens())
1022            {
1023                if(to.nextToken().equals(" "))
1024                {
1025                    i--;
1026                }
1027            }
1028        }
1029
1030        while(to.hasMoreTokens())
1031        {
1032            String JavaDoc tmp = to.nextToken();
1033
1034            if(!tmp.equals(" "))
1035            {
1036                try
1037                {
1038                    Integer.parseInt(tmp);
1039                }
1040                catch(NumberFormatException JavaDoc ex)
1041                {
1042                    return "-1";
1043                }
1044
1045                return tmp;
1046            }
1047        }
1048
1049        return "-2";
1050    }
1051
1052    /**
1053    * Try to determine the os-type.
1054    * (Used internally to check how to parse the ls-output)
1055    *
1056    * @return A Part of the SYST comman server response
1057    */

1058    public String JavaDoc getOsType()
1059    {
1060        if(TESTMODE)
1061        {
1062            return "MVS";
1063        }
1064        else
1065        {
1066            return osType;
1067        }
1068    }
1069
1070    private void setOsType(String JavaDoc os)
1071    {
1072        osType = os.toUpperCase();
1073    }
1074
1075    private int getPasvPort(String JavaDoc str)
1076    {
1077        int start = str.lastIndexOf(",");
1078        String JavaDoc lo = "";
1079        start++;
1080
1081        while(start < str.length())
1082        {
1083            char c = str.charAt(start);
1084
1085            if(!Character.isDigit(c))
1086            {
1087                break;
1088            }
1089
1090            lo = lo + c;
1091            start++;
1092        }
1093
1094        System.out.println("\n\n\n"+str);
1095        
1096        String JavaDoc hi = "";
1097        start = str.lastIndexOf(",");
1098        start--;
1099
1100        while(true)
1101        {
1102            char c = str.charAt(start);
1103
1104            if(!Character.isDigit(c))
1105            {
1106                break;
1107            }
1108
1109            hi = c + hi;
1110            start--;
1111        }
1112
1113        //System.out.print(hi+":"+lo+" - ");
1114
return ((Integer.parseInt(hi) * 256) + Integer.parseInt(lo));
1115    }
1116
1117    private int getActivePort()
1118    {
1119        return (getPortA() * 256) + getPortB();
1120    }
1121
1122    /** parse a symlink */
1123    private String JavaDoc parseSymlink(String JavaDoc file)
1124    {
1125        if(file.indexOf("->") >= 0)
1126        {
1127            //System.out.print(file+" :-> symlink converted to:");
1128
file = file.substring(0, file.indexOf("->")).trim();
1129            file = file + "###";
1130
1131            //System.out.println(file);
1132
}
1133
1134        return file;
1135    }
1136
1137    /** parse a symlink and cut the back */
1138    private String JavaDoc parseSymlinkBack(String JavaDoc file)
1139    {
1140        if(file.indexOf("->") >= 0)
1141        {
1142            //System.out.print(file+" :-> symlink converted to:");
1143
file = file.substring(file.indexOf("->") + 2).trim();
1144
1145            //System.out.println(file);
1146
}
1147
1148        return file;
1149    }
1150
1151    /** test for symlink */
1152    private boolean isSymlink(String JavaDoc file)
1153    {
1154        if(file.indexOf("->") >= 0)
1155        {
1156            return true;
1157        }
1158
1159        return false;
1160    }
1161
1162    /** Download a file or directory.
1163    * Uses multithreading if enabled and does not block.
1164    *
1165    * @param file The file to download
1166    * @return An int-statuscode, see constants defined in this class for details
1167    */

1168    public int handleDownload(String JavaDoc file)
1169    {
1170        if(Settings.getEnableMultiThreading())
1171        {
1172            Log.out("spawning new thread for this download.");
1173
1174            FtpTransfer t = new FtpTransfer(host, port, getLocalPath(),
1175                                            getCachedPWD(), file, username,
1176                                            password, Transfer.DOWNLOAD,
1177                                            handler, listeners, crlf);
1178            lastTransfer = t;
1179
1180            return NEW_TRANSFER_SPAWNED;
1181        }
1182        else
1183        {
1184            Log.out("multithreading is completely disabled.");
1185
1186            return download(file);
1187        }
1188    }
1189
1190    /**
1191    * Download a file or directory, block until finished.
1192    *
1193    * @param file The file to download
1194    * @return An int returncode
1195    */

1196    public int download(String JavaDoc file)
1197    {
1198        //Log.out("ftp download started:" + this);
1199

1200        int stat;
1201
1202        if(file.endsWith("/"))
1203        {
1204            shortProgress = true;
1205            fileCount = 0;
1206            baseFile = file;
1207            dataType = DataConnection.GETDIR;
1208
1209            stat = downloadDir(file);
1210
1211            //pause(100);
1212
fireActionFinished(this);
1213            fireProgressUpdate(baseFile,
1214                               DataConnection.DFINISHED + ":" + fileCount, -1);
1215            shortProgress = false;
1216        }
1217        else
1218        {
1219            dataType = DataConnection.GET;
1220
1221            stat = rawDownload(file);
1222
1223        if(Settings.enableFtpDelays) {
1224             try
1225             {
1226                Thread.sleep(100);
1227             } catch(Exception JavaDoc ex) {}
1228        }
1229
1230            fireActionFinished(this);
1231        }
1232
1233    if(Settings.enableFtpDelays) {
1234         try
1235         {
1236            Thread.sleep(400);
1237         }
1238         catch(Exception JavaDoc ex)
1239         {
1240         }
1241    }
1242
1243        return stat;
1244    }
1245
1246    /**
1247    * Get download InputStream.
1248    *
1249    * @param file The file to download
1250    * @return An InputStream
1251    */

1252    public InputStream JavaDoc getDownloadInputStream(String JavaDoc file)
1253    {
1254        Log.out("ftp stream download started:" + this);
1255        file = parse(file);
1256
1257        try
1258        {
1259            int p = 0;
1260            dataType = DataConnection.GET;
1261            file = StringUtils.getFile(file);
1262
1263            String JavaDoc path = getLocalPath() + file;
1264
1265            BufferedReader JavaDoc in = jcon.getReader();
1266
1267            modeStream();
1268            p = negotiatePort();
1269
1270            dcon = new DataConnection(this, p, host, path, dataType, false, true);
1271
1272            while(!dcon.isThere())
1273            {
1274                pause(10);
1275            }
1276
1277            jcon.send(RETR + " " + file);
1278
1279            return dcon.getInputStream();
1280        }
1281        catch(Exception JavaDoc ex)
1282        {
1283            ex.printStackTrace();
1284            Log.debug(ex.toString() +
1285                      " @FtpConnection::getDownloadInputStream");
1286
1287            return null;
1288        }
1289    }
1290
1291    private int rawDownload(String JavaDoc file)
1292    {
1293        file = parse(file);
1294
1295        //String path = file;
1296
try
1297        {
1298            int p = 0;
1299
1300            //if(isRelative(file)) path = getLocalPath() + file;
1301
file = StringUtils.getFile(file);
1302
1303            String JavaDoc path = getLocalPath() + file;
1304
1305            //System.out.println(file + " : " + path);
1306
//BufferedReader in = jcon.getReader();
1307
modeStream();
1308
1309            //binary();
1310
p = negotiatePort();
1311
1312            File JavaDoc f = new File JavaDoc(path);
1313
1314            //System.out.println("path: "+path);
1315
boolean resume = false;
1316
1317            if(f.exists() && Settings.enableResuming)
1318            {
1319                jcon.send(REST + " " + f.length());
1320
1321                if(getLine(PROCEED) != null)
1322                {
1323                    resume = true;
1324                }
1325            }
1326
1327            dcon = new DataConnection(this, p, host, path, dataType, resume); //, new Updater());
1328

1329            while(!dcon.isThere())
1330            {
1331                pause(10);
1332            }
1333
1334            jcon.send(RETR + " " + file);
1335
1336            String JavaDoc line = getLine(POSITIVE);
1337            Log.debug(line);
1338
1339            // file has been created even if not downloaded, delete it
1340
if(line.startsWith(NEGATIVE))
1341            {
1342                File JavaDoc f2 = new File JavaDoc(path);
1343
1344                if(f2.exists() && (f2.length() == 0))
1345                {
1346                    f2.delete();
1347                }
1348
1349                return PERMISSION_DENIED;
1350            }
1351            else if(!line.startsWith(POSITIVE) && !line.startsWith(PROCEED))
1352            {
1353                return TRANSFER_FAILED;
1354            }
1355
1356            // we need to block since some ftp-servers do not want the
1357
// refresh command that dirpanel sends otherwise
1358
while(!dcon.finished)
1359            {
1360                pause(10);
1361            }
1362        }
1363        catch(Exception JavaDoc ex)
1364        {
1365            ex.printStackTrace();
1366            Log.debug(ex.toString() + " @FtpConnection::download");
1367
1368            return TRANSFER_FAILED;
1369        }
1370
1371        return TRANSFER_SUCCESSFUL;
1372    }
1373
1374    private int downloadDir(String JavaDoc dir)
1375    {
1376        if(!dir.endsWith("/"))
1377        {
1378            dir = dir + "/";
1379        }
1380
1381        if(StringUtils.isRelative(dir))
1382        {
1383            dir = getCachedPWD() + dir;
1384        }
1385
1386        String JavaDoc path = getLocalPath() + StringUtils.getDir(dir);
1387
1388        //System.out.println("path: "+path);
1389
String JavaDoc pwd = getCachedPWD() + StringUtils.getDir(dir);
1390
1391        String JavaDoc oldDir = getLocalPath();
1392        String JavaDoc oldPwd = getCachedPWD();
1393
1394        File JavaDoc f = new File JavaDoc(path);
1395
1396        if(!f.exists())
1397        {
1398            if(!f.mkdir())
1399            {
1400                Log.debug("Can't create directory: " + dir);
1401            }
1402            else
1403            {
1404                Log.debug("Created directory...");
1405            }
1406        }
1407
1408        setLocalPath(path);
1409
1410        if(!chdirNoRefresh(pwd))
1411        {
1412            return CHDIR_FAILED;
1413        }
1414
1415        try
1416        {
1417            list();
1418        }
1419        catch(IOException JavaDoc ex)
1420        {
1421            return PERMISSION_DENIED;
1422        }
1423
1424        String JavaDoc[] tmp = sortLs();
1425
1426        setLocalPath(path);
1427
1428        for(int i = 0; i < tmp.length; i++)
1429        {
1430            if(tmp[i].endsWith("/"))
1431            {
1432                if(tmp[i].trim().equals("../") || tmp[i].trim().equals("./"))
1433                {
1434                    Log.debug("Skipping " + tmp[i].trim());
1435                }
1436                else
1437                {
1438                    if(!work)
1439                    {
1440                        return TRANSFER_STOPPED;
1441                    }
1442
1443                    if(downloadDir(tmp[i]) < 0)
1444                    {
1445                        ; // return TRANSFER_FAILED;
1446
}
1447                }
1448            }
1449            else
1450            {
1451                //System.out.println( "file: " + getLocalPath() + tmp[i] + "\n\n");
1452
if(!work)
1453                {
1454                    return TRANSFER_STOPPED;
1455                }
1456
1457                fileCount++;
1458
1459                if(rawDownload(getLocalPath() + tmp[i]) < 0)
1460                {
1461                    ; // return TRANSFER_FAILED;
1462
}
1463            }
1464        }
1465
1466        chdirNoRefresh(oldPwd);
1467        setLocalPath(oldDir);
1468
1469        return TRANSFER_SUCCESSFUL;
1470    }
1471
1472    /** Upload a file or directory.
1473    * Uses multithreading if enabled and does not block.
1474    *
1475    * @param file The file to upload
1476    * @return An int-statuscode, NEW_TRANSFER_SPAWNED,TRANSFER_FAILED or TRANSFER_SUCCESSFUL
1477    */

1478    public int handleUpload(String JavaDoc file)
1479    {
1480        return handleUpload(file, null);
1481    }
1482
1483    /** Upload a file or directory.
1484    * Uses multithreading if enabled and does not block.
1485    *
1486    * @param file The file to upload
1487    * @param realName The file to rename the uploaded file to
1488    * @return An int-statuscode, NEW_TRANSFER_SPAWNED,TRANSFER_FAILED or TRANSFER_SUCCESSFUL
1489    */

1490    public int handleUpload(String JavaDoc file, String JavaDoc realName)
1491    {
1492        if(Settings.getEnableMultiThreading() &&
1493               (!Settings.getNoUploadMultiThreading()))
1494        {
1495            Log.out("spawning new thread for this upload.");
1496
1497            FtpTransfer t;
1498
1499            if(realName != null)
1500            {
1501                t = new FtpTransfer(host, port, getLocalPath(), getCachedPWD(),
1502                                    file, username, password, Transfer.UPLOAD,
1503                                    handler, listeners, realName, crlf);
1504            }
1505            else
1506            {
1507                t = new FtpTransfer(host, port, getLocalPath(), getCachedPWD(),
1508                                    file, username, password, Transfer.UPLOAD,
1509                                    handler, listeners, crlf);
1510            }
1511
1512            lastTransfer = t;
1513
1514            return NEW_TRANSFER_SPAWNED;
1515        }
1516        else
1517        {
1518            if(Settings.getNoUploadMultiThreading())
1519            {
1520                Log.out("upload multithreading is disabled.");
1521            }
1522            else
1523            {
1524                Log.out("multithreading is completely disabled.");
1525            }
1526
1527            return (realName == null) ? upload(file) : upload(file, realName);
1528        }
1529    }
1530
1531    /**
1532    * Upload a file or directory, block until finished.
1533    *
1534    * @param file The file to upload
1535    * @return An int returncode
1536    */

1537    public int upload(String JavaDoc file)
1538    {
1539        return upload(file, file);
1540    }
1541
1542    /**
1543    * Upload and a file or directory under a given name, block until finished.
1544    * Note that setting realName does not affect directory transfers
1545    *
1546    * @param file The file to upload
1547    * @param realName The file to rename the uploaded file to
1548    * @return An int responsecode
1549    */

1550    public int upload(String JavaDoc file, String JavaDoc realName)
1551    {
1552        return upload(file, realName, null);
1553    }
1554
1555    /**
1556    * Upload from an InputStream, block until finished.
1557    *
1558    * @param file The file to upload
1559    * @param in InputStream to read from
1560    * @return An int responsecode
1561    */

1562    public int upload(String JavaDoc file, InputStream JavaDoc in)
1563    {
1564        return upload(file, file, in);
1565    }
1566
1567    /**
1568    * Upload and a file or directory under a given name, block until finished.
1569    * Note that setting realName does not affect directory transfers
1570    *
1571    * @param file The file to upload
1572    * @param realName The file to rename the uploaded file to
1573    * @param in InputStream to read from
1574    * @return An int responsecode
1575    */

1576    public int upload(String JavaDoc file, String JavaDoc realName, InputStream JavaDoc in)
1577    {
1578        hasUploaded = true;
1579        Log.out("ftp upload started: " + this);
1580
1581        int stat;
1582
1583        if((in == null) && new File JavaDoc(file).isDirectory())
1584        {
1585            shortProgress = true;
1586            fileCount = 0;
1587            baseFile = file;
1588            dataType = DataConnection.PUTDIR;
1589            isDirUpload = true;
1590
1591            stat = uploadDir(file);
1592
1593            shortProgress = false;
1594
1595            //System.out.println(fileCount + ":" + baseFile);
1596
fireProgressUpdate(baseFile,
1597                               DataConnection.DFINISHED + ":" + fileCount, -1);
1598
1599            fireActionFinished(this);
1600            fireDirectoryUpdate(this);
1601        }
1602        else
1603        {
1604            dataType = DataConnection.PUT;
1605            stat = rawUpload(file, realName, in);
1606
1607            try
1608            {
1609                Thread.sleep(100);
1610            }
1611            catch(Exception JavaDoc ex)
1612            {
1613            }
1614
1615            fireActionFinished(this);
1616            fireDirectoryUpdate(this);
1617        }
1618
1619        try
1620        {
1621            Thread.sleep(500);
1622        }
1623        catch(Exception JavaDoc ex)
1624        {
1625        }
1626
1627        return stat;
1628    }
1629
1630    private int rawUpload(String JavaDoc file)
1631    {
1632        return rawUpload(file, file);
1633    }
1634
1635    private int rawUpload(String JavaDoc file, String JavaDoc realName)
1636    {
1637        return rawUpload(file, realName, null);
1638    }
1639
1640    /** uploads a file */
1641    private int rawUpload(String JavaDoc file, String JavaDoc realName, InputStream JavaDoc in)
1642    {
1643        if(!file.equals(realName))
1644        {
1645            Log.debug("File: " + file + ", stored as " + realName);
1646        }
1647        else
1648        {
1649            Log.debug("File: " + file);
1650            realName = null;
1651        }
1652
1653        file = parse(file);
1654
1655        String JavaDoc path = file;
1656
1657        try
1658        {
1659            int p = 0;
1660
1661            if(StringUtils.isRelative(file))
1662            {
1663                path = getLocalPath() + file;
1664            }
1665
1666            file = StringUtils.getFile(file);
1667
1668            //BufferedReader in = jcon.getReader();
1669
boolean resume = false;
1670            String JavaDoc size = "0";
1671
1672            if(Settings.enableUploadResuming && (in == null))
1673            {
1674                list();
1675
1676                String JavaDoc[] ls = sortLs();
1677                String JavaDoc[] sizes = sortSize();
1678
1679                if((ls == null) || (sizes == null))
1680                {
1681                    Log.out(">>> ls out of sync (skipping resume check)");
1682                }
1683                else
1684                {
1685                    for(int i = 0; i < ls.length; i++)
1686                    {
1687                        //Log.out(ls[i] + ":" + sizes[i]);
1688
if(realName != null)
1689                        {
1690                            if(ls[i].equals(realName))
1691                            {
1692                                resume = true;
1693                                size = sizes[i];
1694
1695                                break;
1696                            }
1697                        }
1698                        else
1699                        {
1700                            if(ls[i].equals(file))
1701                            {
1702                                resume = true;
1703                                size = sizes[i];
1704                            }
1705                        }
1706                    }
1707
1708                    File JavaDoc f = new File JavaDoc(path);
1709
1710                    if(f.exists() && (f.length() <= Integer.parseInt(size)))
1711                    {
1712                        Log.out("skipping resuming, file is <= filelength");
1713                        resume = false;
1714                    }
1715                    else if(f.exists() && Integer.parseInt(size) > 0)
1716                    {
1717                        if(!Settings.noUploadResumingQuestion) {
1718                            if(JOptionPane.showConfirmDialog(new JLabel JavaDoc(), "A file smaller than the one to be uploaded already exists on the server,\n do you want to resume the upload?", "Resume upload?", JOptionPane.YES_NO_OPTION)
1719                                    != JOptionPane.OK_OPTION) {
1720                                resume = false;
1721                            }
1722                        }
1723                        Log.out("resume: " + resume + ", size: " + size);
1724                    }
1725                    else {
1726                        Log.out("resume: " + resume + ", size: " + size);
1727                    }
1728                }
1729            }
1730
1731            modeStream();
1732
1733            //binary();
1734
p = negotiatePort();
1735
1736            if(resume && Settings.enableUploadResuming)
1737            {
1738                jcon.send(REST + " " + size);
1739
1740                if(getLine(PROCEED) == null)
1741                {
1742                    resume = false;
1743                }
1744            }
1745
1746            dcon = new DataConnection(this, p, host, path, dataType, resume,
1747                                      Integer.parseInt(size), in); //, new Updater());
1748

1749            while(!dcon.isThere())
1750            {
1751                pause(10);
1752            }
1753
1754            //System.out.println(path + " : " + file);
1755
if(realName != null)
1756            {
1757                jcon.send(STOR + " " + realName);
1758            }
1759            else
1760            {
1761                jcon.send(STOR + " " + file);
1762            }
1763
1764            String JavaDoc tmp = getLine(POSITIVE);
1765
1766            if(!tmp.startsWith(POSITIVE) && !tmp.startsWith(PROCEED))
1767            {
1768                return TRANSFER_FAILED;
1769            }
1770
1771            Log.debug(tmp);
1772
1773            // we need to block since some ftp-servers do not want the
1774
// refresh command that dirpanel sends otherwise
1775
while(!dcon.finished)
1776            {
1777                pause(10);
1778            }
1779        }
1780        catch(Exception JavaDoc ex)
1781        {
1782            ex.printStackTrace();
1783            Log.debug(ex.toString() + " @FtpConnection::upload");
1784
1785            return TRANSFER_FAILED;
1786        }
1787
1788        return TRANSFER_SUCCESSFUL;
1789    }
1790
1791    private int uploadDir(String JavaDoc dir)
1792    {
1793        //System.out.println("up");
1794
if(dir.endsWith("\\"))
1795        {
1796            System.out.println("Something's wrong with the selected directory - please report this bug!");
1797        }
1798
1799        if(!dir.endsWith("/"))
1800        {
1801            dir = dir + "/";
1802        }
1803
1804        if(StringUtils.isRelative(dir))
1805        {
1806            dir = getLocalPath() + dir;
1807        }
1808
1809        String JavaDoc single = StringUtils.getDir(dir);
1810        String JavaDoc path = dir.substring(0, dir.indexOf(single));
1811
1812        String JavaDoc remoteDir = getCachedPWD() + single; //StringUtils.removeStart(dir,path);
1813
String JavaDoc oldDir = getCachedPWD();
1814
1815        if(Settings.safeMode)
1816        {
1817            noop();
1818        }
1819
1820        boolean successful = mkdir(remoteDir);
1821
1822        if(!successful)
1823        {
1824            return MKDIR_FAILED;
1825        }
1826
1827        if(Settings.safeMode)
1828        {
1829            noop();
1830        }
1831
1832        chdirNoRefresh(remoteDir);
1833
1834        File JavaDoc f2 = new File JavaDoc(dir);
1835        String JavaDoc[] tmp = f2.list();
1836
1837        for(int i = 0; i < tmp.length; i++)
1838        {
1839            String JavaDoc res = dir + tmp[i];
1840            File JavaDoc f3 = new File JavaDoc(res);
1841
1842            if(f3.isDirectory())
1843            {
1844                if(!work)
1845                {
1846                    return TRANSFER_STOPPED;
1847                }
1848
1849                uploadDir(res);
1850            }
1851            else
1852            {
1853                //System.out.println(">>>\nlp: "+path+single + "\nrp: ");
1854
//System.out.println(remoteDir +"\nres: "+res);
1855
if(!work)
1856                {
1857                    return TRANSFER_STOPPED;
1858                }
1859
1860                fileCount++;
1861
1862                if(rawUpload(res) < 0)
1863                {
1864                    ; //return TRANSFER_STOPPED;
1865
}
1866            }
1867        }
1868
1869        chdirNoRefresh(oldDir);
1870
1871        return TRANSFER_SUCCESSFUL;
1872    }
1873
1874    private String JavaDoc parse(String JavaDoc file)
1875    {
1876        file = parseSymlink(file);
1877
1878        return file;
1879    }
1880
1881    /** recursive delete remote directory */
1882    private int cleanDir(String JavaDoc dir, String JavaDoc path)
1883    {
1884        if(dir.equals(""))
1885        {
1886            return 0;
1887        }
1888
1889        if(!dir.endsWith("/"))
1890        {
1891            dir = dir + "/";
1892        }
1893
1894        String JavaDoc remoteDir = StringUtils.removeStart(dir, path);
1895
1896        String JavaDoc oldDir = pwd;
1897        chdirNoRefresh(pwd + remoteDir);
1898
1899        try
1900        {
1901            list();
1902        }
1903        catch(IOException JavaDoc ex)
1904        {
1905            // probably we don't have permission to ls here
1906
return PERMISSION_DENIED;
1907        }
1908
1909        String JavaDoc[] tmp = sortLs();
1910        chdirNoRefresh(oldDir);
1911
1912        if(tmp == null)
1913        {
1914            return GENERIC_FAILED;
1915        }
1916
1917        for(int i = 0; i < tmp.length; i++)
1918        {
1919            Log.out("cleanDir: " + tmp);
1920
1921            if(isSymlink(tmp[i]))
1922            {
1923                Log.debug("WARNING: Skipping symlink, remove failed.");
1924                Log.debug("This is necessary to prevent possible data loss when removing those symlinks.");
1925
1926                tmp[i] = null;
1927            }
1928
1929            if(tmp[i] != null)
1930            {
1931                tmp[i] = parseSymlink(tmp[i]);
1932            }
1933
1934            if((tmp[i] == null) || tmp[i].equals("./") || tmp[i].equals("../"))
1935            {
1936                //System.out.println(tmp[i]+"\n\n\n");
1937
continue;
1938            }
1939
1940            //System.out.println(tmp[i]);
1941
//pause(500);
1942
if(tmp[i].endsWith("/"))
1943            {
1944                // System.out.println(dir);
1945
cleanDir(dir + tmp[i], path);
1946
1947                int x = removeFileOrDir(dir + tmp[i]);
1948
1949                if(x < 0)
1950                {
1951                    return x;
1952                }
1953            }
1954            else
1955            {
1956                // System.out.println(dir+tmp[i]);
1957
int x = removeFileOrDir(dir + tmp[i]);
1958
1959                if(x < 0)
1960                {
1961                    return x;
1962                }
1963            }
1964        }
1965
1966        return REMOVE_SUCCESSFUL;
1967    }
1968
1969    /**
1970    * Remove a remote file or directory.
1971    *
1972    * @param file The file to remove
1973    * @return REMOVE_SUCCESSFUL, REMOVE_FAILED, PERMISSION_DENIED or GENERIC_FAILED
1974    */

1975    public int removeFileOrDir(String JavaDoc file)
1976    {
1977        if(file == null)
1978        {
1979            return 0;
1980        }
1981
1982        if(file.trim().equals(".") || file.trim().equals(".."))
1983        {
1984            Log.debug("ERROR: Catching attempt to delete . or .. directories");
1985
1986            return GENERIC_FAILED;
1987        }
1988
1989        if(isSymlink(file))
1990        {
1991            Log.debug("WARNING: Skipping symlink, remove failed.");
1992            Log.debug("This is necessary to prevent possible data loss when removing those symlinks.");
1993
1994            return REMOVE_FAILED;
1995        }
1996
1997        file = parseSymlink(file);
1998
1999        if(file.endsWith("/"))
2000        {
2001            int ret = cleanDir(file, getCachedPWD());
2002
2003            if(ret < 0)
2004            {
2005                return ret;
2006            }
2007
2008            jcon.send(RMD + " " + file);
2009        }
2010        else
2011        {
2012            jcon.send(DELE + " " + file);
2013        }
2014
2015        if(success(POSITIVE))//FTP250_COMPLETED))
2016
{
2017            return REMOVE_SUCCESSFUL;
2018        }
2019        else
2020        {
2021            return REMOVE_FAILED;
2022        }
2023    }
2024
2025    /**
2026    * Disconnect from the server.
2027    * The connection is marked ad closed even if the server does not respond correctly -
2028    * if it fails for any reason the connection should just time out
2029    *
2030    */

2031    public void disconnect()
2032    {
2033        jcon.send(QUIT);
2034        getLine(POSITIVE);//FTP221_SERVICE_CLOSING);
2035
connected = false;
2036    }
2037
2038    /**
2039    * Execute a remote command.
2040    * Sends noops before and after the command
2041    *
2042    * @param cmd The raw command that is to be sent to the server
2043    */

2044    public void sendRawCommand(String JavaDoc cmd)
2045    {
2046        noop();
2047        Log.clearCache();
2048        jcon.send(cmd);
2049        noop();
2050    }
2051
2052    /**
2053    * Reads the response until line found or error.
2054    * (Used internally)
2055    *
2056    * @param until The String the response line hast to start with, 2 for succesful return codes for example
2057    */

2058    public String JavaDoc getLine(String JavaDoc until)
2059    {
2060        return getLine(new String JavaDoc[] { until });
2061    }
2062
2063    /**
2064    * Reads the response until line found or error.
2065    * (Used internally)
2066    */

2067    public String JavaDoc getLine(String JavaDoc[] until)
2068    {
2069        BufferedReader JavaDoc in = null;
2070
2071        try
2072        {
2073            in = jcon.getReader();
2074        }
2075        catch(Exception JavaDoc ex)
2076        {
2077            Log.debug(ex.toString() + " @FtpConnection::getLine");
2078        }
2079
2080        //String resultString = null;
2081
String JavaDoc tmp;
2082
2083        while(true)
2084        {
2085            try
2086            {
2087                tmp = in.readLine();
2088
2089                if(tmp == null)
2090                {
2091                    break;
2092                }
2093
2094                Log.debug(tmp);
2095
2096                if(((tmp.startsWith(NEGATIVE) || (tmp.startsWith(NEGATIVE2))) &&
2097                       (tmp.charAt(3) != MORE_LINES_APPENDED)) ||
2098                       tmp.startsWith(PROCEED))
2099                {
2100                    return tmp;
2101                }
2102                else
2103                {
2104                    for(int i = 0; i < until.length; i++)
2105                    {
2106                        if(tmp.startsWith(until[i]))
2107                        {
2108                            //if(resultString == null) resultString = tmp;
2109
//else resultString = resultString + "\n" + tmp;
2110
if(tmp.charAt(3) != MORE_LINES_APPENDED)
2111                            {
2112                                return tmp;
2113                            }
2114                        }
2115                    }
2116                }
2117            }
2118            catch(Exception JavaDoc ex)
2119            {
2120                Log.debug(ex.toString() + " @FtpConnection::getLine");
2121
2122                break;
2123            }
2124        }
2125
2126        return null;
2127    }
2128
2129    /**
2130    * Check if login() was successful.
2131    *
2132    * @return True if connected, false otherwise
2133    */

2134    public boolean isConnected()
2135    {
2136        return connected;
2137    }
2138
2139    /**
2140    * Get the current remote directory.
2141    *
2142    * @return The server's CWD
2143    */

2144    public String JavaDoc getPWD()
2145    {
2146        if(connected)
2147        {
2148            updatePWD();
2149        }
2150
2151        if(TESTMODE)
2152        {
2153            return "HUGO.user.";
2154        }
2155
2156        return pwd;
2157    }
2158
2159    /**
2160    * Returns current remote directory (cached)
2161    *
2162    * @return The cached CWD
2163    */

2164    public String JavaDoc getCachedPWD()
2165    {
2166        return pwd;
2167    }
2168
2169    /**
2170    * updates PWD
2171    */

2172    private void updatePWD()
2173    {
2174        jcon.send(PWD);
2175
2176        String JavaDoc tmp = getLine(POSITIVE);//FTP257_PATH_CREATED);
2177

2178        if(tmp == null)
2179        {
2180            return;
2181        }
2182
2183        if(TESTMODE)
2184        {
2185            tmp = "\"'T759F.'\"";
2186        }
2187              
2188        String JavaDoc x1 = tmp;
2189        
2190        if(x1.indexOf("\"") >= 0) {
2191            x1 = tmp.substring(tmp.indexOf("\"") + 1);
2192            x1 = x1.substring(0, x1.indexOf("\""));
2193        }
2194
2195        if(getOsType().indexOf("MVS") >= 0)
2196        {
2197            //if(x1.indexOf("'") == 0) {
2198
// String x2 = x1.substring(1, x1.lastIndexOf("'"));
2199
// x1 = x2;
2200
//}
2201
Log.out("pwd: " + x1);
2202        }
2203        else if(!x1.endsWith("/"))
2204        {
2205            x1 = x1 + "/";
2206        }
2207
2208        pwd = x1;
2209    }
2210
2211    /**
2212    * Change directory unparsed.
2213    * Use chdir instead if you do not parse the dir correctly...
2214    *
2215    * @param dirName The raw directory name
2216    * @return True if successful, false otherwise
2217    */

2218    public boolean chdirRaw(String JavaDoc dirName)
2219    {
2220        jcon.send(CWD + " " + dirName);
2221
2222        return success(POSITIVE);//FTP250_COMPLETED);
2223
}
2224
2225    private boolean success(String JavaDoc op)
2226    {
2227        String JavaDoc tmp = getLine(op);
2228
2229        if((tmp != null) && tmp.startsWith(op))
2230        {
2231            return true;
2232        }
2233        else
2234        {
2235            return false;
2236        }
2237    }
2238
2239    /**
2240     * Change to the parent of the current working directory.
2241     * The CDUP command is a special case of CWD, and is included
2242     * to simplify the implementation of programs for transferring
2243     * directory trees between operating systems having different
2244     * syntaxes for naming the parent directory.
2245     *
2246     * @return True if successful, false otherwise
2247     */

2248    public boolean cdup()
2249    {
2250        jcon.send(CDUP);
2251
2252        return success(POSITIVE);//FTP200_OK);
2253
}
2254
2255    /**
2256    * Create a directory with the given name.
2257    *
2258    * @param dirName The name of the directory to create
2259    * @return True if successful, false otherwise
2260    */

2261    public boolean mkdir(String JavaDoc dirName)
2262    {
2263        jcon.send(MKD + " " + dirName);
2264
2265        boolean ret = success(POSITIVE); // Filezille server bugfix, was: FTP257_PATH_CREATED);
2266
Log.out("mkdir(" + dirName + ") returned: " + ret);
2267
2268        //*** Added 03/20/2005
2269
fireDirectoryUpdate(this);
2270
2271        //***
2272
return ret;
2273    }
2274
2275    private int negotiatePort() throws IOException JavaDoc
2276    {
2277        String JavaDoc tmp = "";
2278
2279        if(Settings.getFtpPasvMode())
2280        {
2281            jcon.send(PASV);
2282
2283            tmp = getLine(FTP227_ENTERING_PASSIVE_MODE);
2284
2285            if((tmp != null) && !tmp.startsWith(NEGATIVE))
2286            {
2287                return getPasvPort(tmp);
2288            }
2289        }
2290
2291        tmp = getActivePortCmd();
2292        jcon.send(tmp);
2293        getLine(FTP200_OK);
2294
2295        return getActivePort();
2296    }
2297
2298    /**
2299    * List remote directory.
2300    * Note that you have to get the output using the
2301    * sort*-methods.
2302    *
2303    * @param outfile The file to save the output to, usually Settings.ls_out
2304    */

2305    public void list() throws IOException JavaDoc
2306    {
2307        String JavaDoc oldType = "";
2308
2309        try
2310        {
2311            BufferedReader JavaDoc in = jcon.getReader();
2312
2313            int p = 0;
2314
2315            modeStream();
2316
2317            oldType = getTypeNow();
2318            ascii();
2319
2320            p = negotiatePort();
2321            dcon = new DataConnection(this, p, host, null, DataConnection.GET, false, true); //,null);
2322

2323            //System.out.println("2...");
2324
while(dcon.getInputStream() == null)
2325            {
2326                //System.out.print("#");
2327
pause(10);
2328            }
2329
2330            DataInputStream JavaDoc input = new DataInputStream JavaDoc(dcon.getInputStream());
2331            
2332            jcon.send(LIST);
2333            getLine(POSITIVE); //FTP226_CLOSING_DATA_REQUEST_SUCCESSFUL);
2334

2335            String JavaDoc line;
2336            currentListing.removeAllElements();
2337            
2338            while((line = input.readLine()) != null) {
2339                //System.out.println("-> "+line);
2340
if(!line.trim().equals("")) {
2341                    currentListing.add(line);
2342                }
2343            }
2344            
2345            input.close();
2346
2347            //System.out.println("4...");
2348
if(!oldType.equals(ASCII))
2349            {
2350                type(oldType);
2351            }
2352        }
2353        catch(Exception JavaDoc ex)
2354        {
2355            Log.debug("Cannot list remote directory!");
2356
2357            if(!oldType.equals(ASCII))
2358            {
2359                type(oldType);
2360            }
2361
2362            ex.printStackTrace();
2363            throw new IOException JavaDoc(ex.getMessage());
2364        }
2365    }
2366
2367    /**
2368    * Parses directory and does a chdir().
2369    * Does also fire a directory update event.
2370    *
2371    * @return True is successful, false otherwise
2372    */

2373    public boolean chdir(String JavaDoc p)
2374    {
2375    //Log.out("Change directory to: "+p);
2376
String JavaDoc tmpPath = p;
2377
2378        boolean tmp = chdirWork(p);
2379
2380        if(!tmp)
2381        {
2382            return false;
2383        }
2384        else
2385        {
2386            fireDirectoryUpdate(this);
2387
2388            return true;
2389        }
2390    }
2391
2392    /**
2393    * Parses directory and does a chdir(), but does not send an update signal
2394    *
2395    * @return True is successful, false otherwise
2396    */

2397    public boolean chdirNoRefresh(String JavaDoc p)
2398    {
2399        return chdirWork(p);
2400    }
2401
2402    private boolean chdirWork(String JavaDoc p)
2403    {
2404        if(Settings.safeMode)
2405        {
2406            noop();
2407        }
2408
2409        p = parseSymlinkBack(p);
2410
2411        if(getOsType().indexOf("OS/2") >= 0)
2412        {
2413            return chdirRaw(p);
2414        }
2415        else if(getOsType().indexOf("MVS") >= 0)
2416        {
2417        boolean cdup = false;
2418
2419        System.out.print("MVS parser: "+p+" -> ");
2420
2421        //TODO: handle relative unix paths
2422
if(!getPWD().startsWith("/")) //return chdirRaw(p);
2423
{
2424         if(p.endsWith("..")) {
2425        cdup = true;
2426         }
2427         //TODO let dirlister form correct syntax
2428

2429             p = p.replaceAll("/", "");
2430         boolean ew = p.startsWith("'");
2431         String JavaDoc tmp = null;
2432
2433         if(p.startsWith("'") && !p.endsWith("'"))
2434         {
2435        if(cdup){
2436            p = p.substring(0,p.length()-4);
2437            if(p.indexOf(".") > 0) {
2438                p = p.substring(0,p.lastIndexOf("."));
2439            }
2440            p += "'";
2441            }
2442
2443        tmp = p.substring(0, p.lastIndexOf("'"));
2444        p = p.substring(p.lastIndexOf("'")+1);
2445        ew = false;
2446         }
2447         else if(cdup){
2448        p = p.substring(0,p.length()-3);
2449        if(p.indexOf(".") > 0) {
2450            p = p.substring(0,p.lastIndexOf("."));
2451        }
2452         }
2453
2454             if(p.indexOf(".") > 0 && !ew)
2455             {
2456            p = p.substring(0, p.indexOf("."));
2457             }
2458
2459         if(tmp != null) p = tmp+p+"'";
2460
2461             System.out.println(p);
2462             Log.out("MVS parser: " + p);
2463
2464             return chdirRaw(p);
2465            }
2466        }
2467
2468        try
2469        {
2470            // check if we don't have a relative path
2471
if(!p.startsWith("/") && !p.startsWith("~"))
2472            {
2473                p = pwd + p;
2474            }
2475
2476            // argh, we should document that!
2477
if(p.endsWith(".."))
2478            {
2479                boolean home = p.startsWith("~");
2480                StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(p, "/");
2481
2482                //System.out.println("path p :"+p +" Tokens: "+stok.countTokens());
2483
if(stok.countTokens() > 2)
2484                {
2485                    String JavaDoc pold1 = "";
2486                    String JavaDoc pold2 = "";
2487                    String JavaDoc pnew = "";
2488
2489                    while(stok.hasMoreTokens())
2490                    {
2491                        pold1 = pold2;
2492                        pold2 = pnew;
2493                        pnew = pnew + "/" + stok.nextToken();
2494                    }
2495
2496                    p = pold1;
2497                }
2498                else
2499                {
2500                    p = "/";
2501                }
2502
2503                if(home)
2504                {
2505                    p = p.substring(1);
2506                }
2507            }
2508
2509            //System.out.println("path: "+p);
2510
if(!chdirRaw(p))
2511            {
2512                return false;
2513            }
2514        }
2515        catch(Exception JavaDoc ex)
2516        {
2517            Log.debug("(remote) Can not get pathname! " + pwd + ":" + p);
2518            ex.printStackTrace();
2519
2520            return false;
2521        }
2522
2523        //fireDirectoryUpdate(this);
2524

2525    // --------------------------------------
2526
updatePWD();
2527
2528
2529        return true;
2530    }
2531
2532    /**
2533    * Waits a specified amount of time
2534    *
2535    * @param time The time to sleep in milliseconds
2536    */

2537    public void pause(int time)
2538    {
2539        try
2540        {
2541            Thread.sleep(time);
2542        }
2543        catch(Exception JavaDoc ex)
2544        {
2545            ex.printStackTrace();
2546        }
2547    }
2548
2549    /**
2550    * Return the local working directory
2551    *
2552    * @return The local CWD
2553    */

2554    public String JavaDoc getLocalPath()
2555    {
2556        return localPath;
2557    }
2558
2559    /**
2560    * Set the local working directory
2561    *
2562    * @param newPath The new local CWD
2563    * @return Always true in the current implementation
2564    */

2565    public boolean setLocalPath(String JavaDoc newPath)
2566    {
2567        localPath = newPath;
2568
2569        if(!localPath.endsWith("/"))
2570        {
2571            localPath = localPath + "/";
2572        }
2573
2574        return true;
2575    }
2576
2577    /**
2578    * Checks wheter a file exists.
2579    *
2580    * @param file the name of the file
2581    * @return An int-code: CHDIR_FAILED, PERMISSION_DENIED (no listing allowed), R, W or DENIED
2582    */

2583    public int exists(String JavaDoc file)
2584    {
2585        String JavaDoc dir = null;
2586        String JavaDoc tmpPWD = getCachedPWD();
2587
2588        if(file.indexOf("/") >= 0)
2589        {
2590            dir = file.substring(0, file.lastIndexOf("/") + 1);
2591            Log.out("checking dir: " + dir);
2592
2593            if(!chdir(dir))
2594            {
2595                return CHDIR_FAILED;
2596            }
2597        }
2598
2599        try
2600        {
2601            list();
2602        }
2603        catch(IOException JavaDoc ex)
2604        {
2605            ex.printStackTrace();
2606
2607            return PERMISSION_DENIED;
2608        }
2609
2610        String JavaDoc f = file.substring(file.lastIndexOf("/") + 1);
2611        Log.out("checking file: " + f);
2612
2613        String JavaDoc[] files = sortLs();
2614        int[] perms = getPermissions();
2615
2616        int y = -1;
2617
2618        for(int x = 0; x < files.length; x++)
2619        {
2620            if(files[x].equals(f))
2621            {
2622                y = x;
2623
2624                break;
2625            }
2626        }
2627
2628        if(y == -1)
2629        {
2630            return FILE_NOT_FOUND;
2631        }
2632
2633        if(dir != null)
2634        {
2635            chdir(tmpPWD);
2636        }
2637
2638        return perms[y];
2639    }
2640
2641    /** Moves or renames remote file.
2642     * @param from remote file to move or rename.
2643     * @param to new file name.
2644     * @return <code>true</code> if completed successfully; <code>false</code> otherwise.
2645     */

2646    public boolean rename(String JavaDoc from, String JavaDoc to)
2647    {
2648        jcon.send("RNFR " + from);
2649
2650        if(success(RC350))
2651        {
2652            jcon.send("RNTO " + to);
2653
2654            if(success(POSITIVE))//FTP250_COMPLETED))
2655
{
2656                return true;
2657            }
2658        }
2659
2660        return false;
2661    }
2662
2663    /**
2664    * Get the port.
2665    *
2666    * @return The port used by the FTP control connection
2667    */

2668    public int getPort()
2669    {
2670        return port;
2671    }
2672
2673    private int getPortA()
2674    {
2675        return porta;
2676    }
2677
2678    private int getPortB()
2679    {
2680        return portb;
2681    }
2682
2683    private void incrementPort()
2684    {
2685        portb++;
2686    }
2687
2688    /*
2689    private String getActivePortCmd() throws UnknownHostException, IOException
2690    {
2691        InetAddress ipaddr = jcon.getLocalAddress();
2692        String ip = ipaddr.getHostAddress().replace('.', ',');
2693
2694        incrementPort();
2695
2696        int a = getPortA();
2697        int b = getPortB();
2698        String ret = "PORT " + ip + "," + a + "," + b;
2699
2700        //System.out.println(ret);
2701        return ret;
2702    }
2703*/

2704    
2705    private String JavaDoc getActivePortCmd() throws UnknownHostException JavaDoc, IOException JavaDoc
2706    {
2707    InetAddress JavaDoc ipaddr = jcon.getLocalAddress();
2708    String JavaDoc ip = ipaddr.getHostAddress().replace('.', ',');
2709     
2710    ServerSocket JavaDoc aSock = new ServerSocket JavaDoc(0);
2711    int availPort = aSock.getLocalPort();
2712    aSock.close();
2713    porta = availPort/256;
2714    portb = availPort%256;
2715    String JavaDoc ret = "PORT " + ip + "," + porta + "," + portb;
2716     
2717// System.out.println(ret);
2718
return ret;
2719    }
2720    
2721    /**
2722     * Tell server we want binary data connections.
2723     */

2724    public void binary()
2725    { // possible responses 200, 500, 501, 504, 421 and 530
2726
type(BINARY);
2727    }
2728
2729    /**
2730     * Tell server we want ascii data connections.
2731     */

2732    public void ascii()
2733    {
2734        type(ASCII);
2735    }
2736
2737    /**
2738    * Set type (L8,I,A for example).
2739    *
2740    * @return True if the type was changed successfully, false otherwise
2741    */

2742    public boolean type(String JavaDoc code)
2743    {
2744        jcon.send(TYPE + " " + code);
2745
2746        String JavaDoc tmp = getLine(POSITIVE);//FTP200_OK);
2747

2748        if((tmp != null) && tmp.startsWith(POSITIVE))//FTP200_OK))
2749
{
2750            typeNow = code;
2751
2752            return true;
2753        }
2754
2755        return false;
2756    }
2757
2758    /**
2759    * Returns the type used.
2760    *
2761    * @return The type String, I, A, L8 for example
2762    */

2763    public String JavaDoc getTypeNow()
2764    {
2765        return typeNow;
2766    }
2767
2768    /**
2769     * Do nothing, but flush buffers
2770     */

2771    public void noop()
2772    {
2773        jcon.send(NOOP);
2774        getLine(POSITIVE);//FTP200_OK);
2775
}
2776
2777    /**
2778     * Try to abort the transfer.
2779     */

2780    public void abort()
2781    {
2782        jcon.send(ABOR);
2783        getLine(POSITIVE); // 226
2784
}
2785
2786    /**
2787     * This command is used to find out the type of operating
2788     * system at the server. The reply shall have as its first
2789     * word one of the system names listed in the current version
2790     * of the Assigned Numbers document (RFC 943).
2791     *
2792     * @return The server response of the SYST command
2793     */

2794    public String JavaDoc system()
2795    { // possible responses 215, 500, 501, 502, and 421
2796
jcon.send(SYST);
2797
2798        String JavaDoc response = getLine(POSITIVE);//FTP215_SYSTEM_TYPE);
2799

2800        if(response != null)
2801        {
2802            //StringTokenizer st = new StringTokenizer(response);
2803
//if (st.countTokens() >= 2)
2804
//{
2805
// st.nextToken();
2806
// String os = st.nextToken();
2807
// setOsType(os);
2808
//}
2809
setOsType(response);
2810        }
2811        else
2812        {
2813            setOsType("UNIX");
2814        }
2815
2816        return response;
2817    }
2818
2819    /**
2820     * Set mode to Stream.
2821     * Used internally.
2822     */

2823    public void modeStream()
2824    {
2825        if(useStream && !modeStreamSet)
2826        {
2827            String JavaDoc ret = mode(STREAM);
2828
2829            if((ret != null) && ret.startsWith(NEGATIVE))
2830            {
2831                useStream = false;
2832            }
2833            else
2834            {
2835                modeStreamSet = true;
2836            }
2837        }
2838    }
2839
2840    /**
2841     * Unsupported at this time.
2842     */

2843    public void modeBlocked()
2844    {
2845        if(useBlocked)
2846        {
2847            if(mode(BLOCKED).startsWith(NEGATIVE))
2848            {
2849                useBlocked = false;
2850            }
2851        }
2852    }
2853
2854    /*
2855     * Unsupported at this time.
2856     */

2857    public void modeCompressed()
2858    {
2859        if(useCompressed)
2860        {
2861            if(mode(COMPRESSED).startsWith(NEGATIVE))
2862            {
2863                useCompressed = false;
2864            }
2865        }
2866    }
2867
2868    /**
2869    * Set mode manually.
2870    *
2871    * @param code The mode code wanted, I, A, L8 for example
2872    * @return The server's response to the request
2873    */

2874    public String JavaDoc mode(String JavaDoc code)
2875    {
2876        jcon.send(MODE + " " + code);
2877
2878        String JavaDoc ret = "";
2879
2880        try
2881        {
2882            ret = getLine(POSITIVE);//FTP200_OK);
2883
}
2884        catch(Exception JavaDoc ex)
2885        {
2886            ex.printStackTrace();
2887        }
2888
2889        return ret;
2890    }
2891
2892    /**
2893    * Return the host used.
2894    *
2895    * @return The remote host of this connection
2896    */

2897    public String JavaDoc getHost()
2898    {
2899        return host;
2900    }
2901
2902    /**
2903    * Return the username.
2904    *
2905    * @return The username used by this connection
2906    */

2907    public String JavaDoc getUsername()
2908    {
2909        return username;
2910    }
2911
2912    /**
2913    * Return the password.
2914    *
2915    * @return The password used by this connection
2916    */

2917    public String JavaDoc getPassword()
2918    {
2919        return password;
2920    }
2921
2922    /**
2923    * Return the DataConnection.
2924    * Should be necessary only for complex actions.
2925    *
2926    * @return The DataConnection object currently used by this conenction
2927    */

2928    public DataConnection getDataConnection()
2929    {
2930        return dcon;
2931    }
2932
2933    /**
2934    * Add a ConnectionListener.
2935    * The Listener is notified about transfers and the connection state.
2936    * @param l A ConnectionListener object
2937    */

2938    public void addConnectionListener(ConnectionListener l)
2939    {
2940        listeners.add(l);
2941    }
2942
2943    /**
2944    * Add a Vector of ConnectionListeners.
2945    * Each Listener is notified about transfers and the connection state.
2946    *
2947    * @param l A Vector containig ConnectionListener objects
2948    */

2949    public void setConnectionListeners(Vector JavaDoc l)
2950    {
2951        listeners = l;
2952    }
2953
2954    /**
2955    * Remote directory has changed.
2956    *
2957    * @param con The FtpConnection calling the event
2958    */

2959    public void fireDirectoryUpdate(FtpConnection con)
2960    {
2961        if(listeners == null)
2962        {
2963            return;
2964        }
2965        else
2966        {
2967            for(int i = 0; i < listeners.size(); i++)
2968            {
2969                ((ConnectionListener) listeners.elementAt(i)).updateRemoteDirectory(con);
2970            }
2971        }
2972    }
2973
2974    /**
2975    * Progress update.
2976    * The transfer is active and makes progress, so a signal is send
2977    * each few kb.
2978    *
2979    * @param file The file transferred
2980    * @param type the type of event, DataConnection.GETDIR for example
2981    * @param bytes The number of bytes transferred so far
2982    */

2983    public void fireProgressUpdate(String JavaDoc file, String JavaDoc type, int bytes)
2984    {
2985        //System.out.println(listener);
2986
if(listeners == null)
2987        {
2988            return;
2989        }
2990        else
2991        {
2992            for(int i = 0; i < listeners.size(); i++)
2993            {
2994                ConnectionListener listener = (ConnectionListener) listeners.elementAt(i);
2995
2996                if(shortProgress && Settings.shortProgress)
2997                {
2998                    if(type.startsWith(DataConnection.DFINISHED))
2999                    {
3000                        listener.updateProgress(baseFile,
3001                                                DataConnection.DFINISHED + ":" +
3002                                                fileCount, bytes);
3003                    }
3004                    else if(isDirUpload)
3005                    {
3006                        listener.updateProgress(baseFile,
3007                                                DataConnection.PUTDIR + ":" +
3008                                                fileCount, bytes);
3009                    }
3010                    else
3011                    {
3012                        listener.updateProgress(baseFile,
3013                                                DataConnection.GETDIR + ":" +
3014                                                fileCount, bytes);
3015                    }
3016                }
3017                else
3018                {
3019                    listener.updateProgress(file, type, bytes);
3020                }
3021            }
3022        }
3023    }
3024
3025    /**
3026    * Connection is there and user logged in
3027    *
3028    * @param con The FtpConnection calling the event
3029    */

3030    public void fireConnectionInitialized(FtpConnection con)
3031    {
3032        if(listeners == null)
3033        {
3034            return;
3035        }
3036        else
3037        {
3038            for(int i = 0; i < listeners.size(); i++)
3039            {
3040                ((ConnectionListener) listeners.elementAt(i)).connectionInitialized(con);
3041            }
3042        }
3043    }
3044
3045    /**
3046    * We are not logged in for some reason
3047    *
3048    * @param con The FtpConnection calling the event
3049    * @param why The login() response code
3050    */

3051    public void fireConnectionFailed(FtpConnection con, String JavaDoc why)
3052    {
3053        if(listeners == null)
3054        {
3055            return;
3056        }
3057        else
3058        {
3059            for(int i = 0; i < listeners.size(); i++)
3060            {
3061                ((ConnectionListener) listeners.elementAt(i)).connectionFailed(con,
3062                                                                               why);
3063            }
3064        }
3065    }
3066
3067    /**
3068    * Transfer is done
3069    *
3070    * @param con The FtpConnection calling the event
3071    */

3072    public void fireActionFinished(FtpConnection con)
3073    {
3074        if(listeners == null)
3075        {
3076            return;
3077        }
3078        else
3079        {
3080            for(int i = 0; i < listeners.size(); i++)
3081            {
3082                ((ConnectionListener) listeners.elementAt(i)).actionFinished(con);
3083            }
3084        }
3085    }
3086
3087    /**
3088    * Return the ConnectionHandler.
3089    *
3090    * @return The connection handler of this instance
3091    */

3092    public ConnectionHandler getConnectionHandler()
3093    {
3094        return handler;
3095    }
3096
3097    /**
3098    * Set the ConnectionHandler.
3099    *
3100    * @param h The connection handler that is to be used by this connection
3101    */

3102    public void setConnectionHandler(ConnectionHandler h)
3103    {
3104        handler = h;
3105    }
3106
3107    /**
3108    * Get the last FtpTransfer object spawned.
3109    *
3110    */

3111    public FtpTransfer getLastInitiatedTransfer()
3112    {
3113        return lastTransfer;
3114    }
3115
3116    /**
3117    * Abort the last spawned transfer.
3118    *
3119    */

3120    public void abortTransfer()
3121    {
3122        try
3123        {
3124            DataConnection dcon = lastTransfer.getDataConnection();
3125
3126            if(dcon == null)
3127            {
3128                Log.out("nothing to abort");
3129
3130                return;
3131            }
3132
3133            dcon.getCon().work = false;
3134            dcon.sock.close();
3135        }
3136        catch(Exception JavaDoc ex)
3137        {
3138            Log.debug("Exception during abort: " + ex.toString());
3139            ex.printStackTrace();
3140        }
3141    }
3142
3143    public Date JavaDoc[] sortDates()
3144    {
3145        if(dateVector.size() > 0)
3146        {
3147            return (Date JavaDoc[]) dateVector.toArray();
3148        }
3149        else
3150        {
3151            return null;
3152        }
3153    }
3154
3155    public String JavaDoc getCRLF() {
3156    return crlf;
3157    }
3158
3159    public BufferedReader JavaDoc getIn() {
3160        return in;
3161    }
3162
3163    public void setIn(BufferedReader JavaDoc in) {
3164        this.in = in;
3165    }
3166
3167    public BufferedReader JavaDoc getCommandInputReader() {
3168        return jcon.getIn();
3169    }
3170    
3171    public OutputStream JavaDoc getCommandOutputStream() {
3172        return jcon.getOut();
3173    }
3174    
3175}
3176
Popular Tags