Source Code Cross Referenced for FtpConnection.java in  » Net » j-ftp » net » sf » jftp » net » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » j ftp » net.sf.jftp.net 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * This program is free software; you can redistribute it and/or
0003:         * modify it under the terms of the GNU General Public License
0004:         * as published by the Free Software Foundation; either version 2
0005:         * of the License, or (at your option) any later version.
0006:         *
0007:         * This program is distributed in the hope that it will be useful,
0008:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0009:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0010:         * GNU General Public License for more details.
0011:         *
0012:         * You should have received a copy of the GNU General Public License
0013:         * along with this program; if not, write to the Free Software
0014:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
0015:         */
0016:        package net.sf.jftp.net;
0017:
0018:        //***now all config files are imported
0019:        import java.io.BufferedReader;
0020:        import java.io.DataInputStream;
0021:        import java.io.File;
0022:        import java.io.IOException;
0023:        import java.io.InputStream;
0024:        import java.io.OutputStream;
0025:        import java.net.InetAddress;
0026:        import java.net.ServerSocket;
0027:        import java.net.UnknownHostException;
0028:        import java.util.Date;
0029:        import java.util.StringTokenizer;
0030:        import java.util.Vector;
0031:
0032:        import javax.swing.JLabel;
0033:        import javax.swing.JOptionPane;
0034:
0035:        import net.sf.jftp.config.LoadSet;
0036:        import net.sf.jftp.config.SaveSet;
0037:        import net.sf.jftp.config.Settings;
0038:        import net.sf.jftp.system.StringUtils;
0039:        import net.sf.jftp.system.logging.Log;
0040:
0041:        /**
0042:         * All control transactions are made here.
0043:         * See doc/FtpDownload.java for examples and note
0044:         * that this class is event-driven and not Exception-based!
0045:         * You might want to take a look at ConnectionListener, too.
0046:         *
0047:         * @author  David Hansmann, hansmann.d@debitel.net
0048:         * @version 1.30+, June 2003
0049:         */
0050:        public class FtpConnection implements  BasicConnection, FtpConstants {
0051:            private static final boolean TESTMODE = false;
0052:
0053:            // everything starting with this will be treated
0054:            // as a negative response
0055:            private final static String NEGATIVE = "5";
0056:            private final static String NEGATIVE2 = "4";
0057:
0058:            // everything starting with this will be treated
0059:            // as a positive response
0060:            private final static String POSITIVE = "2";
0061:
0062:            // for resuming
0063:            private final static String PROCEED = "3"; //"350";
0064:            private final static char MORE_LINES_APPENDED = '-';
0065:
0066:            /** Internal download constant */
0067:            public final static String DOWNLOAD = "DOWNLOAD";
0068:
0069:            /** Internal upload constant */
0070:            public final static String UPLOAD = "UPLOAD";
0071:
0072:            /** Internal abort command constant */
0073:            public final static String ABOR = "ABOR";
0074:
0075:            //*** 1.44: if LIST is not set, then load it from advanced settings
0076:            //***       And if the file for it is not found, then create it
0077:            //***       with LIST -laL as the default
0078:            public static String LIST_DEFAULT = "LIST -laL";
0079:            public static String LIST = "default";
0080:            public final static String ASCII = "A";
0081:            public final static String BINARY = "I";
0082:            public final static String EBCDIC = "E";
0083:            public final static String L8 = "L 8";
0084:            public final static String STREAM = "S";
0085:            public final static String BLOCKED = "B";
0086:            public final static String COMPRESSED = "C";
0087:            private static boolean useStream = true;
0088:            private static boolean useBlocked = true;
0089:            private static boolean useCompressed = true;
0090:
0091:            // active ftp ports
0092:            private static int porta = 5; // 5 * 256 + 1 = 1281
0093:            private static int portb = 1;
0094:
0095:            //***
0096:
0097:            /**
0098:             *        Used to determine the type of transfer.
0099:             */
0100:            public boolean hasUploaded = false;
0101:            public boolean work = true;
0102:            private boolean msg = true;
0103:            private boolean ok = true;
0104:            private String pwd = "";
0105:            private String initCWD = Settings.defaultDir;
0106:            private String[] loginAck = new String[] {
0107:                    FTP331_USER_OK_NEED_PASSWORD, FTP230_LOGGED_IN };
0108:            private String osType = "";
0109:            private String dataType;
0110:            private FtpTransfer lastTransfer = null;
0111:            private boolean modeStreamSet = false;
0112:            private DataConnection dcon = null;
0113:            private Vector listeners = new Vector();
0114:            private ConnectionHandler handler = new ConnectionHandler();
0115:
0116:            // directory downloaded to
0117:            private String localPath = null;
0118:
0119:            /** the host */
0120:            private String host = "";
0121:
0122:            /** the user */
0123:            private String username;
0124:
0125:            /** the password */
0126:            private String password;
0127:
0128:            /** the port */
0129:            private int port = 21;
0130:
0131:            /** the InputStream of the control connection */
0132:            private BufferedReader in;
0133:
0134:            /** the OutputStream of the control connection */
0135:            private JConnection jcon;
0136:
0137:            /** we are disconnected */
0138:            private boolean connected = false;
0139:            private boolean shortProgress = false;
0140:            private boolean isDirUpload = false;
0141:            private String baseFile;
0142:            private int fileCount;
0143:            private String typeNow = "";
0144:            private String crlf = null;
0145:
0146:            /**
0147:             * May contain date listing
0148:             */
0149:            public Vector dateVector = new Vector();
0150:            public Vector currentListing = new Vector();
0151:            public Vector currentFiles = new Vector();
0152:            public Vector currentSizes = new Vector();
0153:            public Vector currentPerms = new Vector();
0154:
0155:            /**
0156:             * Create an instance with a given host
0157:             *
0158:             * @param host The host to connect to
0159:             */
0160:            public FtpConnection(String host) {
0161:                this .host = host;
0162:
0163:                File f = new File(".");
0164:                setLocalPath(f.getAbsolutePath());
0165:            }
0166:
0167:            /**
0168:             * Create an instance with a given host, port and initial remote working directory
0169:             *
0170:             * @param host The host to connect to
0171:             * @param port The port used for the control connection, usually 21
0172:             * @param initCWD The initial remote working directory
0173:             */
0174:            public FtpConnection(String host, int port, String initCWD) {
0175:                this .host = host;
0176:                this .port = port;
0177:                this .initCWD = initCWD;
0178:
0179:                File f = new File(".");
0180:                setLocalPath(f.getAbsolutePath());
0181:            }
0182:
0183:            /**
0184:             * Connect to the server an log in.
0185:             *
0186:             * Does also fire directory update and connection initialized event if successful or
0187:             * connection failed event if failed.
0188:             *
0189:             * @param username The username
0190:             * @param password  The password
0191:             * @param initCWD The initial remote working directory
0192:             * @param crlfx \n, \r, \r\n, CR, LF or CRLF - line break style of the server
0193:             * @return  WRONG_LOGIN_DATA, OFFLINE, GENERIC_FAILED or LOGIN_OK status code
0194:             */
0195:            public FtpConnection(String host, int port, String initCWD,
0196:                    String crlfx) {
0197:                this .host = host;
0198:                this .port = port;
0199:                this .initCWD = initCWD;
0200:
0201:                if (crlfx != null) {
0202:                    if (crlfx.equals("\n") || crlfx.equals("\r")
0203:                            || crlfx.equals("\r\n"))
0204:                        this .crlf = crlfx;
0205:                    crlfx = crlfx.trim().toUpperCase();
0206:                    if (crlfx.equals("LF"))
0207:                        this .crlf = "\n";
0208:                    else if (crlfx.equals("CR"))
0209:                        this .crlf = "\r";
0210:                    else if (crlfx.equals("CRLF"))
0211:                        this .crlf = "\r\n";
0212:                }
0213:                //Log.out("\n\nCRLF:---"+crlf+"---\n\n");
0214:
0215:                File f = new File(".");
0216:                setLocalPath(f.getAbsolutePath());
0217:            }
0218:
0219:            /**
0220:             * Connect to the server an log in.
0221:             *
0222:             * Does also fire directory update and connection initialized event if successful or
0223:             * connection failed event if failed.
0224:             *
0225:             * @param username The username
0226:             * @param password  The password
0227:             * @return  WRONG_LOGIN_DATA, OFFLINE, GENERIC_FAILED or LOGIN_OK status code
0228:             */
0229:            public int login(String username, String password) {
0230:                this .username = username;
0231:                this .password = password;
0232:
0233:                int status = LOGIN_OK;
0234:
0235:                if (msg) {
0236:                    Log.debug("Connecting to " + host);
0237:                }
0238:
0239:                jcon = new JConnection(host, port);
0240:
0241:                if (jcon.isThere()) {
0242:                    in = jcon.getReader();
0243:
0244:                    if (getLine(POSITIVE) == null)//FTP220_SERVICE_READY) == null)
0245:                    {
0246:                        ok = false;
0247:                        Log
0248:                                .debug("Server closed Connection, maybe too many users...");
0249:                        status = OFFLINE;
0250:                    }
0251:
0252:                    if (msg) {
0253:                        Log.debug("Connection established...");
0254:                    }
0255:
0256:                    jcon.send(USER + " " + username);
0257:
0258:                    if (!getLine(loginAck).startsWith(POSITIVE))//FTP230_LOGGED_IN))
0259:                    {
0260:                        jcon.send(PASS + " " + password);
0261:
0262:                        if (success(POSITIVE))//FTP230_LOGGED_IN))
0263:                        {
0264:                            if (msg) {
0265:                                Log.debug("Logged in...");
0266:                            }
0267:                        } else {
0268:                            Log.debug("Wrong password!");
0269:                            ok = false;
0270:                            status = WRONG_LOGIN_DATA;
0271:                        }
0272:                    }
0273:
0274:                    // end if(jcon)...
0275:                } else {
0276:                    if (msg) {
0277:                        Log.debug("FTP not available!");
0278:                        ok = false;
0279:                        status = GENERIC_FAILED;
0280:                    }
0281:                }
0282:
0283:                if (ok) {
0284:                    connected = true;
0285:                    system();
0286:
0287:                    //if(getOsType().indexOf("MVS") < 0) 
0288:                    binary();
0289:
0290:                    if (initCWD.trim().equals(Settings.defaultDir)
0291:                            || !chdirNoRefresh(initCWD)) {
0292:                        //System.out.println("default dir...");
0293:                        //if(!chdirNoRefresh(getPWD()))
0294:                        //{
0295:                        //System.out.println("FtpConnection should not do this...");
0296:                        //	if(!chdirNoRefresh("~"))
0297:                        //	{
0298:                        //  		chdirNoRefresh("/");
0299:                        //	}
0300:                        //}
0301:                        updatePWD();
0302:                    }
0303:
0304:                    //Array of length 6 created, as that is maximum LoadSet size (need
0305:                    //public variable with that constant there for it to refer to?)
0306:                    String[] advSettings = new String[6];
0307:
0308:                    if (getOsType().indexOf("OS/2") >= 0) {
0309:                        LIST_DEFAULT = "LIST";
0310:                    }
0311:
0312:                    if (LIST.equals("default")) {
0313:                        //just get the first item (somehow it knows first is the
0314:                        //FTP list command)
0315:                        advSettings = LoadSet.loadSet(Settings.adv_settings);
0316:
0317:                        //*** IF FILE NOT FOUND, CREATE IT AND SET IT TO LIST_DEFAULT
0318:                        if (advSettings == null) {
0319:                            LIST = LIST_DEFAULT;
0320:
0321:                            SaveSet s = new SaveSet(Settings.adv_settings, LIST);
0322:                        } else {
0323:                            LIST = advSettings[0];
0324:
0325:                            if (LIST == null) {
0326:                                LIST = LIST_DEFAULT;
0327:                            }
0328:                        }
0329:                    }
0330:
0331:                    if (getOsType().indexOf("MVS") >= 0) {
0332:                        LIST = "LIST";
0333:                    }
0334:
0335:                    //***
0336:                    fireDirectoryUpdate(this );
0337:                    fireConnectionInitialized(this );
0338:                } else {
0339:                    fireConnectionFailed(this , new Integer(status).toString());
0340:                }
0341:
0342:                return status;
0343:            }
0344:
0345:            /**
0346:             * Sort the filesizes an return an array.
0347:             *
0348:             * The Array should be in sync with the other sort*-Methods
0349:             *
0350:             * @return An String-array of sizes containing the size or -1 if failed or 0 for directories
0351:             */
0352:            public String[] sortSize() {
0353:                try {
0354:                    currentSizes.removeAllElements();
0355:
0356:                    for (int i = 0; i < currentListing.size(); i++) {
0357:                        String tmp = (String) currentListing.get(i);
0358:
0359:                        // ------------- VMS override -------------------
0360:                        if (getOsType().indexOf("VMS") >= 0) {
0361:                            if (tmp.indexOf(";") < 0) {
0362:                                continue;
0363:                            }
0364:
0365:                            currentSizes.add("-1");
0366:
0367:                            continue;
0368:                        }
0369:
0370:                        // ------------- MVS override -------------------
0371:                        if (getOsType().indexOf("MVS") >= 0) {
0372:                            if (tmp.startsWith("Volume")
0373:                                    || (tmp.indexOf(" ") < 0)) {
0374:                                continue;
0375:                            }
0376:
0377:                            currentSizes.add("-1");
0378:
0379:                            continue;
0380:                        }
0381:
0382:                        // ------------------------------------------------
0383:                        else if (getOsType().indexOf("WINDOW") >= 0) {
0384:                            StringTokenizer to = new StringTokenizer(tmp, " ",
0385:                                    false);
0386:
0387:                            if (to.countTokens() >= 4) {
0388:                                to.nextToken();
0389:                                to.nextToken();
0390:
0391:                                String size = to.nextToken();
0392:
0393:                                if (size.equals("<DIR>")) {
0394:                                    currentSizes.add("0");
0395:                                } else {
0396:                                    try {
0397:                                        Long.parseLong(size);
0398:                                        currentSizes.add(size);
0399:                                    } catch (Exception ex) {
0400:                                        currentSizes.add("-1");
0401:                                        Log
0402:                                                .out("WARNING: filesize can not be determined - value is "
0403:                                                        + size);
0404:                                    }
0405:                                }
0406:                            }
0407:                        }
0408:
0409:                        // ------------------------------------------------
0410:                        else if (getOsType().indexOf("OS/2") >= 0) {
0411:                            StringTokenizer to = new StringTokenizer(tmp, " ",
0412:                                    false);
0413:                            tmp = giveSize(to, 0);
0414:                            Log.out("OS/2 parser (size): " + tmp);
0415:                            currentSizes.add(tmp);
0416:                        } else {
0417:                            //Log.out("\n\nparser\n\n");
0418:                            StringTokenizer to = new StringTokenizer(tmp, " ",
0419:                                    false);
0420:
0421:                            if (to.countTokens() >= 8) // unix
0422:                            {
0423:                                tmp = giveSize(to, 4);
0424:                                currentSizes.add(tmp);
0425:
0426:                                //Log.out(tmp);
0427:                            } else if (to.countTokens() == 7) // unix, too
0428:                            {
0429:                                Log
0430:                                        .out("WARNING: 7 token backup size parser activated!");
0431:                                tmp = giveSize(to, 4);
0432:                                currentSizes.add(tmp);
0433:                            } else {
0434:                                Log.debug("cannot parse line: " + tmp);
0435:                            }
0436:                        }
0437:                    }
0438:                } catch (Exception ex) {
0439:                    Log.debug(ex.toString() + " @FtpConnection::sortSize#1");
0440:                    return new String[0];
0441:                }
0442:
0443:                return toArray(currentSizes);
0444:            }
0445:
0446:            private String[] toArray(Vector in) {
0447:                String ret[] = new String[in.size()];
0448:
0449:                for (int i = 0; i < in.size(); i++) {
0450:                    ret[i] = (String) in.get(i);
0451:                }
0452:
0453:                return ret;
0454:            }
0455:
0456:            /**
0457:             * Sort the permissions an return an array.
0458:             *
0459:             * The Array should be in sync with the other sort*-Methods
0460:             *
0461:             * @param file The file containing the raw server listing, usually Settings.ls_out
0462:             * @return An int-array of sizes containing W, R or DENIED for each file
0463:             */
0464:            public int[] getPermissions() {
0465:                try {
0466:                    currentPerms.removeAllElements();
0467:
0468:                    for (int i = 0; i < currentListing.size(); i++) {
0469:                        String tmp = (String) currentListing.get(i);
0470:
0471:                        // ------------- VMS override -------------------
0472:                        if (getOsType().indexOf("VMS") >= 0) {
0473:                            if (tmp.indexOf(";") < 0) {
0474:                                continue;
0475:                            }
0476:
0477:                            currentPerms.add("r");
0478:
0479:                            continue;
0480:                        }
0481:
0482:                        // ------------- MVS override -------------------
0483:                        if (getOsType().indexOf("MVS") >= 0) {
0484:                            if (tmp.startsWith("Volume")) {
0485:                                continue;
0486:                            }
0487:
0488:                            currentPerms.add("r");
0489:
0490:                            continue;
0491:                        }
0492:
0493:                        // ------------------------------------------------
0494:
0495:                        StringTokenizer to = new StringTokenizer(tmp.trim(),
0496:                                " ", false);
0497:
0498:                        if (!(to.countTokens() > 3)
0499:                                || (tmp.startsWith("/") && (tmp
0500:                                        .indexOf("denied") > 0))) {
0501:                            continue;
0502:                        }
0503:
0504:                        tmp = to.nextToken();
0505:
0506:                        if (tmp.length() != 10) {
0507:                            //System.out.println(tmp + " - e");
0508:                            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
0509:                        }
0510:
0511:                        char ur = tmp.charAt(1);
0512:                        char uw = tmp.charAt(2);
0513:                        char ar = tmp.charAt(7);
0514:                        char aw = tmp.charAt(8);
0515:
0516:                        to.nextToken();
0517:
0518:                        String user = to.nextToken();
0519:
0520:                        //System.out.println(""+ur+":"+ar+":"+tmp);
0521:                        if (aw == 'w') {
0522:                            currentPerms.add("w");
0523:                        } else if (user.equals(username) && (uw == 'w')) {
0524:                            currentPerms.add("w");
0525:                        } else if (ar == 'r') {
0526:                            currentPerms.add("r");
0527:                        } else if (user.equals(username) && (ur == 'r')) {
0528:                            currentPerms.add("r");
0529:                        } else {
0530:                            //System.out.println(ur+":"+ar+":"+user+":"+username+":");
0531:                            currentPerms.add("n");
0532:                        }
0533:                    }
0534:                } catch (Exception ex) {
0535:                    Log.debug(ex.toString()
0536:                            + " @FtpConnection::getPermissions#1");
0537:                }
0538:
0539:                int[] ret = new int[currentPerms.size()];
0540:
0541:                for (int i = 0; i < currentPerms.size(); i++) {
0542:                    String fx = (String) currentPerms.get(i);
0543:
0544:                    if (fx.equals("w")) {
0545:                        ret[i] = W;
0546:                    } else if (fx.equals("n")) {
0547:                        ret[i] = DENIED;
0548:                    } else {
0549:                        ret[i] = R;
0550:                    }
0551:                    //System.out.println(ret[i]);
0552:                }
0553:
0554:                return ret;
0555:            }
0556:
0557:            /**
0558:             * Sort the filenames of the current working dir an return an array.
0559:             *
0560:             * The Array should be in sync with the other sort*-Methods
0561:             *
0562:             * @return An String-array of sizes containing the name of the file (symlinks are resolved)
0563:             */
0564:            public String[] sortLs() {
0565:                try {
0566:                    boolean newUnixDateStyle = false;
0567:                    dateVector = new Vector();
0568:                    currentFiles.removeAllElements();
0569:
0570:                    for (int i = 0; i < currentListing.size(); i++) {
0571:                        String tmp = (String) currentListing.get(i);
0572:
0573:                        // ------------------- VMS override --------------------
0574:                        if (getOsType().indexOf("VMS") >= 0) {
0575:                            int x = tmp.indexOf(";");
0576:
0577:                            if (x < 0) {
0578:                                continue;
0579:                            }
0580:
0581:                            tmp = tmp.substring(0, x);
0582:
0583:                            if (tmp.endsWith("DIR")) {
0584:                                currentFiles.add(tmp.substring(0, tmp
0585:                                        .lastIndexOf("."))
0586:                                        + "/");
0587:                            } else {
0588:                                currentFiles.add(tmp);
0589:                            }
0590:
0591:                            //Log.out("listing - (vms parser): " + tmp);
0592:
0593:                            continue;
0594:                        } else if (getOsType().indexOf("OS/2") >= 0) {
0595:                            StringTokenizer to2 = new StringTokenizer(tmp, " ",
0596:                                    true);
0597:
0598:                            if (giveFile(to2, 2).indexOf("DIR") >= 0) {
0599:                                to2 = new StringTokenizer(tmp, " ", true);
0600:                                tmp = giveFile(to2, 5);
0601:                                tmp = tmp + "/";
0602:                            } else {
0603:                                to2 = new StringTokenizer(tmp, " ", true);
0604:
0605:                                if (giveFile(to2, 1).indexOf("DIR") >= 0) {
0606:                                    //Log.out("OS/2 parser (DIRFIX): " + tmp);
0607:                                    to2 = new StringTokenizer(tmp, " ", true);
0608:                                    tmp = giveFile(to2, 4);
0609:                                    tmp = tmp + "/";
0610:                                } else {
0611:                                    to2 = new StringTokenizer(tmp, " ", true);
0612:                                    tmp = giveFile(to2, 4);
0613:                                }
0614:                            }
0615:
0616:                            Log.out("OS/2 parser: " + tmp);
0617:                            currentFiles.add(tmp);
0618:
0619:                            continue;
0620:                        }
0621:
0622:                        // -------------------------------------------------------
0623:                        // ------------------- MVS override --------------------
0624:                        if (getOsType().indexOf("MVS") >= 0) {
0625:                            if (tmp.startsWith("Volume")
0626:                                    || (tmp.indexOf(" ") < 0)) {
0627:                                Log.out("->" + tmp);
0628:
0629:                                continue;
0630:                            }
0631:
0632:                            String f = tmp.substring(tmp.lastIndexOf(" "))
0633:                                    .trim();
0634:                            String isDir = tmp.substring(
0635:                                    tmp.lastIndexOf(" ") - 5, tmp
0636:                                            .lastIndexOf(" "));
0637:
0638:                            if (isDir.indexOf("PO") >= 0) {
0639:                                currentFiles.add(f + "/");
0640:                            } else {
0641:                                currentFiles.add(f);
0642:                            }
0643:
0644:                            Log.out("listing - (mvs parser): " + tmp + " -> "
0645:                                    + f);
0646:                            continue;
0647:                        } else if (getOsType().indexOf("OS/2") >= 0) {
0648:                            StringTokenizer to2 = new StringTokenizer(tmp, " ",
0649:                                    true);
0650:
0651:                            if (giveFile(to2, 2).indexOf("DIR") >= 0) {
0652:                                to2 = new StringTokenizer(tmp, " ", true);
0653:                                tmp = giveFile(to2, 5);
0654:                                tmp = tmp + "/";
0655:                            } else {
0656:                                to2 = new StringTokenizer(tmp, " ", true);
0657:
0658:                                if (giveFile(to2, 1).indexOf("DIR") >= 0) {
0659:                                    //Log.out("OS/2 parser (DIRFIX): " + tmp);
0660:                                    to2 = new StringTokenizer(tmp, " ", true);
0661:                                    tmp = giveFile(to2, 4);
0662:                                    tmp = tmp + "/";
0663:                                } else {
0664:                                    to2 = new StringTokenizer(tmp, " ", true);
0665:                                    tmp = giveFile(to2, 4);
0666:                                }
0667:                            }
0668:
0669:                            Log.out("OS/2 parser: " + tmp);
0670:                            currentFiles.add(tmp);
0671:
0672:                            continue;
0673:                        }
0674:
0675:                        // -------------------------------------------------------
0676:                        // ------------------- Unix, Windows and others -----
0677:                        boolean isDir = false;
0678:                        boolean isLink = false;
0679:
0680:                        if (tmp.startsWith("d") || (tmp.indexOf("<DIR>") >= 0)) {
0681:                            isDir = true;
0682:                        }
0683:
0684:                        if (tmp.startsWith("l")) {
0685:                            isLink = true;
0686:                        }
0687:
0688:                        if (tmp.startsWith("/") && (tmp.indexOf("denied") > 0)) {
0689:                            continue;
0690:                        }
0691:
0692:                        StringTokenizer to = new StringTokenizer(tmp, " ",
0693:                                false);
0694:                        StringTokenizer to2 = new StringTokenizer(tmp, " ",
0695:                                true);
0696:
0697:                        int tokens = to.countTokens();
0698:
0699:                        //Log.out("listing: tokens: " + tokens + " - " + tmp);
0700:                        boolean set = false;
0701:
0702:                        //-----preparsing-----
0703:                        int lcount = 0;
0704:
0705:                        if (!newUnixDateStyle) {
0706:                            try {
0707:                                StringTokenizer tx = new StringTokenizer(tmp,
0708:                                        " ", false);
0709:                                tx.nextToken();
0710:                                tx.nextToken();
0711:                                tx.nextToken();
0712:                                tx.nextToken();
0713:                                tx.nextToken();
0714:
0715:                                String date = tx.nextToken();
0716:                                int x = date.indexOf("-");
0717:                                int y = date.lastIndexOf("-");
0718:
0719:                                if (y > x) {
0720:                                    Log.debug("Using new Unix date parser");
0721:                                    newUnixDateStyle = true;
0722:                                }
0723:                            } catch (Exception ex) {
0724:                                Log.out("could not preparse line: " + tmp);
0725:                                lcount++;
0726:
0727:                                //ex.printStackTrace();
0728:                            }
0729:                        }
0730:
0731:                        //--------------------
0732:                        //Log.out("tmp: " + tmp);
0733:                        if (newUnixDateStyle) // unix, too
0734:                        {
0735:                            set = true;
0736:
0737:                            //Log.out("listing - (unix parser #2, token 7): " + tmp);
0738:                            //------- date parser testing ---------
0739:                            try {
0740:                                //Log.out(">>> date parser: " + tmp);
0741:                                StringTokenizer to3 = new StringTokenizer(tmp,
0742:                                        " ", true);
0743:                                String date = giveFile(to3, 5);
0744:                                String date2 = date
0745:                                        .substring(date.indexOf("-") + 1);
0746:                                date2 = date2.substring(date.indexOf("-") + 2);
0747:
0748:                                //Log.out("date1: "+date+"/"+"date2: "+date2);	
0749:                                String t = date;
0750:                                String y = t.substring(0, t.indexOf("-"));
0751:                                String m = t.substring(t.indexOf("-") + 1, t
0752:                                        .indexOf("-") + 3);
0753:                                String m1 = t.substring(t.indexOf("-") + 1);
0754:                                String day = m1.substring(m1.indexOf("-") + 1,
0755:                                        m1.indexOf("-") + 3);
0756:                                String h = date2.substring(0, date2
0757:                                        .indexOf(":"));
0758:                                String min = date2.substring(
0759:                                        date2.indexOf(":") + 1, date2
0760:                                                .indexOf(":") + 3);
0761:
0762:                                //Log.out("day:"+day+"year:"+y+"mon:"+m+"hour:"+h+"m:"+min);
0763:                                Date d = new Date();
0764:                                d.setDate(Integer.parseInt(day));
0765:                                d.setYear(Integer.parseInt(y));
0766:                                d.setMonth(Integer.parseInt(m) - 1);
0767:                                d.setHours(Integer.parseInt(h));
0768:                                d.setMinutes(Integer.parseInt(min));
0769:
0770:                                dateVector.add(d);
0771:
0772:                                //Log.out("+++ date: \"" + d.toString() + "\"");
0773:                            } catch (Exception ex) {
0774:                                ex.printStackTrace();
0775:
0776:                                //set = false;
0777:                            }
0778:
0779:                            // -----------------------------
0780:                            tmp = giveFile(to2, 7);
0781:
0782:                            if (lcount > 1) {
0783:                                dateVector = new Vector();
0784:                            }
0785:                        } else if (tokens > 8) // unix
0786:                        {
0787:                            set = true;
0788:                            tmp = giveFile(to2, 8);
0789:
0790:                            //Log.out("listing - (unix parser, token 8): " + tmp);
0791:                        } else if (tokens > 3) // windows
0792:                        {
0793:                            set = true;
0794:                            tmp = giveFile(to2, 3);
0795:
0796:                            if (tmp.startsWith("<error>")) {
0797:                                tmp = giveFile(to2, 4);
0798:
0799:                                //Log.out("listing - (windows parser, token 4): " + tmp);
0800:                            } else {
0801:                                //Log.out("listing - (windows parser, token 3): " + tmp);
0802:                            }
0803:                        }
0804:
0805:                        if (tmp.startsWith("<error>") || !set) {
0806:                            if (tokens < 3) {
0807:                                continue;
0808:                            }
0809:
0810:                            tmp = giveFile(to2, tokens);
0811:                            Log
0812:                                    .out("listing - WARNING: listing style unknown, using last token as filename!");
0813:                            Log
0814:                                    .out("listing - this may work but may also fail, filesizes and permissions will probably fail, too...");
0815:                            Log
0816:                                    .out("listing - please send us a feature request with the serveraddress to let us support this listing style :)");
0817:                            Log.out("listing - (backup parser, token " + tokens
0818:                                    + " ): " + tmp);
0819:                        }
0820:
0821:                        if (isDir) {
0822:                            tmp = tmp + "/";
0823:                        } else if (isLink) {
0824:                            tmp = tmp + "###";
0825:                        }
0826:
0827:                        currentFiles.add(tmp);
0828:                        // -------------------------------------------------------------
0829:                    }
0830:
0831:                    String[] files = toArray(currentFiles);
0832:
0833:                    for (int i = 0; i < files.length; i++) {
0834:                        files[i] = parseSymlink(files[i]);
0835:
0836:                        //System.out.println("> " + files[i]+":"+dateVector.elementAt(i));
0837:                        //System.out.println("> " + files.length+":"+dateVector.size());
0838:                    }
0839:
0840:                    return files;
0841:                } catch (Exception ex) {
0842:                    Log.debug(ex.toString() + " @FtpConnection::sortLs");
0843:                    ex.printStackTrace();
0844:                }
0845:
0846:                //------- date parser test ------
0847:
0848:                /*
0849:                String[] x = (String[]) dateVector.toArray();
0850:                for(int i=0; i<x.length; i++)
0851:                {
0852:                        Log.out(":"+x[i]);
0853:                }
0854:                 */
0855:
0856:                //-------------------------------
0857:                return new String[0];
0858:            }
0859:
0860:            /** get a filename */
0861:            private String giveFile(StringTokenizer to, int lev) {
0862:                String t2 = null;
0863:
0864:                for (int i = 0; i < lev; i++) {
0865:                    if (to.hasMoreTokens()) {
0866:                        String t = to.nextToken();
0867:
0868:                        //Log.out("> "+t);
0869:                        if (t.equals(" ") || t.equals("\t")) {
0870:                            // -
0871:
0872:                            /*
0873:                               while(to.hasMoreTokens())
0874:                               {
0875:                                       t2 = to.nextToken();
0876:                                   if(!t.equals(" ") && !t.equals("\t")) break;
0877:                               }
0878:                             */
0879:                            i--;
0880:                        }
0881:                    }
0882:                }
0883:
0884:                String tmp = "<error>";
0885:
0886:                /*
0887:                if(t2 != null)
0888:                {
0889:                        tmp = t2;
0890:                }
0891:                 */
0892:                while (tmp.equals(" ") || tmp.equals("\t")
0893:                        || tmp.equals("<error>")) {
0894:                    if (to.hasMoreTokens()) {
0895:                        tmp = to.nextToken();
0896:                    } else {
0897:                        break;
0898:                    }
0899:                }
0900:
0901:                while (to.hasMoreTokens()) {
0902:                    tmp = tmp + to.nextToken();
0903:                }
0904:
0905:                //Log.out(">>> "+tmp);
0906:                return tmp;
0907:            }
0908:
0909:            /** get a filesize */
0910:            private String giveSize(StringTokenizer to, int lev) {
0911:                for (int i = 0; i < lev; i++) {
0912:                    if (to.hasMoreTokens()) {
0913:                        if (to.nextToken().equals(" ")) {
0914:                            i--;
0915:                        }
0916:                    }
0917:                }
0918:
0919:                while (to.hasMoreTokens()) {
0920:                    String tmp = to.nextToken();
0921:
0922:                    if (!tmp.equals(" ")) {
0923:                        try {
0924:                            Integer.parseInt(tmp);
0925:                        } catch (NumberFormatException ex) {
0926:                            return "-1";
0927:                        }
0928:
0929:                        return tmp;
0930:                    }
0931:                }
0932:
0933:                return "-2";
0934:            }
0935:
0936:            /**
0937:             * Try to determine the os-type.
0938:             * (Used internally to check how to parse the ls-output)
0939:             *
0940:             * @return A Part of the SYST comman server response
0941:             */
0942:            public String getOsType() {
0943:                if (TESTMODE) {
0944:                    return "MVS";
0945:                } else {
0946:                    return osType;
0947:                }
0948:            }
0949:
0950:            private void setOsType(String os) {
0951:                osType = os.toUpperCase();
0952:            }
0953:
0954:            private int getPasvPort(String str) {
0955:                int start = str.lastIndexOf(",");
0956:                String lo = "";
0957:                start++;
0958:
0959:                while (start < str.length()) {
0960:                    char c = str.charAt(start);
0961:
0962:                    if (!Character.isDigit(c)) {
0963:                        break;
0964:                    }
0965:
0966:                    lo = lo + c;
0967:                    start++;
0968:                }
0969:
0970:                System.out.println("\n\n\n" + str);
0971:
0972:                String hi = "";
0973:                start = str.lastIndexOf(",");
0974:                start--;
0975:
0976:                while (true) {
0977:                    char c = str.charAt(start);
0978:
0979:                    if (!Character.isDigit(c)) {
0980:                        break;
0981:                    }
0982:
0983:                    hi = c + hi;
0984:                    start--;
0985:                }
0986:
0987:                //System.out.print(hi+":"+lo+" - ");
0988:                return ((Integer.parseInt(hi) * 256) + Integer.parseInt(lo));
0989:            }
0990:
0991:            private int getActivePort() {
0992:                return (getPortA() * 256) + getPortB();
0993:            }
0994:
0995:            /** parse a symlink */
0996:            private String parseSymlink(String file) {
0997:                if (file.indexOf("->") >= 0) {
0998:                    //System.out.print(file+" :-> symlink converted to:");
0999:                    file = file.substring(0, file.indexOf("->")).trim();
1000:                    file = file + "###";
1001:
1002:                    //System.out.println(file);
1003:                }
1004:
1005:                return file;
1006:            }
1007:
1008:            /** parse a symlink and cut the back */
1009:            private String parseSymlinkBack(String file) {
1010:                if (file.indexOf("->") >= 0) {
1011:                    //System.out.print(file+" :-> symlink converted to:");
1012:                    file = file.substring(file.indexOf("->") + 2).trim();
1013:
1014:                    //System.out.println(file);
1015:                }
1016:
1017:                return file;
1018:            }
1019:
1020:            /** test for symlink */
1021:            private boolean isSymlink(String file) {
1022:                if (file.indexOf("->") >= 0) {
1023:                    return true;
1024:                }
1025:
1026:                return false;
1027:            }
1028:
1029:            /** Download a file or directory.
1030:             * Uses multithreading if enabled and does not block.
1031:             *
1032:             * @param file The file to download
1033:             * @return An int-statuscode, see constants defined in this class for details
1034:             */
1035:            public int handleDownload(String file) {
1036:                if (Settings.getEnableMultiThreading()) {
1037:                    Log.out("spawning new thread for this download.");
1038:
1039:                    FtpTransfer t = new FtpTransfer(host, port, getLocalPath(),
1040:                            getCachedPWD(), file, username, password,
1041:                            Transfer.DOWNLOAD, handler, listeners, crlf);
1042:                    lastTransfer = t;
1043:
1044:                    return NEW_TRANSFER_SPAWNED;
1045:                } else {
1046:                    Log.out("multithreading is completely disabled.");
1047:
1048:                    return download(file);
1049:                }
1050:            }
1051:
1052:            /**
1053:             * Download a file or directory, block until finished.
1054:             *
1055:             * @param file The file to download
1056:             * @return An int returncode
1057:             */
1058:            public int download(String file) {
1059:                //Log.out("ftp download started:" + this);
1060:
1061:                int stat;
1062:
1063:                if (file.endsWith("/")) {
1064:                    shortProgress = true;
1065:                    fileCount = 0;
1066:                    baseFile = file;
1067:                    dataType = DataConnection.GETDIR;
1068:
1069:                    stat = downloadDir(file);
1070:
1071:                    //pause(100);
1072:                    fireActionFinished(this );
1073:                    fireProgressUpdate(baseFile, DataConnection.DFINISHED + ":"
1074:                            + fileCount, -1);
1075:                    shortProgress = false;
1076:                } else {
1077:                    dataType = DataConnection.GET;
1078:
1079:                    stat = rawDownload(file);
1080:
1081:                    if (Settings.enableFtpDelays) {
1082:                        try {
1083:                            Thread.sleep(100);
1084:                        } catch (Exception ex) {
1085:                        }
1086:                    }
1087:
1088:                    fireActionFinished(this );
1089:                }
1090:
1091:                if (Settings.enableFtpDelays) {
1092:                    try {
1093:                        Thread.sleep(400);
1094:                    } catch (Exception ex) {
1095:                    }
1096:                }
1097:
1098:                return stat;
1099:            }
1100:
1101:            /**
1102:             * Get download InputStream.
1103:             *
1104:             * @param file The file to download
1105:             * @return An InputStream
1106:             */
1107:            public InputStream getDownloadInputStream(String file) {
1108:                Log.out("ftp stream download started:" + this );
1109:                file = parse(file);
1110:
1111:                try {
1112:                    int p = 0;
1113:                    dataType = DataConnection.GET;
1114:                    file = StringUtils.getFile(file);
1115:
1116:                    String path = getLocalPath() + file;
1117:
1118:                    BufferedReader in = jcon.getReader();
1119:
1120:                    modeStream();
1121:                    p = negotiatePort();
1122:
1123:                    dcon = new DataConnection(this , p, host, path, dataType,
1124:                            false, true);
1125:
1126:                    while (!dcon.isThere()) {
1127:                        pause(10);
1128:                    }
1129:
1130:                    jcon.send(RETR + " " + file);
1131:
1132:                    return dcon.getInputStream();
1133:                } catch (Exception ex) {
1134:                    ex.printStackTrace();
1135:                    Log.debug(ex.toString()
1136:                            + " @FtpConnection::getDownloadInputStream");
1137:
1138:                    return null;
1139:                }
1140:            }
1141:
1142:            private int rawDownload(String file) {
1143:                file = parse(file);
1144:
1145:                //String path = file;
1146:                try {
1147:                    int p = 0;
1148:
1149:                    //if(isRelative(file)) path = getLocalPath() + file;
1150:                    file = StringUtils.getFile(file);
1151:
1152:                    String path = getLocalPath() + file;
1153:
1154:                    //System.out.println(file + " : " + path);
1155:                    //BufferedReader in = jcon.getReader();
1156:                    modeStream();
1157:
1158:                    //binary();
1159:                    p = negotiatePort();
1160:
1161:                    File f = new File(path);
1162:
1163:                    //System.out.println("path: "+path);
1164:                    boolean resume = false;
1165:
1166:                    if (f.exists() && Settings.enableResuming) {
1167:                        jcon.send(REST + " " + f.length());
1168:
1169:                        if (getLine(PROCEED) != null) {
1170:                            resume = true;
1171:                        }
1172:                    }
1173:
1174:                    dcon = new DataConnection(this , p, host, path, dataType,
1175:                            resume); //, new Updater());
1176:
1177:                    while (!dcon.isThere()) {
1178:                        pause(10);
1179:                    }
1180:
1181:                    jcon.send(RETR + " " + file);
1182:
1183:                    String line = getLine(POSITIVE);
1184:                    Log.debug(line);
1185:
1186:                    // file has been created even if not downloaded, delete it
1187:                    if (line.startsWith(NEGATIVE)) {
1188:                        File f2 = new File(path);
1189:
1190:                        if (f2.exists() && (f2.length() == 0)) {
1191:                            f2.delete();
1192:                        }
1193:
1194:                        return PERMISSION_DENIED;
1195:                    } else if (!line.startsWith(POSITIVE)
1196:                            && !line.startsWith(PROCEED)) {
1197:                        return TRANSFER_FAILED;
1198:                    }
1199:
1200:                    // we need to block since some ftp-servers do not want the
1201:                    // refresh command that dirpanel sends otherwise
1202:                    while (!dcon.finished) {
1203:                        pause(10);
1204:                    }
1205:                } catch (Exception ex) {
1206:                    ex.printStackTrace();
1207:                    Log.debug(ex.toString() + " @FtpConnection::download");
1208:
1209:                    return TRANSFER_FAILED;
1210:                }
1211:
1212:                return TRANSFER_SUCCESSFUL;
1213:            }
1214:
1215:            private int downloadDir(String dir) {
1216:                if (!dir.endsWith("/")) {
1217:                    dir = dir + "/";
1218:                }
1219:
1220:                if (StringUtils.isRelative(dir)) {
1221:                    dir = getCachedPWD() + dir;
1222:                }
1223:
1224:                String path = getLocalPath() + StringUtils.getDir(dir);
1225:
1226:                //System.out.println("path: "+path);
1227:                String pwd = getCachedPWD() + StringUtils.getDir(dir);
1228:
1229:                String oldDir = getLocalPath();
1230:                String oldPwd = getCachedPWD();
1231:
1232:                File f = new File(path);
1233:
1234:                if (!f.exists()) {
1235:                    if (!f.mkdir()) {
1236:                        Log.debug("Can't create directory: " + dir);
1237:                    } else {
1238:                        Log.debug("Created directory...");
1239:                    }
1240:                }
1241:
1242:                setLocalPath(path);
1243:
1244:                if (!chdirNoRefresh(pwd)) {
1245:                    return CHDIR_FAILED;
1246:                }
1247:
1248:                try {
1249:                    list();
1250:                } catch (IOException ex) {
1251:                    return PERMISSION_DENIED;
1252:                }
1253:
1254:                String[] tmp = sortLs();
1255:
1256:                setLocalPath(path);
1257:
1258:                for (int i = 0; i < tmp.length; i++) {
1259:                    if (tmp[i].endsWith("/")) {
1260:                        if (tmp[i].trim().equals("../")
1261:                                || tmp[i].trim().equals("./")) {
1262:                            Log.debug("Skipping " + tmp[i].trim());
1263:                        } else {
1264:                            if (!work) {
1265:                                return TRANSFER_STOPPED;
1266:                            }
1267:
1268:                            if (downloadDir(tmp[i]) < 0) {
1269:                                ; // return TRANSFER_FAILED;
1270:                            }
1271:                        }
1272:                    } else {
1273:                        //System.out.println( "file: " + getLocalPath() + tmp[i] + "\n\n");
1274:                        if (!work) {
1275:                            return TRANSFER_STOPPED;
1276:                        }
1277:
1278:                        fileCount++;
1279:
1280:                        if (rawDownload(getLocalPath() + tmp[i]) < 0) {
1281:                            ; // return TRANSFER_FAILED;
1282:                        }
1283:                    }
1284:                }
1285:
1286:                chdirNoRefresh(oldPwd);
1287:                setLocalPath(oldDir);
1288:
1289:                return TRANSFER_SUCCESSFUL;
1290:            }
1291:
1292:            /** Upload a file or directory.
1293:             * Uses multithreading if enabled and does not block.
1294:             *
1295:             * @param file The file to upload
1296:             * @return An int-statuscode, NEW_TRANSFER_SPAWNED,TRANSFER_FAILED or TRANSFER_SUCCESSFUL
1297:             */
1298:            public int handleUpload(String file) {
1299:                return handleUpload(file, null);
1300:            }
1301:
1302:            /** Upload a file or directory.
1303:             * Uses multithreading if enabled and does not block.
1304:             *
1305:             * @param file The file to upload
1306:             * @param realName The file to rename the uploaded file to
1307:             * @return An int-statuscode, NEW_TRANSFER_SPAWNED,TRANSFER_FAILED or TRANSFER_SUCCESSFUL
1308:             */
1309:            public int handleUpload(String file, String realName) {
1310:                if (Settings.getEnableMultiThreading()
1311:                        && (!Settings.getNoUploadMultiThreading())) {
1312:                    Log.out("spawning new thread for this upload.");
1313:
1314:                    FtpTransfer t;
1315:
1316:                    if (realName != null) {
1317:                        t = new FtpTransfer(host, port, getLocalPath(),
1318:                                getCachedPWD(), file, username, password,
1319:                                Transfer.UPLOAD, handler, listeners, realName,
1320:                                crlf);
1321:                    } else {
1322:                        t = new FtpTransfer(host, port, getLocalPath(),
1323:                                getCachedPWD(), file, username, password,
1324:                                Transfer.UPLOAD, handler, listeners, crlf);
1325:                    }
1326:
1327:                    lastTransfer = t;
1328:
1329:                    return NEW_TRANSFER_SPAWNED;
1330:                } else {
1331:                    if (Settings.getNoUploadMultiThreading()) {
1332:                        Log.out("upload multithreading is disabled.");
1333:                    } else {
1334:                        Log.out("multithreading is completely disabled.");
1335:                    }
1336:
1337:                    return (realName == null) ? upload(file) : upload(file,
1338:                            realName);
1339:                }
1340:            }
1341:
1342:            /**
1343:             * Upload a file or directory, block until finished.
1344:             *
1345:             * @param file The file to upload
1346:             * @return An int returncode
1347:             */
1348:            public int upload(String file) {
1349:                return upload(file, file);
1350:            }
1351:
1352:            /**
1353:             * Upload and a file or directory under a given name, block until finished.
1354:             * Note that setting realName does not affect directory transfers
1355:             *
1356:             * @param file The file to upload
1357:             * @param realName The file to rename the uploaded file to
1358:             * @return An int responsecode
1359:             */
1360:            public int upload(String file, String realName) {
1361:                return upload(file, realName, null);
1362:            }
1363:
1364:            /**
1365:             * Upload from an InputStream, block until finished.
1366:             *
1367:             * @param file The file to upload
1368:             * @param in InputStream to read from
1369:             * @return An int responsecode
1370:             */
1371:            public int upload(String file, InputStream in) {
1372:                return upload(file, file, in);
1373:            }
1374:
1375:            /**
1376:             * Upload and a file or directory under a given name, block until finished.
1377:             * Note that setting realName does not affect directory transfers
1378:             *
1379:             * @param file The file to upload
1380:             * @param realName The file to rename the uploaded file to
1381:             * @param in InputStream to read from
1382:             * @return An int responsecode
1383:             */
1384:            public int upload(String file, String realName, InputStream in) {
1385:                hasUploaded = true;
1386:                Log.out("ftp upload started: " + this );
1387:
1388:                int stat;
1389:
1390:                if ((in == null) && new File(file).isDirectory()) {
1391:                    shortProgress = true;
1392:                    fileCount = 0;
1393:                    baseFile = file;
1394:                    dataType = DataConnection.PUTDIR;
1395:                    isDirUpload = true;
1396:
1397:                    stat = uploadDir(file);
1398:
1399:                    shortProgress = false;
1400:
1401:                    //System.out.println(fileCount + ":" + baseFile);
1402:                    fireProgressUpdate(baseFile, DataConnection.DFINISHED + ":"
1403:                            + fileCount, -1);
1404:
1405:                    fireActionFinished(this );
1406:                    fireDirectoryUpdate(this );
1407:                } else {
1408:                    dataType = DataConnection.PUT;
1409:                    stat = rawUpload(file, realName, in);
1410:
1411:                    try {
1412:                        Thread.sleep(100);
1413:                    } catch (Exception ex) {
1414:                    }
1415:
1416:                    fireActionFinished(this );
1417:                    fireDirectoryUpdate(this );
1418:                }
1419:
1420:                try {
1421:                    Thread.sleep(500);
1422:                } catch (Exception ex) {
1423:                }
1424:
1425:                return stat;
1426:            }
1427:
1428:            private int rawUpload(String file) {
1429:                return rawUpload(file, file);
1430:            }
1431:
1432:            private int rawUpload(String file, String realName) {
1433:                return rawUpload(file, realName, null);
1434:            }
1435:
1436:            /** uploads a file */
1437:            private int rawUpload(String file, String realName, InputStream in) {
1438:                if (!file.equals(realName)) {
1439:                    Log.debug("File: " + file + ", stored as " + realName);
1440:                } else {
1441:                    Log.debug("File: " + file);
1442:                    realName = null;
1443:                }
1444:
1445:                file = parse(file);
1446:
1447:                String path = file;
1448:
1449:                try {
1450:                    int p = 0;
1451:
1452:                    if (StringUtils.isRelative(file)) {
1453:                        path = getLocalPath() + file;
1454:                    }
1455:
1456:                    file = StringUtils.getFile(file);
1457:
1458:                    //BufferedReader in = jcon.getReader();
1459:                    boolean resume = false;
1460:                    String size = "0";
1461:
1462:                    if (Settings.enableUploadResuming && (in == null)) {
1463:                        list();
1464:
1465:                        String[] ls = sortLs();
1466:                        String[] sizes = sortSize();
1467:
1468:                        if ((ls == null) || (sizes == null)) {
1469:                            Log
1470:                                    .out(">>> ls out of sync (skipping resume check)");
1471:                        } else {
1472:                            for (int i = 0; i < ls.length; i++) {
1473:                                //Log.out(ls[i] + ":" + sizes[i]);
1474:                                if (realName != null) {
1475:                                    if (ls[i].equals(realName)) {
1476:                                        resume = true;
1477:                                        size = sizes[i];
1478:
1479:                                        break;
1480:                                    }
1481:                                } else {
1482:                                    if (ls[i].equals(file)) {
1483:                                        resume = true;
1484:                                        size = sizes[i];
1485:                                    }
1486:                                }
1487:                            }
1488:
1489:                            File f = new File(path);
1490:
1491:                            if (f.exists()
1492:                                    && (f.length() <= Integer.parseInt(size))) {
1493:                                Log
1494:                                        .out("skipping resuming, file is <= filelength");
1495:                                resume = false;
1496:                            } else if (f.exists() && Integer.parseInt(size) > 0) {
1497:                                if (!Settings.noUploadResumingQuestion) {
1498:                                    if (JOptionPane
1499:                                            .showConfirmDialog(
1500:                                                    new JLabel(),
1501:                                                    "A file smaller than the one to be uploaded already exists on the server,\n do you want to resume the upload?",
1502:                                                    "Resume upload?",
1503:                                                    JOptionPane.YES_NO_OPTION) != JOptionPane.OK_OPTION) {
1504:                                        resume = false;
1505:                                    }
1506:                                }
1507:                                Log
1508:                                        .out("resume: " + resume + ", size: "
1509:                                                + size);
1510:                            } else {
1511:                                Log
1512:                                        .out("resume: " + resume + ", size: "
1513:                                                + size);
1514:                            }
1515:                        }
1516:                    }
1517:
1518:                    modeStream();
1519:
1520:                    //binary();
1521:                    p = negotiatePort();
1522:
1523:                    if (resume && Settings.enableUploadResuming) {
1524:                        jcon.send(REST + " " + size);
1525:
1526:                        if (getLine(PROCEED) == null) {
1527:                            resume = false;
1528:                        }
1529:                    }
1530:
1531:                    dcon = new DataConnection(this , p, host, path, dataType,
1532:                            resume, Integer.parseInt(size), in); //, new Updater());
1533:
1534:                    while (!dcon.isThere()) {
1535:                        pause(10);
1536:                    }
1537:
1538:                    //System.out.println(path + " : " + file);
1539:                    if (realName != null) {
1540:                        jcon.send(STOR + " " + realName);
1541:                    } else {
1542:                        jcon.send(STOR + " " + file);
1543:                    }
1544:
1545:                    String tmp = getLine(POSITIVE);
1546:
1547:                    if (!tmp.startsWith(POSITIVE) && !tmp.startsWith(PROCEED)) {
1548:                        return TRANSFER_FAILED;
1549:                    }
1550:
1551:                    Log.debug(tmp);
1552:
1553:                    // we need to block since some ftp-servers do not want the
1554:                    // refresh command that dirpanel sends otherwise
1555:                    while (!dcon.finished) {
1556:                        pause(10);
1557:                    }
1558:                } catch (Exception ex) {
1559:                    ex.printStackTrace();
1560:                    Log.debug(ex.toString() + " @FtpConnection::upload");
1561:
1562:                    return TRANSFER_FAILED;
1563:                }
1564:
1565:                return TRANSFER_SUCCESSFUL;
1566:            }
1567:
1568:            private int uploadDir(String dir) {
1569:                //System.out.println("up");
1570:                if (dir.endsWith("\\")) {
1571:                    System.out
1572:                            .println("Something's wrong with the selected directory - please report this bug!");
1573:                }
1574:
1575:                if (!dir.endsWith("/")) {
1576:                    dir = dir + "/";
1577:                }
1578:
1579:                if (StringUtils.isRelative(dir)) {
1580:                    dir = getLocalPath() + dir;
1581:                }
1582:
1583:                String single = StringUtils.getDir(dir);
1584:                String path = dir.substring(0, dir.indexOf(single));
1585:
1586:                String remoteDir = getCachedPWD() + single; //StringUtils.removeStart(dir,path);
1587:                String oldDir = getCachedPWD();
1588:
1589:                if (Settings.safeMode) {
1590:                    noop();
1591:                }
1592:
1593:                boolean successful = mkdir(remoteDir);
1594:
1595:                if (!successful) {
1596:                    return MKDIR_FAILED;
1597:                }
1598:
1599:                if (Settings.safeMode) {
1600:                    noop();
1601:                }
1602:
1603:                chdirNoRefresh(remoteDir);
1604:
1605:                File f2 = new File(dir);
1606:                String[] tmp = f2.list();
1607:
1608:                for (int i = 0; i < tmp.length; i++) {
1609:                    String res = dir + tmp[i];
1610:                    File f3 = new File(res);
1611:
1612:                    if (f3.isDirectory()) {
1613:                        if (!work) {
1614:                            return TRANSFER_STOPPED;
1615:                        }
1616:
1617:                        uploadDir(res);
1618:                    } else {
1619:                        //System.out.println(">>>\nlp: "+path+single + "\nrp: ");
1620:                        //System.out.println(remoteDir +"\nres: "+res);
1621:                        if (!work) {
1622:                            return TRANSFER_STOPPED;
1623:                        }
1624:
1625:                        fileCount++;
1626:
1627:                        if (rawUpload(res) < 0) {
1628:                            ; //return TRANSFER_STOPPED;
1629:                        }
1630:                    }
1631:                }
1632:
1633:                chdirNoRefresh(oldDir);
1634:
1635:                return TRANSFER_SUCCESSFUL;
1636:            }
1637:
1638:            private String parse(String file) {
1639:                file = parseSymlink(file);
1640:
1641:                return file;
1642:            }
1643:
1644:            /** recursive delete remote directory */
1645:            private int cleanDir(String dir, String path) {
1646:                if (dir.equals("")) {
1647:                    return 0;
1648:                }
1649:
1650:                if (!dir.endsWith("/")) {
1651:                    dir = dir + "/";
1652:                }
1653:
1654:                String remoteDir = StringUtils.removeStart(dir, path);
1655:
1656:                String oldDir = pwd;
1657:                chdirNoRefresh(pwd + remoteDir);
1658:
1659:                try {
1660:                    list();
1661:                } catch (IOException ex) {
1662:                    // probably we don't have permission to ls here
1663:                    return PERMISSION_DENIED;
1664:                }
1665:
1666:                String[] tmp = sortLs();
1667:                chdirNoRefresh(oldDir);
1668:
1669:                if (tmp == null) {
1670:                    return GENERIC_FAILED;
1671:                }
1672:
1673:                for (int i = 0; i < tmp.length; i++) {
1674:                    Log.out("cleanDir: " + tmp);
1675:
1676:                    if (isSymlink(tmp[i])) {
1677:                        Log.debug("WARNING: Skipping symlink, remove failed.");
1678:                        Log
1679:                                .debug("This is necessary to prevent possible data loss when removing those symlinks.");
1680:
1681:                        tmp[i] = null;
1682:                    }
1683:
1684:                    if (tmp[i] != null) {
1685:                        tmp[i] = parseSymlink(tmp[i]);
1686:                    }
1687:
1688:                    if ((tmp[i] == null) || tmp[i].equals("./")
1689:                            || tmp[i].equals("../")) {
1690:                        //System.out.println(tmp[i]+"\n\n\n");
1691:                        continue;
1692:                    }
1693:
1694:                    //System.out.println(tmp[i]);
1695:                    //pause(500);
1696:                    if (tmp[i].endsWith("/")) {
1697:                        //   System.out.println(dir);
1698:                        cleanDir(dir + tmp[i], path);
1699:
1700:                        int x = removeFileOrDir(dir + tmp[i]);
1701:
1702:                        if (x < 0) {
1703:                            return x;
1704:                        }
1705:                    } else {
1706:                        //   System.out.println(dir+tmp[i]);
1707:                        int x = removeFileOrDir(dir + tmp[i]);
1708:
1709:                        if (x < 0) {
1710:                            return x;
1711:                        }
1712:                    }
1713:                }
1714:
1715:                return REMOVE_SUCCESSFUL;
1716:            }
1717:
1718:            /**
1719:             * Remove a remote file or directory.
1720:             *
1721:             * @param file The file to remove
1722:             * @return REMOVE_SUCCESSFUL, REMOVE_FAILED, PERMISSION_DENIED or  GENERIC_FAILED
1723:             */
1724:            public int removeFileOrDir(String file) {
1725:                if (file == null) {
1726:                    return 0;
1727:                }
1728:
1729:                if (file.trim().equals(".") || file.trim().equals("..")) {
1730:                    Log
1731:                            .debug("ERROR: Catching attempt to delete . or .. directories");
1732:
1733:                    return GENERIC_FAILED;
1734:                }
1735:
1736:                if (isSymlink(file)) {
1737:                    Log.debug("WARNING: Skipping symlink, remove failed.");
1738:                    Log
1739:                            .debug("This is necessary to prevent possible data loss when removing those symlinks.");
1740:
1741:                    return REMOVE_FAILED;
1742:                }
1743:
1744:                file = parseSymlink(file);
1745:
1746:                if (file.endsWith("/")) {
1747:                    int ret = cleanDir(file, getCachedPWD());
1748:
1749:                    if (ret < 0) {
1750:                        return ret;
1751:                    }
1752:
1753:                    jcon.send(RMD + " " + file);
1754:                } else {
1755:                    jcon.send(DELE + " " + file);
1756:                }
1757:
1758:                if (success(POSITIVE))//FTP250_COMPLETED))
1759:                {
1760:                    return REMOVE_SUCCESSFUL;
1761:                } else {
1762:                    return REMOVE_FAILED;
1763:                }
1764:            }
1765:
1766:            /**
1767:             * Disconnect from the server.
1768:             * The connection is marked ad closed even if the server does not respond correctly -
1769:             * if it fails for any reason the connection should just time out
1770:             *
1771:             */
1772:            public void disconnect() {
1773:                jcon.send(QUIT);
1774:                getLine(POSITIVE);//FTP221_SERVICE_CLOSING);
1775:                connected = false;
1776:            }
1777:
1778:            /**
1779:             * Execute a remote command.
1780:             * Sends noops before and after the command
1781:             *
1782:             *  @param cmd The raw command that is to be sent to the server
1783:             */
1784:            public void sendRawCommand(String cmd) {
1785:                noop();
1786:                Log.clearCache();
1787:                jcon.send(cmd);
1788:                noop();
1789:            }
1790:
1791:            /**
1792:             * Reads the response until line found or error.
1793:             * (Used internally)
1794:             *
1795:             * @param until The String the response line hast to start with, 2 for succesful return codes for example
1796:             */
1797:            public String getLine(String until) {
1798:                return getLine(new String[] { until });
1799:            }
1800:
1801:            /**
1802:             * Reads the response until line found or error.
1803:             * (Used internally)
1804:             */
1805:            public String getLine(String[] until) {
1806:                BufferedReader in = null;
1807:
1808:                try {
1809:                    in = jcon.getReader();
1810:                } catch (Exception ex) {
1811:                    Log.debug(ex.toString() + " @FtpConnection::getLine");
1812:                }
1813:
1814:                //String resultString = null;
1815:                String tmp;
1816:
1817:                while (true) {
1818:                    try {
1819:                        tmp = in.readLine();
1820:
1821:                        if (tmp == null) {
1822:                            break;
1823:                        }
1824:
1825:                        Log.debug(tmp);
1826:
1827:                        if (((tmp.startsWith(NEGATIVE) || (tmp
1828:                                .startsWith(NEGATIVE2))) && (tmp.charAt(3) != MORE_LINES_APPENDED))
1829:                                || tmp.startsWith(PROCEED)) {
1830:                            return tmp;
1831:                        } else {
1832:                            for (int i = 0; i < until.length; i++) {
1833:                                if (tmp.startsWith(until[i])) {
1834:                                    //if(resultString == null) resultString = tmp;
1835:                                    //else resultString = resultString + "\n" + tmp;
1836:                                    if (tmp.charAt(3) != MORE_LINES_APPENDED) {
1837:                                        return tmp;
1838:                                    }
1839:                                }
1840:                            }
1841:                        }
1842:                    } catch (Exception ex) {
1843:                        Log.debug(ex.toString() + " @FtpConnection::getLine");
1844:
1845:                        break;
1846:                    }
1847:                }
1848:
1849:                return null;
1850:            }
1851:
1852:            /**
1853:             * Check if login() was successful.
1854:             *
1855:             * @return True if connected, false otherwise
1856:             */
1857:            public boolean isConnected() {
1858:                return connected;
1859:            }
1860:
1861:            /**
1862:             * Get the current remote directory.
1863:             *
1864:             * @return The server's CWD
1865:             */
1866:            public String getPWD() {
1867:                if (connected) {
1868:                    updatePWD();
1869:                }
1870:
1871:                if (TESTMODE) {
1872:                    return "HUGO.user.";
1873:                }
1874:
1875:                return pwd;
1876:            }
1877:
1878:            /**
1879:             * Returns current remote directory (cached)
1880:             *
1881:             * @return The cached CWD
1882:             */
1883:            public String getCachedPWD() {
1884:                return pwd;
1885:            }
1886:
1887:            /**
1888:             * updates PWD
1889:             */
1890:            private void updatePWD() {
1891:                jcon.send(PWD);
1892:
1893:                String tmp = getLine(POSITIVE);//FTP257_PATH_CREATED);
1894:
1895:                if (tmp == null) {
1896:                    return;
1897:                }
1898:
1899:                if (TESTMODE) {
1900:                    tmp = "\"'T759F.'\"";
1901:                }
1902:
1903:                String x1 = tmp;
1904:
1905:                if (x1.indexOf("\"") >= 0) {
1906:                    x1 = tmp.substring(tmp.indexOf("\"") + 1);
1907:                    x1 = x1.substring(0, x1.indexOf("\""));
1908:                }
1909:
1910:                if (getOsType().indexOf("MVS") >= 0) {
1911:                    //if(x1.indexOf("'") == 0) {
1912:                    //        String x2 = x1.substring(1, x1.lastIndexOf("'"));
1913:                    //        x1 = x2;
1914:                    //}
1915:                    Log.out("pwd: " + x1);
1916:                } else if (!x1.endsWith("/")) {
1917:                    x1 = x1 + "/";
1918:                }
1919:
1920:                pwd = x1;
1921:            }
1922:
1923:            /**
1924:             * Change directory unparsed.
1925:             * Use chdir instead if you do not parse the dir correctly...
1926:             *
1927:             * @param dirName The raw directory name
1928:             * @return True if successful, false otherwise
1929:             */
1930:            public boolean chdirRaw(String dirName) {
1931:                jcon.send(CWD + " " + dirName);
1932:
1933:                return success(POSITIVE);//FTP250_COMPLETED);
1934:            }
1935:
1936:            private boolean success(String op) {
1937:                String tmp = getLine(op);
1938:
1939:                if ((tmp != null) && tmp.startsWith(op)) {
1940:                    return true;
1941:                } else {
1942:                    return false;
1943:                }
1944:            }
1945:
1946:            /**
1947:             * Change to the parent of the current working directory.
1948:             * The CDUP command is a special case of CWD, and is included
1949:             * to simplify the implementation of programs for transferring
1950:             * directory trees between operating systems having different
1951:             * syntaxes for naming the parent directory.
1952:             *
1953:             * @return True if successful, false otherwise
1954:             */
1955:            public boolean cdup() {
1956:                jcon.send(CDUP);
1957:
1958:                return success(POSITIVE);//FTP200_OK);
1959:            }
1960:
1961:            /**
1962:             * Create a directory with the given name.
1963:             *
1964:             * @param dirName The name of the directory to create
1965:             * @return True if successful, false otherwise
1966:             */
1967:            public boolean mkdir(String dirName) {
1968:                jcon.send(MKD + " " + dirName);
1969:
1970:                boolean ret = success(POSITIVE); // Filezille server bugfix, was: FTP257_PATH_CREATED);
1971:                Log.out("mkdir(" + dirName + ")  returned: " + ret);
1972:
1973:                //*** Added 03/20/2005
1974:                fireDirectoryUpdate(this );
1975:
1976:                //***	
1977:                return ret;
1978:            }
1979:
1980:            private int negotiatePort() throws IOException {
1981:                String tmp = "";
1982:
1983:                if (Settings.getFtpPasvMode()) {
1984:                    jcon.send(PASV);
1985:
1986:                    tmp = getLine(FTP227_ENTERING_PASSIVE_MODE);
1987:
1988:                    if ((tmp != null) && !tmp.startsWith(NEGATIVE)) {
1989:                        return getPasvPort(tmp);
1990:                    }
1991:                }
1992:
1993:                tmp = getActivePortCmd();
1994:                jcon.send(tmp);
1995:                getLine(FTP200_OK);
1996:
1997:                return getActivePort();
1998:            }
1999:
2000:            /**
2001:             * List remote directory.
2002:             * Note that you have to get the output using the
2003:             * sort*-methods.
2004:             *
2005:             * @param outfile The file to save the output to, usually Settings.ls_out
2006:             */
2007:            public void list() throws IOException {
2008:                String oldType = "";
2009:
2010:                try {
2011:                    BufferedReader in = jcon.getReader();
2012:
2013:                    int p = 0;
2014:
2015:                    modeStream();
2016:
2017:                    oldType = getTypeNow();
2018:                    ascii();
2019:
2020:                    p = negotiatePort();
2021:                    dcon = new DataConnection(this , p, host, null,
2022:                            DataConnection.GET, false, true); //,null);
2023:
2024:                    //System.out.println("2...");
2025:                    while (dcon.getInputStream() == null) {
2026:                        //System.out.print("#");
2027:                        pause(10);
2028:                    }
2029:
2030:                    DataInputStream input = new DataInputStream(dcon
2031:                            .getInputStream());
2032:
2033:                    jcon.send(LIST);
2034:                    getLine(POSITIVE); //FTP226_CLOSING_DATA_REQUEST_SUCCESSFUL);
2035:
2036:                    String line;
2037:                    currentListing.removeAllElements();
2038:
2039:                    while ((line = input.readLine()) != null) {
2040:                        //System.out.println("-> "+line);
2041:                        if (!line.trim().equals("")) {
2042:                            currentListing.add(line);
2043:                        }
2044:                    }
2045:
2046:                    input.close();
2047:
2048:                    //System.out.println("4...");
2049:                    if (!oldType.equals(ASCII)) {
2050:                        type(oldType);
2051:                    }
2052:                } catch (Exception ex) {
2053:                    Log.debug("Cannot list remote directory!");
2054:
2055:                    if (!oldType.equals(ASCII)) {
2056:                        type(oldType);
2057:                    }
2058:
2059:                    ex.printStackTrace();
2060:                    throw new IOException(ex.getMessage());
2061:                }
2062:            }
2063:
2064:            /**
2065:             * Parses directory and does a chdir().
2066:             * Does also fire a directory update event.
2067:             *
2068:             * @return True is successful, false otherwise
2069:             */
2070:            public boolean chdir(String p) {
2071:                //Log.out("Change directory to: "+p);
2072:                String tmpPath = p;
2073:
2074:                boolean tmp = chdirWork(p);
2075:
2076:                if (!tmp) {
2077:                    return false;
2078:                } else {
2079:                    fireDirectoryUpdate(this );
2080:
2081:                    return true;
2082:                }
2083:            }
2084:
2085:            /**
2086:             * Parses directory and does a chdir(), but does not send an update signal
2087:             *
2088:             * @return True is successful, false otherwise
2089:             */
2090:            public boolean chdirNoRefresh(String p) {
2091:                return chdirWork(p);
2092:            }
2093:
2094:            private boolean chdirWork(String p) {
2095:                if (Settings.safeMode) {
2096:                    noop();
2097:                }
2098:
2099:                p = parseSymlinkBack(p);
2100:
2101:                if (getOsType().indexOf("OS/2") >= 0) {
2102:                    return chdirRaw(p);
2103:                } else if (getOsType().indexOf("MVS") >= 0) {
2104:                    boolean cdup = false;
2105:
2106:                    System.out.print("MVS parser: " + p + " -> ");
2107:
2108:                    //TODO: handle relative unix paths
2109:                    if (!getPWD().startsWith("/")) //return chdirRaw(p);
2110:                    {
2111:                        if (p.endsWith("..")) {
2112:                            cdup = true;
2113:                        }
2114:                        //TODO let dirlister form correct syntax
2115:
2116:                        p = p.replaceAll("/", "");
2117:                        boolean ew = p.startsWith("'");
2118:                        String tmp = null;
2119:
2120:                        if (p.startsWith("'") && !p.endsWith("'")) {
2121:                            if (cdup) {
2122:                                p = p.substring(0, p.length() - 4);
2123:                                if (p.indexOf(".") > 0) {
2124:                                    p = p.substring(0, p.lastIndexOf("."));
2125:                                }
2126:                                p += "'";
2127:                            }
2128:
2129:                            tmp = p.substring(0, p.lastIndexOf("'"));
2130:                            p = p.substring(p.lastIndexOf("'") + 1);
2131:                            ew = false;
2132:                        } else if (cdup) {
2133:                            p = p.substring(0, p.length() - 3);
2134:                            if (p.indexOf(".") > 0) {
2135:                                p = p.substring(0, p.lastIndexOf("."));
2136:                            }
2137:                        }
2138:
2139:                        if (p.indexOf(".") > 0 && !ew) {
2140:                            p = p.substring(0, p.indexOf("."));
2141:                        }
2142:
2143:                        if (tmp != null)
2144:                            p = tmp + p + "'";
2145:
2146:                        System.out.println(p);
2147:                        Log.out("MVS parser: " + p);
2148:
2149:                        return chdirRaw(p);
2150:                    }
2151:                }
2152:
2153:                try {
2154:                    // check if we don't have a relative path
2155:                    if (!p.startsWith("/") && !p.startsWith("~")) {
2156:                        p = pwd + p;
2157:                    }
2158:
2159:                    // argh, we should document that!
2160:                    if (p.endsWith("..")) {
2161:                        boolean home = p.startsWith("~");
2162:                        StringTokenizer stok = new StringTokenizer(p, "/");
2163:
2164:                        //System.out.println("path p :"+p +" Tokens: "+stok.countTokens());
2165:                        if (stok.countTokens() > 2) {
2166:                            String pold1 = "";
2167:                            String pold2 = "";
2168:                            String pnew = "";
2169:
2170:                            while (stok.hasMoreTokens()) {
2171:                                pold1 = pold2;
2172:                                pold2 = pnew;
2173:                                pnew = pnew + "/" + stok.nextToken();
2174:                            }
2175:
2176:                            p = pold1;
2177:                        } else {
2178:                            p = "/";
2179:                        }
2180:
2181:                        if (home) {
2182:                            p = p.substring(1);
2183:                        }
2184:                    }
2185:
2186:                    //System.out.println("path: "+p);
2187:                    if (!chdirRaw(p)) {
2188:                        return false;
2189:                    }
2190:                } catch (Exception ex) {
2191:                    Log
2192:                            .debug("(remote) Can not get pathname! " + pwd
2193:                                    + ":" + p);
2194:                    ex.printStackTrace();
2195:
2196:                    return false;
2197:                }
2198:
2199:                //fireDirectoryUpdate(this);
2200:
2201:                // --------------------------------------
2202:                updatePWD();
2203:
2204:                return true;
2205:            }
2206:
2207:            /**
2208:             * Waits a specified amount of time
2209:             *
2210:             * @param time The time to sleep in milliseconds
2211:             */
2212:            public void pause(int time) {
2213:                try {
2214:                    Thread.sleep(time);
2215:                } catch (Exception ex) {
2216:                    ex.printStackTrace();
2217:                }
2218:            }
2219:
2220:            /**
2221:             * Return the local working directory
2222:             *
2223:             * @return The local CWD
2224:             */
2225:            public String getLocalPath() {
2226:                return localPath;
2227:            }
2228:
2229:            /**
2230:             * Set the local working directory
2231:             *
2232:             * @param newPath The new local CWD
2233:             * @return Always true in the current implementation
2234:             */
2235:            public boolean setLocalPath(String newPath) {
2236:                localPath = newPath;
2237:
2238:                if (!localPath.endsWith("/")) {
2239:                    localPath = localPath + "/";
2240:                }
2241:
2242:                return true;
2243:            }
2244:
2245:            /**
2246:             * Checks wheter a file exists.
2247:             *
2248:             * @param file the name of the file
2249:             * @return An int-code: CHDIR_FAILED, PERMISSION_DENIED (no listing allowed), R, W or DENIED
2250:             */
2251:            public int exists(String file) {
2252:                String dir = null;
2253:                String tmpPWD = getCachedPWD();
2254:
2255:                if (file.indexOf("/") >= 0) {
2256:                    dir = file.substring(0, file.lastIndexOf("/") + 1);
2257:                    Log.out("checking dir: " + dir);
2258:
2259:                    if (!chdir(dir)) {
2260:                        return CHDIR_FAILED;
2261:                    }
2262:                }
2263:
2264:                try {
2265:                    list();
2266:                } catch (IOException ex) {
2267:                    ex.printStackTrace();
2268:
2269:                    return PERMISSION_DENIED;
2270:                }
2271:
2272:                String f = file.substring(file.lastIndexOf("/") + 1);
2273:                Log.out("checking file: " + f);
2274:
2275:                String[] files = sortLs();
2276:                int[] perms = getPermissions();
2277:
2278:                int y = -1;
2279:
2280:                for (int x = 0; x < files.length; x++) {
2281:                    if (files[x].equals(f)) {
2282:                        y = x;
2283:
2284:                        break;
2285:                    }
2286:                }
2287:
2288:                if (y == -1) {
2289:                    return FILE_NOT_FOUND;
2290:                }
2291:
2292:                if (dir != null) {
2293:                    chdir(tmpPWD);
2294:                }
2295:
2296:                return perms[y];
2297:            }
2298:
2299:            /** Moves or renames remote file.
2300:             * @param from remote file to move or rename.
2301:             * @param to new file name.
2302:             * @return <code>true</code> if completed successfully; <code>false</code> otherwise.
2303:             */
2304:            public boolean rename(String from, String to) {
2305:                jcon.send("RNFR " + from);
2306:
2307:                if (success(RC350)) {
2308:                    jcon.send("RNTO " + to);
2309:
2310:                    if (success(POSITIVE))//FTP250_COMPLETED))
2311:                    {
2312:                        return true;
2313:                    }
2314:                }
2315:
2316:                return false;
2317:            }
2318:
2319:            /**
2320:             * Get the port.
2321:             *
2322:             * @return The port used by the FTP control connection
2323:             */
2324:            public int getPort() {
2325:                return port;
2326:            }
2327:
2328:            private int getPortA() {
2329:                return porta;
2330:            }
2331:
2332:            private int getPortB() {
2333:                return portb;
2334:            }
2335:
2336:            private void incrementPort() {
2337:                portb++;
2338:            }
2339:
2340:            /*
2341:            private String getActivePortCmd() throws UnknownHostException, IOException
2342:            {
2343:                InetAddress ipaddr = jcon.getLocalAddress();
2344:                String ip = ipaddr.getHostAddress().replace('.', ',');
2345:
2346:                incrementPort();
2347:
2348:                int a = getPortA();
2349:                int b = getPortB();
2350:                String ret = "PORT " + ip + "," + a + "," + b;
2351:
2352:                //System.out.println(ret);
2353:                return ret;
2354:            }
2355:             */
2356:
2357:            private String getActivePortCmd() throws UnknownHostException,
2358:                    IOException {
2359:                InetAddress ipaddr = jcon.getLocalAddress();
2360:                String ip = ipaddr.getHostAddress().replace('.', ',');
2361:
2362:                ServerSocket aSock = new ServerSocket(0);
2363:                int availPort = aSock.getLocalPort();
2364:                aSock.close();
2365:                porta = availPort / 256;
2366:                portb = availPort % 256;
2367:                String ret = "PORT " + ip + "," + porta + "," + portb;
2368:
2369:                //    System.out.println(ret); 
2370:                return ret;
2371:            }
2372:
2373:            /**
2374:             * Tell server we want binary data connections.
2375:             */
2376:            public void binary() { // possible responses 200, 500, 501, 504, 421 and 530
2377:                type(BINARY);
2378:            }
2379:
2380:            /**
2381:             * Tell server we want ascii data connections.
2382:             */
2383:            public void ascii() {
2384:                type(ASCII);
2385:            }
2386:
2387:            /**
2388:             * Set type (L8,I,A for example).
2389:             *
2390:             * @return True if the type was changed successfully, false otherwise
2391:             */
2392:            public boolean type(String code) {
2393:                jcon.send(TYPE + " " + code);
2394:
2395:                String tmp = getLine(POSITIVE);//FTP200_OK);
2396:
2397:                if ((tmp != null) && tmp.startsWith(POSITIVE))//FTP200_OK))
2398:                {
2399:                    typeNow = code;
2400:
2401:                    return true;
2402:                }
2403:
2404:                return false;
2405:            }
2406:
2407:            /**
2408:             * Returns the type used.
2409:             *
2410:             * @return The type String, I, A, L8 for example
2411:             */
2412:            public String getTypeNow() {
2413:                return typeNow;
2414:            }
2415:
2416:            /**
2417:             * Do nothing, but flush buffers
2418:             */
2419:            public void noop() {
2420:                jcon.send(NOOP);
2421:                getLine(POSITIVE);//FTP200_OK);
2422:            }
2423:
2424:            /**
2425:             * Try to abort the transfer.
2426:             */
2427:            public void abort() {
2428:                jcon.send(ABOR);
2429:                getLine(POSITIVE); // 226
2430:            }
2431:
2432:            /**
2433:             * This command is used to find out the type of operating
2434:             * system at the server. The reply shall have as its first
2435:             * word one of the system names listed in the current version
2436:             * of the Assigned Numbers document (RFC 943).
2437:             *
2438:             * @return The server response of the SYST command
2439:             */
2440:            public String system() { // possible responses 215, 500, 501, 502, and 421
2441:                jcon.send(SYST);
2442:
2443:                String response = getLine(POSITIVE);//FTP215_SYSTEM_TYPE);
2444:
2445:                if (response != null) {
2446:                    //StringTokenizer st = new StringTokenizer(response);
2447:                    //if (st.countTokens() >= 2)
2448:                    //{
2449:                    //     st.nextToken();
2450:                    //     String os = st.nextToken();
2451:                    //     setOsType(os);
2452:                    //}
2453:                    setOsType(response);
2454:                } else {
2455:                    setOsType("UNIX");
2456:                }
2457:
2458:                return response;
2459:            }
2460:
2461:            /**
2462:             * Set mode to Stream.
2463:             * Used internally.
2464:             */
2465:            public void modeStream() {
2466:                if (useStream && !modeStreamSet) {
2467:                    String ret = mode(STREAM);
2468:
2469:                    if ((ret != null) && ret.startsWith(NEGATIVE)) {
2470:                        useStream = false;
2471:                    } else {
2472:                        modeStreamSet = true;
2473:                    }
2474:                }
2475:            }
2476:
2477:            /**
2478:             * Unsupported at this time.
2479:             */
2480:            public void modeBlocked() {
2481:                if (useBlocked) {
2482:                    if (mode(BLOCKED).startsWith(NEGATIVE)) {
2483:                        useBlocked = false;
2484:                    }
2485:                }
2486:            }
2487:
2488:            /*
2489:             * Unsupported at this time.
2490:             */
2491:            public void modeCompressed() {
2492:                if (useCompressed) {
2493:                    if (mode(COMPRESSED).startsWith(NEGATIVE)) {
2494:                        useCompressed = false;
2495:                    }
2496:                }
2497:            }
2498:
2499:            /**
2500:             * Set mode manually.
2501:             *
2502:             * @param code The mode code wanted, I, A, L8 for example
2503:             * @return The server's response to the request
2504:             */
2505:            public String mode(String code) {
2506:                jcon.send(MODE + " " + code);
2507:
2508:                String ret = "";
2509:
2510:                try {
2511:                    ret = getLine(POSITIVE);//FTP200_OK);
2512:                } catch (Exception ex) {
2513:                    ex.printStackTrace();
2514:                }
2515:
2516:                return ret;
2517:            }
2518:
2519:            /**
2520:             * Return the host used.
2521:             *
2522:             * @return The remote host of this connection
2523:             */
2524:            public String getHost() {
2525:                return host;
2526:            }
2527:
2528:            /**
2529:             * Return the username.
2530:             *
2531:             * @return The username used by this connection
2532:             */
2533:            public String getUsername() {
2534:                return username;
2535:            }
2536:
2537:            /**
2538:             * Return the password.
2539:             *
2540:             * @return The password used by this connection
2541:             */
2542:            public String getPassword() {
2543:                return password;
2544:            }
2545:
2546:            /**
2547:             * Return the DataConnection.
2548:             * Should be necessary only for complex actions.
2549:             *
2550:             * @return The DataConnection object currently used by this conenction
2551:             */
2552:            public DataConnection getDataConnection() {
2553:                return dcon;
2554:            }
2555:
2556:            /**
2557:             * Add a ConnectionListener.
2558:             * The Listener is notified about transfers and the connection state.
2559:             * @param l A ConnectionListener object
2560:             */
2561:            public void addConnectionListener(ConnectionListener l) {
2562:                listeners.add(l);
2563:            }
2564:
2565:            /**
2566:             * Add a Vector of ConnectionListeners.
2567:             * Each Listener is notified about transfers and the connection state.
2568:             *
2569:             * @param l A Vector containig ConnectionListener objects
2570:             */
2571:            public void setConnectionListeners(Vector l) {
2572:                listeners = l;
2573:            }
2574:
2575:            /**
2576:             * Remote directory has changed.
2577:             *
2578:             * @param con The FtpConnection calling the event
2579:             */
2580:            public void fireDirectoryUpdate(FtpConnection con) {
2581:                if (listeners == null) {
2582:                    return;
2583:                } else {
2584:                    for (int i = 0; i < listeners.size(); i++) {
2585:                        ((ConnectionListener) listeners.elementAt(i))
2586:                                .updateRemoteDirectory(con);
2587:                    }
2588:                }
2589:            }
2590:
2591:            /**
2592:             * Progress update.
2593:             * The transfer is active and makes progress, so a signal is send
2594:             * each few kb.
2595:             *
2596:             * @param file The file transferred
2597:             * @param type the type of event, DataConnection.GETDIR for example
2598:             * @param bytes The number of bytes transferred so far
2599:             */
2600:            public void fireProgressUpdate(String file, String type, int bytes) {
2601:                //System.out.println(listener);
2602:                if (listeners == null) {
2603:                    return;
2604:                } else {
2605:                    for (int i = 0; i < listeners.size(); i++) {
2606:                        ConnectionListener listener = (ConnectionListener) listeners
2607:                                .elementAt(i);
2608:
2609:                        if (shortProgress && Settings.shortProgress) {
2610:                            if (type.startsWith(DataConnection.DFINISHED)) {
2611:                                listener.updateProgress(baseFile,
2612:                                        DataConnection.DFINISHED + ":"
2613:                                                + fileCount, bytes);
2614:                            } else if (isDirUpload) {
2615:                                listener
2616:                                        .updateProgress(baseFile,
2617:                                                DataConnection.PUTDIR + ":"
2618:                                                        + fileCount, bytes);
2619:                            } else {
2620:                                listener
2621:                                        .updateProgress(baseFile,
2622:                                                DataConnection.GETDIR + ":"
2623:                                                        + fileCount, bytes);
2624:                            }
2625:                        } else {
2626:                            listener.updateProgress(file, type, bytes);
2627:                        }
2628:                    }
2629:                }
2630:            }
2631:
2632:            /**
2633:             * Connection is there and user logged in
2634:             *
2635:             * @param con The FtpConnection calling the event
2636:             */
2637:            public void fireConnectionInitialized(FtpConnection con) {
2638:                if (listeners == null) {
2639:                    return;
2640:                } else {
2641:                    for (int i = 0; i < listeners.size(); i++) {
2642:                        ((ConnectionListener) listeners.elementAt(i))
2643:                                .connectionInitialized(con);
2644:                    }
2645:                }
2646:            }
2647:
2648:            /**
2649:             * We are not logged in for some reason
2650:             *
2651:             * @param con The FtpConnection calling the event
2652:             * @param why The login() response code
2653:             */
2654:            public void fireConnectionFailed(FtpConnection con, String why) {
2655:                if (listeners == null) {
2656:                    return;
2657:                } else {
2658:                    for (int i = 0; i < listeners.size(); i++) {
2659:                        ((ConnectionListener) listeners.elementAt(i))
2660:                                .connectionFailed(con, why);
2661:                    }
2662:                }
2663:            }
2664:
2665:            /**
2666:             * Transfer is done
2667:             *
2668:             * @param con The FtpConnection calling the event
2669:             */
2670:            public void fireActionFinished(FtpConnection con) {
2671:                if (listeners == null) {
2672:                    return;
2673:                } else {
2674:                    for (int i = 0; i < listeners.size(); i++) {
2675:                        ((ConnectionListener) listeners.elementAt(i))
2676:                                .actionFinished(con);
2677:                    }
2678:                }
2679:            }
2680:
2681:            /**
2682:             * Return the ConnectionHandler.
2683:             *
2684:             * @return The connection handler of this instance
2685:             */
2686:            public ConnectionHandler getConnectionHandler() {
2687:                return handler;
2688:            }
2689:
2690:            /**
2691:             * Set the ConnectionHandler.
2692:             *
2693:             * @param h The connection handler that is to be used by this connection
2694:             */
2695:            public void setConnectionHandler(ConnectionHandler h) {
2696:                handler = h;
2697:            }
2698:
2699:            /**
2700:             * Get the last FtpTransfer object spawned.
2701:             *
2702:             */
2703:            public FtpTransfer getLastInitiatedTransfer() {
2704:                return lastTransfer;
2705:            }
2706:
2707:            /**
2708:             * Abort the last spawned transfer.
2709:             *
2710:             */
2711:            public void abortTransfer() {
2712:                try {
2713:                    DataConnection dcon = lastTransfer.getDataConnection();
2714:
2715:                    if (dcon == null) {
2716:                        Log.out("nothing to abort");
2717:
2718:                        return;
2719:                    }
2720:
2721:                    dcon.getCon().work = false;
2722:                    dcon.sock.close();
2723:                } catch (Exception ex) {
2724:                    Log.debug("Exception during abort: " + ex.toString());
2725:                    ex.printStackTrace();
2726:                }
2727:            }
2728:
2729:            public Date[] sortDates() {
2730:                if (dateVector.size() > 0) {
2731:                    return (Date[]) dateVector.toArray();
2732:                } else {
2733:                    return null;
2734:                }
2735:            }
2736:
2737:            public String getCRLF() {
2738:                return crlf;
2739:            }
2740:
2741:            public BufferedReader getIn() {
2742:                return in;
2743:            }
2744:
2745:            public void setIn(BufferedReader in) {
2746:                this .in = in;
2747:            }
2748:
2749:            public BufferedReader getCommandInputReader() {
2750:                return jcon.getIn();
2751:            }
2752:
2753:            public OutputStream getCommandOutputStream() {
2754:                return jcon.getOut();
2755:            }
2756:
2757:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.