1 16 package net.sf.jftp.net; 17 18 19 import java.io.BufferedReader ; 21 import java.io.DataInputStream ; 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.io.OutputStream ; 26 import java.net.InetAddress ; 27 import java.net.ServerSocket ; 28 import java.net.UnknownHostException ; 29 import java.util.Date ; 30 import java.util.StringTokenizer ; 31 import java.util.Vector ; 32 33 import javax.swing.JLabel ; 34 import javax.swing.JOptionPane ; 35 36 import net.sf.jftp.config.LoadSet; 37 import net.sf.jftp.config.SaveSet; 38 import net.sf.jftp.config.Settings; 39 import net.sf.jftp.system.StringUtils; 40 import net.sf.jftp.system.logging.Log; 41 42 43 52 public class FtpConnection implements BasicConnection, FtpConstants 53 { 54 private static final boolean TESTMODE = false; 55 56 private final static String NEGATIVE = "5"; 59 private final static String NEGATIVE2 = "4"; 60 61 private final static String POSITIVE = "2"; 64 65 private final static String PROCEED = "3"; private final static char MORE_LINES_APPENDED = '-'; 68 69 70 public final static String DOWNLOAD = "DOWNLOAD"; 71 72 73 public final static String UPLOAD = "UPLOAD"; 74 75 76 public final static String ABOR = "ABOR"; 77 78 public static String LIST_DEFAULT = "LIST -laL"; 82 public static String LIST = "default"; 83 public final static String ASCII = "A"; 84 public final static String BINARY = "I"; 85 public final static String EBCDIC = "E"; 86 public final static String L8 = "L 8"; 87 public final static String STREAM = "S"; 88 public final static String BLOCKED = "B"; 89 public final static String COMPRESSED = "C"; 90 private static boolean useStream = true; 91 private static boolean useBlocked = true; 92 private static boolean useCompressed = true; 93 94 private static int porta = 5; private static int portb = 1; 97 98 100 103 public boolean hasUploaded = false; 104 public boolean work = true; 105 private boolean msg = true; 106 private boolean ok = true; 107 private String pwd = ""; 108 private String initCWD = Settings.defaultDir; 109 private String [] loginAck = new String [] 110 { 111 FTP331_USER_OK_NEED_PASSWORD, 112 FTP230_LOGGED_IN 113 }; 114 private String osType = ""; 115 private String dataType; 116 private FtpTransfer lastTransfer = null; 117 private boolean modeStreamSet = false; 118 private DataConnection dcon = null; 119 private Vector listeners = new Vector (); 120 private ConnectionHandler handler = new ConnectionHandler(); 121 122 private String localPath = null; 124 125 126 private String host = ""; 127 128 129 private String username; 130 131 132 private String password; 133 134 135 private int port = 21; 136 137 138 private BufferedReader in; 139 140 141 private JConnection jcon; 142 143 144 private boolean connected = false; 145 private boolean shortProgress = false; 146 private boolean isDirUpload = false; 147 private String baseFile; 148 private int fileCount; 149 private String typeNow = ""; 150 private String crlf = null; 151 152 155 public Vector dateVector = new Vector (); 156 public Vector currentListing = new Vector (); 157 public Vector currentFiles = new Vector (); 158 public Vector currentSizes = new Vector (); 159 public Vector currentPerms = new Vector (); 160 161 166 public FtpConnection(String host) 167 { 168 this.host = host; 169 170 File f = new File ("."); 171 setLocalPath(f.getAbsolutePath()); 172 } 173 174 181 public FtpConnection(String host, int port, String initCWD) 182 { 183 this.host = host; 184 this.port = port; 185 this.initCWD = initCWD; 186 187 File f = new File ("."); 188 setLocalPath(f.getAbsolutePath()); 189 } 190 191 203 public FtpConnection(String host, int port, String initCWD, String crlfx) 204 { 205 this.host = host; 206 this.port = port; 207 this.initCWD = initCWD; 208 209 if(crlfx != null) { 210 if(crlfx.equals("\n") || crlfx.equals("\r") || crlfx.equals("\r\n")) this.crlf = crlfx; 211 crlfx = crlfx.trim().toUpperCase(); 212 if(crlfx.equals("LF")) this.crlf = "\n"; 213 else if(crlfx.equals("CR")) this.crlf = "\r"; 214 else if(crlfx.equals("CRLF")) this.crlf = "\r\n"; 215 } 216 218 File f = new File ("."); 219 setLocalPath(f.getAbsolutePath()); 220 } 221 222 232 public int login(String username, String password) 233 { 234 this.username = username; 235 this.password = password; 236 237 int status = LOGIN_OK; 238 239 if(msg) 240 { 241 Log.debug("Connecting to " + host); 242 } 243 244 jcon = new JConnection(host, port); 245 246 if(jcon.isThere()) 247 { 248 in = jcon.getReader(); 249 250 if(getLine(POSITIVE) == null) { 252 ok = false; 253 Log.debug("Server closed Connection, maybe too many users..."); 254 status = OFFLINE; 255 } 256 257 if(msg) 258 { 259 Log.debug("Connection established..."); 260 } 261 262 jcon.send(USER + " " + username); 263 264 if(!getLine(loginAck).startsWith(POSITIVE)) { 266 jcon.send(PASS + " " + password); 267 268 if(success(POSITIVE)) { 270 if(msg) 271 { 272 Log.debug("Logged in..."); 273 } 274 } 275 else 276 { 277 Log.debug("Wrong password!"); 278 ok = false; 279 status = WRONG_LOGIN_DATA; 280 } 281 } 282 283 } 285 else 286 { 287 if(msg) 288 { 289 Log.debug("FTP not available!"); 290 ok = false; 291 status = GENERIC_FAILED; 292 } 293 } 294 295 if(ok) 296 { 297 connected = true; 298 system(); 299 300 binary(); 302 303 if(initCWD.trim().equals(Settings.defaultDir) || 304 !chdirNoRefresh(initCWD)) 305 { 306 updatePWD(); 316 } 317 318 String [] advSettings = new String [6]; 321 322 if(getOsType().indexOf("OS/2") >= 0) 323 { 324 LIST_DEFAULT = "LIST"; 325 } 326 327 if(LIST.equals("default")) 328 { 329 advSettings = LoadSet.loadSet(Settings.adv_settings); 332 333 if(advSettings == null) 335 { 336 LIST = LIST_DEFAULT; 337 338 SaveSet s = new SaveSet(Settings.adv_settings, LIST); 339 } 340 else 341 { 342 LIST = advSettings[0]; 343 344 if(LIST == null) 345 { 346 LIST = LIST_DEFAULT; 347 } 348 } 349 } 350 351 if(getOsType().indexOf("MVS") >= 0) 352 { 353 LIST = "LIST"; 354 } 355 356 fireDirectoryUpdate(this); 358 fireConnectionInitialized(this); 359 } 360 else 361 { 362 fireConnectionFailed(this, new Integer (status).toString()); 363 } 364 365 return status; 366 } 367 368 375 public String [] sortSize() 376 { 377 try 378 { 379 currentSizes.removeAllElements(); 380 381 for(int i=0; i<currentListing.size(); i++) 382 { 383 String tmp = (String ) currentListing.get(i); 384 385 if(getOsType().indexOf("VMS") >= 0) 387 { 388 if(tmp.indexOf(";") < 0) 389 { 390 continue; 391 } 392 393 currentSizes.add("-1"); 394 395 continue; 396 } 397 398 if(getOsType().indexOf("MVS") >= 0) 400 { 401 if(tmp.startsWith("Volume") || (tmp.indexOf(" ") < 0)) 402 { 403 continue; 404 } 405 406 currentSizes.add("-1"); 407 408 continue; 409 } 410 411 else if(getOsType().indexOf("WINDOW") >= 0) 413 { 414 StringTokenizer to = new StringTokenizer (tmp, " ", false); 415 416 if(to.countTokens() >= 4) 417 { 418 to.nextToken(); 419 to.nextToken(); 420 421 String size = to.nextToken(); 422 423 if(size.equals("<DIR>")) 424 { 425 currentSizes.add("0"); 426 } 427 else 428 { 429 try 430 { 431 Long.parseLong(size); 432 currentSizes.add(size); 433 } 434 catch(Exception ex) 435 { 436 currentSizes.add("-1"); 437 Log.out("WARNING: filesize can not be determined - value is " + 438 size); 439 } 440 } 441 } 442 } 443 444 else if(getOsType().indexOf("OS/2") >= 0) 446 { 447 StringTokenizer to = new StringTokenizer (tmp, " ", false); 448 tmp = giveSize(to, 0); 449 Log.out("OS/2 parser (size): " + tmp); 450 currentSizes.add(tmp); 451 } 452 else 453 { 454 StringTokenizer to = new StringTokenizer (tmp, " ", false); 456 457 if(to.countTokens() >= 8) { 459 tmp = giveSize(to, 4); 460 currentSizes.add(tmp); 461 462 } 464 else if(to.countTokens() == 7) { 466 Log.out("WARNING: 7 token backup size parser activated!"); 467 tmp = giveSize(to, 4); 468 currentSizes.add(tmp); 469 } 470 else 471 { 472 Log.debug("cannot parse line: " + tmp); 473 } 474 } 475 } 476 } 477 catch(Exception ex) 478 { 479 Log.debug(ex.toString() + " @FtpConnection::sortSize#1"); 480 return new String [0]; 481 } 482 483 return toArray(currentSizes); 484 } 485 486 private String [] toArray(Vector in) { 487 String ret[] = new String [in.size()]; 488 489 for(int i=0; i<in.size(); i++) { 490 ret[i] = (String ) in.get(i); 491 } 492 493 return ret; 494 } 495 496 504 public int[] getPermissions() 505 { 506 try 507 { 508 currentPerms.removeAllElements(); 509 510 for(int i=0; i<currentListing.size(); i++) 511 { 512 String tmp = (String ) currentListing.get(i); 513 514 if(getOsType().indexOf("VMS") >= 0) 516 { 517 if(tmp.indexOf(";") < 0) 518 { 519 continue; 520 } 521 522 currentPerms.add("r"); 523 524 continue; 525 } 526 527 if(getOsType().indexOf("MVS") >= 0) 529 { 530 if(tmp.startsWith("Volume")) 531 { 532 continue; 533 } 534 535 currentPerms.add("r"); 536 537 continue; 538 } 539 540 542 StringTokenizer to = new StringTokenizer (tmp.trim(), " ", false); 543 544 if(!(to.countTokens() > 3) || 545 (tmp.startsWith("/") && (tmp.indexOf("denied") > 0))) 546 { 547 continue; 548 } 549 550 tmp = to.nextToken(); 551 552 if(tmp.length() != 10) 553 { 554 return null; } 557 558 char ur = tmp.charAt(1); 559 char uw = tmp.charAt(2); 560 char ar = tmp.charAt(7); 561 char aw = tmp.charAt(8); 562 563 to.nextToken(); 564 565 String user = to.nextToken(); 566 567 if(aw == 'w') 569 { 570 currentPerms.add("w"); 571 } 572 else if(user.equals(username) && (uw == 'w')) 573 { 574 currentPerms.add("w"); 575 } 576 else if(ar == 'r') 577 { 578 currentPerms.add("r"); 579 } 580 else if(user.equals(username) && (ur == 'r')) 581 { 582 currentPerms.add("r"); 583 } 584 else 585 { 586 currentPerms.add("n"); 588 } 589 } 590 } 591 catch(Exception ex) 592 { 593 Log.debug(ex.toString() + " @FtpConnection::getPermissions#1"); 594 } 595 596 int[] ret = new int[currentPerms.size()]; 597 598 for(int i=0; i<currentPerms.size(); i++) { 599 String fx = (String ) currentPerms.get(i); 600 601 if(fx.equals("w")) 602 { 603 ret[i] = W; 604 } 605 else if(fx.equals("n")) 606 { 607 ret[i] = DENIED; 608 } 609 else 610 { 611 ret[i] = R; 612 } 613 } 615 616 return ret; 617 } 618 619 626 public String [] sortLs() 627 { 628 try 629 { 630 boolean newUnixDateStyle = false; 631 dateVector = new Vector (); 632 currentFiles.removeAllElements(); 633 634 for(int i=0; i<currentListing.size(); i++) 635 { 636 String tmp = (String ) currentListing.get(i); 637 638 if(getOsType().indexOf("VMS") >= 0) 640 { 641 int x = tmp.indexOf(";"); 642 643 if(x < 0) 644 { 645 continue; 646 } 647 648 tmp = tmp.substring(0, x); 649 650 if(tmp.endsWith("DIR")) 651 { 652 currentFiles.add(tmp.substring(0, tmp.lastIndexOf(".")) + 653 "/"); 654 } 655 else 656 { 657 currentFiles.add(tmp); 658 } 659 660 662 continue; 663 } 664 else if(getOsType().indexOf("OS/2") >= 0) 665 { 666 StringTokenizer to2 = new StringTokenizer (tmp, " ", true); 667 668 if(giveFile(to2, 2).indexOf("DIR") >= 0) 669 { 670 to2 = new StringTokenizer (tmp, " ", true); 671 tmp = giveFile(to2, 5); 672 tmp = tmp + "/"; 673 } 674 else 675 { 676 to2 = new StringTokenizer (tmp, " ", true); 677 678 if(giveFile(to2, 1).indexOf("DIR") >= 0) 679 { 680 to2 = new StringTokenizer (tmp, " ", true); 682 tmp = giveFile(to2, 4); 683 tmp = tmp + "/"; 684 } 685 else 686 { 687 to2 = new StringTokenizer (tmp, " ", true); 688 tmp = giveFile(to2, 4); 689 } 690 } 691 692 Log.out("OS/2 parser: " + tmp); 693 currentFiles.add(tmp); 694 695 continue; 696 } 697 698 if(getOsType().indexOf("MVS") >= 0) 701 { 702 if(tmp.startsWith("Volume") || (tmp.indexOf(" ") < 0)) 703 { 704 Log.out("->" + tmp); 705 706 continue; 707 } 708 709 String f = tmp.substring(tmp.lastIndexOf(" ")).trim(); 710 String isDir = tmp.substring(tmp.lastIndexOf(" ") - 5, 711 tmp.lastIndexOf(" ")); 712 713 if(isDir.indexOf("PO") >= 0) 714 { 715 currentFiles.add(f + "/"); 716 } 717 else 718 { 719 currentFiles.add(f); 720 } 721 722 Log.out("listing - (mvs parser): " + tmp + " -> " + f); 723 continue; 724 } 725 else if(getOsType().indexOf("OS/2") >= 0) 726 { 727 StringTokenizer to2 = new StringTokenizer (tmp, " ", true); 728 729 if(giveFile(to2, 2).indexOf("DIR") >= 0) 730 { 731 to2 = new StringTokenizer (tmp, " ", true); 732 tmp = giveFile(to2, 5); 733 tmp = tmp + "/"; 734 } 735 else 736 { 737 to2 = new StringTokenizer (tmp, " ", true); 738 739 if(giveFile(to2, 1).indexOf("DIR") >= 0) 740 { 741 to2 = new StringTokenizer (tmp, " ", true); 743 tmp = giveFile(to2, 4); 744 tmp = tmp + "/"; 745 } 746 else 747 { 748 to2 = new StringTokenizer (tmp, " ", true); 749 tmp = giveFile(to2, 4); 750 } 751 } 752 753 Log.out("OS/2 parser: " + tmp); 754 currentFiles.add(tmp); 755 756 continue; 757 } 758 759 boolean isDir = false; 762 boolean isLink = false; 763 764 if(tmp.startsWith("d") || (tmp.indexOf("<DIR>") >= 0)) 765 { 766 isDir = true; 767 } 768 769 if(tmp.startsWith("l")) 770 { 771 isLink = true; 772 } 773 774 if(tmp.startsWith("/") && (tmp.indexOf("denied") > 0)) 775 { 776 continue; 777 } 778 779 StringTokenizer to = new StringTokenizer (tmp, " ", false); 780 StringTokenizer to2 = new StringTokenizer (tmp, " ", true); 781 782 int tokens = to.countTokens(); 783 784 boolean set = false; 786 787 int lcount = 0; 789 790 if(!newUnixDateStyle) 791 { 792 try 793 { 794 StringTokenizer tx = new StringTokenizer (tmp, " ", false); 795 tx.nextToken(); 796 tx.nextToken(); 797 tx.nextToken(); 798 tx.nextToken(); 799 tx.nextToken(); 800 801 String date = tx.nextToken(); 802 int x = date.indexOf("-"); 803 int y = date.lastIndexOf("-"); 804 805 if(y > x) 806 { 807 Log.debug("Using new Unix date parser"); 808 newUnixDateStyle = true; 809 } 810 } 811 catch(Exception ex) 812 { 813 Log.out("could not preparse line: " + tmp); 814 lcount++; 815 816 } 818 } 819 820 if(newUnixDateStyle) { 824 set = true; 825 826 try 829 { 830 StringTokenizer to3 = new StringTokenizer (tmp, " ", true); 832 String date = giveFile(to3, 5); 833 String date2 = date.substring(date.indexOf("-") + 1); 834 date2 = date2.substring(date.indexOf("-") + 2); 835 836 String t = date; 838 String y = t.substring(0, t.indexOf("-")); 839 String m = t.substring(t.indexOf("-") + 1, 840 t.indexOf("-") + 3); 841 String m1 = t.substring(t.indexOf("-") + 1); 842 String day = m1.substring(m1.indexOf("-") + 1, 843 m1.indexOf("-") + 3); 844 String h = date2.substring(0, date2.indexOf(":")); 845 String min = date2.substring(date2.indexOf(":") + 1, 846 date2.indexOf(":") + 3); 847 848 Date d = new Date (); 850 d.setDate(Integer.parseInt(day)); 851 d.setYear(Integer.parseInt(y)); 852 d.setMonth(Integer.parseInt(m) - 1); 853 d.setHours(Integer.parseInt(h)); 854 d.setMinutes(Integer.parseInt(min)); 855 856 dateVector.add(d); 857 858 } 860 catch(Exception ex) 861 { 862 ex.printStackTrace(); 863 864 } 866 867 tmp = giveFile(to2, 7); 869 870 if(lcount > 1) 871 { 872 dateVector = new Vector (); 873 } 874 } 875 else if(tokens > 8) { 877 set = true; 878 tmp = giveFile(to2, 8); 879 880 } 882 else if(tokens > 3) { 884 set = true; 885 tmp = giveFile(to2, 3); 886 887 if(tmp.startsWith("<error>")) 888 { 889 tmp = giveFile(to2, 4); 890 891 } 893 else 894 { 895 } 897 } 898 899 if(tmp.startsWith("<error>") || !set) 900 { 901 if(tokens < 3) 902 { 903 continue; 904 } 905 906 tmp = giveFile(to2, tokens); 907 Log.out("listing - WARNING: listing style unknown, using last token as filename!"); 908 Log.out("listing - this may work but may also fail, filesizes and permissions will probably fail, too..."); 909 Log.out("listing - please send us a feature request with the serveraddress to let us support this listing style :)"); 910 Log.out("listing - (backup parser, token " + tokens + 911 " ): " + tmp); 912 } 913 914 if(isDir) 915 { 916 tmp = tmp + "/"; 917 } 918 else if(isLink) 919 { 920 tmp = tmp + "###"; 921 } 922 923 currentFiles.add(tmp); 924 } 926 927 String [] files = toArray(currentFiles); 928 929 for(int i = 0; i < files.length; i++) 930 { 931 files[i] = parseSymlink(files[i]); 932 933 } 936 937 return files; 938 } 939 catch(Exception ex) 940 { 941 Log.debug(ex.toString() + " @FtpConnection::sortLs"); 942 ex.printStackTrace(); 943 } 944 945 947 954 955 return new String [0]; 957 } 958 959 960 private String giveFile(StringTokenizer to, int lev) 961 { 962 String t2 = null; 963 964 for(int i = 0; i < lev; i++) 965 { 966 if(to.hasMoreTokens()) 967 { 968 String t = to.nextToken(); 969 970 if(t.equals(" ") || t.equals("\t")) 972 { 973 975 982 i--; 983 } 984 } 985 } 986 987 String tmp = "<error>"; 988 989 995 while(tmp.equals(" ") || tmp.equals("\t") || tmp.equals("<error>")) 996 { 997 if(to.hasMoreTokens()) 998 { 999 tmp = to.nextToken(); 1000 } 1001 else 1002 { 1003 break; 1004 } 1005 } 1006 1007 while(to.hasMoreTokens()) 1008 { 1009 tmp = tmp + to.nextToken(); 1010 } 1011 1012 return tmp; 1014 } 1015 1016 1017 private String giveSize(StringTokenizer to, int lev) 1018 { 1019 for(int i = 0; i < lev; i++) 1020 { 1021 if(to.hasMoreTokens()) 1022 { 1023 if(to.nextToken().equals(" ")) 1024 { 1025 i--; 1026 } 1027 } 1028 } 1029 1030 while(to.hasMoreTokens()) 1031 { 1032 String tmp = to.nextToken(); 1033 1034 if(!tmp.equals(" ")) 1035 { 1036 try 1037 { 1038 Integer.parseInt(tmp); 1039 } 1040 catch(NumberFormatException ex) 1041 { 1042 return "-1"; 1043 } 1044 1045 return tmp; 1046 } 1047 } 1048 1049 return "-2"; 1050 } 1051 1052 1058 public String getOsType() 1059 { 1060 if(TESTMODE) 1061 { 1062 return "MVS"; 1063 } 1064 else 1065 { 1066 return osType; 1067 } 1068 } 1069 1070 private void setOsType(String os) 1071 { 1072 osType = os.toUpperCase(); 1073 } 1074 1075 private int getPasvPort(String str) 1076 { 1077 int start = str.lastIndexOf(","); 1078 String lo = ""; 1079 start++; 1080 1081 while(start < str.length()) 1082 { 1083 char c = str.charAt(start); 1084 1085 if(!Character.isDigit(c)) 1086 { 1087 break; 1088 } 1089 1090 lo = lo + c; 1091 start++; 1092 } 1093 1094 System.out.println("\n\n\n"+str); 1095 1096 String hi = ""; 1097 start = str.lastIndexOf(","); 1098 start--; 1099 1100 while(true) 1101 { 1102 char c = str.charAt(start); 1103 1104 if(!Character.isDigit(c)) 1105 { 1106 break; 1107 } 1108 1109 hi = c + hi; 1110 start--; 1111 } 1112 1113 return ((Integer.parseInt(hi) * 256) + Integer.parseInt(lo)); 1115 } 1116 1117 private int getActivePort() 1118 { 1119 return (getPortA() * 256) + getPortB(); 1120 } 1121 1122 1123 private String parseSymlink(String file) 1124 { 1125 if(file.indexOf("->") >= 0) 1126 { 1127 file = file.substring(0, file.indexOf("->")).trim(); 1129 file = file + "###"; 1130 1131 } 1133 1134 return file; 1135 } 1136 1137 1138 private String parseSymlinkBack(String file) 1139 { 1140 if(file.indexOf("->") >= 0) 1141 { 1142 file = file.substring(file.indexOf("->") + 2).trim(); 1144 1145 } 1147 1148 return file; 1149 } 1150 1151 1152 private boolean isSymlink(String file) 1153 { 1154 if(file.indexOf("->") >= 0) 1155 { 1156 return true; 1157 } 1158 1159 return false; 1160 } 1161 1162 1168 public int handleDownload(String file) 1169 { 1170 if(Settings.getEnableMultiThreading()) 1171 { 1172 Log.out("spawning new thread for this download."); 1173 1174 FtpTransfer t = new FtpTransfer(host, port, getLocalPath(), 1175 getCachedPWD(), file, username, 1176 password, Transfer.DOWNLOAD, 1177 handler, listeners, crlf); 1178 lastTransfer = t; 1179 1180 return NEW_TRANSFER_SPAWNED; 1181 } 1182 else 1183 { 1184 Log.out("multithreading is completely disabled."); 1185 1186 return download(file); 1187 } 1188 } 1189 1190 1196 public int download(String file) 1197 { 1198 1200 int stat; 1201 1202 if(file.endsWith("/")) 1203 { 1204 shortProgress = true; 1205 fileCount = 0; 1206 baseFile = file; 1207 dataType = DataConnection.GETDIR; 1208 1209 stat = downloadDir(file); 1210 1211 fireActionFinished(this); 1213 fireProgressUpdate(baseFile, 1214 DataConnection.DFINISHED + ":" + fileCount, -1); 1215 shortProgress = false; 1216 } 1217 else 1218 { 1219 dataType = DataConnection.GET; 1220 1221 stat = rawDownload(file); 1222 1223 if(Settings.enableFtpDelays) { 1224 try 1225 { 1226 Thread.sleep(100); 1227 } catch(Exception ex) {} 1228 } 1229 1230 fireActionFinished(this); 1231 } 1232 1233 if(Settings.enableFtpDelays) { 1234 try 1235 { 1236 Thread.sleep(400); 1237 } 1238 catch(Exception ex) 1239 { 1240 } 1241 } 1242 1243 return stat; 1244 } 1245 1246 1252 public InputStream getDownloadInputStream(String file) 1253 { 1254 Log.out("ftp stream download started:" + this); 1255 file = parse(file); 1256 1257 try 1258 { 1259 int p = 0; 1260 dataType = DataConnection.GET; 1261 file = StringUtils.getFile(file); 1262 1263 String path = getLocalPath() + file; 1264 1265 BufferedReader in = jcon.getReader(); 1266 1267 modeStream(); 1268 p = negotiatePort(); 1269 1270 dcon = new DataConnection(this, p, host, path, dataType, false, true); 1271 1272 while(!dcon.isThere()) 1273 { 1274 pause(10); 1275 } 1276 1277 jcon.send(RETR + " " + file); 1278 1279 return dcon.getInputStream(); 1280 } 1281 catch(Exception ex) 1282 { 1283 ex.printStackTrace(); 1284 Log.debug(ex.toString() + 1285 " @FtpConnection::getDownloadInputStream"); 1286 1287 return null; 1288 } 1289 } 1290 1291 private int rawDownload(String file) 1292 { 1293 file = parse(file); 1294 1295 try 1297 { 1298 int p = 0; 1299 1300 file = StringUtils.getFile(file); 1302 1303 String path = getLocalPath() + file; 1304 1305 modeStream(); 1308 1309 p = negotiatePort(); 1311 1312 File f = new File (path); 1313 1314 boolean resume = false; 1316 1317 if(f.exists() && Settings.enableResuming) 1318 { 1319 jcon.send(REST + " " + f.length()); 1320 1321 if(getLine(PROCEED) != null) 1322 { 1323 resume = true; 1324 } 1325 } 1326 1327 dcon = new DataConnection(this, p, host, path, dataType, resume); 1329 while(!dcon.isThere()) 1330 { 1331 pause(10); 1332 } 1333 1334 jcon.send(RETR + " " + file); 1335 1336 String line = getLine(POSITIVE); 1337 Log.debug(line); 1338 1339 if(line.startsWith(NEGATIVE)) 1341 { 1342 File f2 = new File (path); 1343 1344 if(f2.exists() && (f2.length() == 0)) 1345 { 1346 f2.delete(); 1347 } 1348 1349 return PERMISSION_DENIED; 1350 } 1351 else if(!line.startsWith(POSITIVE) && !line.startsWith(PROCEED)) 1352 { 1353 return TRANSFER_FAILED; 1354 } 1355 1356 while(!dcon.finished) 1359 { 1360 pause(10); 1361 } 1362 } 1363 catch(Exception ex) 1364 { 1365 ex.printStackTrace(); 1366 Log.debug(ex.toString() + " @FtpConnection::download"); 1367 1368 return TRANSFER_FAILED; 1369 } 1370 1371 return TRANSFER_SUCCESSFUL; 1372 } 1373 1374 private int downloadDir(String dir) 1375 { 1376 if(!dir.endsWith("/")) 1377 { 1378 dir = dir + "/"; 1379 } 1380 1381 if(StringUtils.isRelative(dir)) 1382 { 1383 dir = getCachedPWD() + dir; 1384 } 1385 1386 String path = getLocalPath() + StringUtils.getDir(dir); 1387 1388 String pwd = getCachedPWD() + StringUtils.getDir(dir); 1390 1391 String oldDir = getLocalPath(); 1392 String oldPwd = getCachedPWD(); 1393 1394 File f = new File (path); 1395 1396 if(!f.exists()) 1397 { 1398 if(!f.mkdir()) 1399 { 1400 Log.debug("Can't create directory: " + dir); 1401 } 1402 else 1403 { 1404 Log.debug("Created directory..."); 1405 } 1406 } 1407 1408 setLocalPath(path); 1409 1410 if(!chdirNoRefresh(pwd)) 1411 { 1412 return CHDIR_FAILED; 1413 } 1414 1415 try 1416 { 1417 list(); 1418 } 1419 catch(IOException ex) 1420 { 1421 return PERMISSION_DENIED; 1422 } 1423 1424 String [] tmp = sortLs(); 1425 1426 setLocalPath(path); 1427 1428 for(int i = 0; i < tmp.length; i++) 1429 { 1430 if(tmp[i].endsWith("/")) 1431 { 1432 if(tmp[i].trim().equals("../") || tmp[i].trim().equals("./")) 1433 { 1434 Log.debug("Skipping " + tmp[i].trim()); 1435 } 1436 else 1437 { 1438 if(!work) 1439 { 1440 return TRANSFER_STOPPED; 1441 } 1442 1443 if(downloadDir(tmp[i]) < 0) 1444 { 1445 ; } 1447 } 1448 } 1449 else 1450 { 1451 if(!work) 1453 { 1454 return TRANSFER_STOPPED; 1455 } 1456 1457 fileCount++; 1458 1459 if(rawDownload(getLocalPath() + tmp[i]) < 0) 1460 { 1461 ; } 1463 } 1464 } 1465 1466 chdirNoRefresh(oldPwd); 1467 setLocalPath(oldDir); 1468 1469 return TRANSFER_SUCCESSFUL; 1470 } 1471 1472 1478 public int handleUpload(String file) 1479 { 1480 return handleUpload(file, null); 1481 } 1482 1483 1490 public int handleUpload(String file, String realName) 1491 { 1492 if(Settings.getEnableMultiThreading() && 1493 (!Settings.getNoUploadMultiThreading())) 1494 { 1495 Log.out("spawning new thread for this upload."); 1496 1497 FtpTransfer t; 1498 1499 if(realName != null) 1500 { 1501 t = new FtpTransfer(host, port, getLocalPath(), getCachedPWD(), 1502 file, username, password, Transfer.UPLOAD, 1503 handler, listeners, realName, crlf); 1504 } 1505 else 1506 { 1507 t = new FtpTransfer(host, port, getLocalPath(), getCachedPWD(), 1508 file, username, password, Transfer.UPLOAD, 1509 handler, listeners, crlf); 1510 } 1511 1512 lastTransfer = t; 1513 1514 return NEW_TRANSFER_SPAWNED; 1515 } 1516 else 1517 { 1518 if(Settings.getNoUploadMultiThreading()) 1519 { 1520 Log.out("upload multithreading is disabled."); 1521 } 1522 else 1523 { 1524 Log.out("multithreading is completely disabled."); 1525 } 1526 1527 return (realName == null) ? upload(file) : upload(file, realName); 1528 } 1529 } 1530 1531 1537 public int upload(String file) 1538 { 1539 return upload(file, file); 1540 } 1541 1542 1550 public int upload(String file, String realName) 1551 { 1552 return upload(file, realName, null); 1553 } 1554 1555 1562 public int upload(String file, InputStream in) 1563 { 1564 return upload(file, file, in); 1565 } 1566 1567 1576 public int upload(String file, String realName, InputStream in) 1577 { 1578 hasUploaded = true; 1579 Log.out("ftp upload started: " + this); 1580 1581 int stat; 1582 1583 if((in == null) && new File (file).isDirectory()) 1584 { 1585 shortProgress = true; 1586 fileCount = 0; 1587 baseFile = file; 1588 dataType = DataConnection.PUTDIR; 1589 isDirUpload = true; 1590 1591 stat = uploadDir(file); 1592 1593 shortProgress = false; 1594 1595 fireProgressUpdate(baseFile, 1597 DataConnection.DFINISHED + ":" + fileCount, -1); 1598 1599 fireActionFinished(this); 1600 fireDirectoryUpdate(this); 1601 } 1602 else 1603 { 1604 dataType = DataConnection.PUT; 1605 stat = rawUpload(file, realName, in); 1606 1607 try 1608 { 1609 Thread.sleep(100); 1610 } 1611 catch(Exception ex) 1612 { 1613 } 1614 1615 fireActionFinished(this); 1616 fireDirectoryUpdate(this); 1617 } 1618 1619 try 1620 { 1621 Thread.sleep(500); 1622 } 1623 catch(Exception ex) 1624 { 1625 } 1626 1627 return stat; 1628 } 1629 1630 private int rawUpload(String file) 1631 { 1632 return rawUpload(file, file); 1633 } 1634 1635 private int rawUpload(String file, String realName) 1636 { 1637 return rawUpload(file, realName, null); 1638 } 1639 1640 1641 private int rawUpload(String file, String realName, InputStream in) 1642 { 1643 if(!file.equals(realName)) 1644 { 1645 Log.debug("File: " + file + ", stored as " + realName); 1646 } 1647 else 1648 { 1649 Log.debug("File: " + file); 1650 realName = null; 1651 } 1652 1653 file = parse(file); 1654 1655 String path = file; 1656 1657 try 1658 { 1659 int p = 0; 1660 1661 if(StringUtils.isRelative(file)) 1662 { 1663 path = getLocalPath() + file; 1664 } 1665 1666 file = StringUtils.getFile(file); 1667 1668 boolean resume = false; 1670 String size = "0"; 1671 1672 if(Settings.enableUploadResuming && (in == null)) 1673 { 1674 list(); 1675 1676 String [] ls = sortLs(); 1677 String [] sizes = sortSize(); 1678 1679 if((ls == null) || (sizes == null)) 1680 { 1681 Log.out(">>> ls out of sync (skipping resume check)"); 1682 } 1683 else 1684 { 1685 for(int i = 0; i < ls.length; i++) 1686 { 1687 if(realName != null) 1689 { 1690 if(ls[i].equals(realName)) 1691 { 1692 resume = true; 1693 size = sizes[i]; 1694 1695 break; 1696 } 1697 } 1698 else 1699 { 1700 if(ls[i].equals(file)) 1701 { 1702 resume = true; 1703 size = sizes[i]; 1704 } 1705 } 1706 } 1707 1708 File f = new File (path); 1709 1710 if(f.exists() && (f.length() <= Integer.parseInt(size))) 1711 { 1712 Log.out("skipping resuming, file is <= filelength"); 1713 resume = false; 1714 } 1715 else if(f.exists() && Integer.parseInt(size) > 0) 1716 { 1717 if(!Settings.noUploadResumingQuestion) { 1718 if(JOptionPane.showConfirmDialog(new JLabel (), "A file smaller than the one to be uploaded already exists on the server,\n do you want to resume the upload?", "Resume upload?", JOptionPane.YES_NO_OPTION) 1719 != JOptionPane.OK_OPTION) { 1720 resume = false; 1721 } 1722 } 1723 Log.out("resume: " + resume + ", size: " + size); 1724 } 1725 else { 1726 Log.out("resume: " + resume + ", size: " + size); 1727 } 1728 } 1729 } 1730 1731 modeStream(); 1732 1733 p = negotiatePort(); 1735 1736 if(resume && Settings.enableUploadResuming) 1737 { 1738 jcon.send(REST + " " + size); 1739 1740 if(getLine(PROCEED) == null) 1741 { 1742 resume = false; 1743 } 1744 } 1745 1746 dcon = new DataConnection(this, p, host, path, dataType, resume, 1747 Integer.parseInt(size), in); 1749 while(!dcon.isThere()) 1750 { 1751 pause(10); 1752 } 1753 1754 if(realName != null) 1756 { 1757 jcon.send(STOR + " " + realName); 1758 } 1759 else 1760 { 1761 jcon.send(STOR + " " + file); 1762 } 1763 1764 String tmp = getLine(POSITIVE); 1765 1766 if(!tmp.startsWith(POSITIVE) && !tmp.startsWith(PROCEED)) 1767 { 1768 return TRANSFER_FAILED; 1769 } 1770 1771 Log.debug(tmp); 1772 1773 while(!dcon.finished) 1776 { 1777 pause(10); 1778 } 1779 } 1780 catch(Exception ex) 1781 { 1782 ex.printStackTrace(); 1783 Log.debug(ex.toString() + " @FtpConnection::upload"); 1784 1785 return TRANSFER_FAILED; 1786 } 1787 1788 return TRANSFER_SUCCESSFUL; 1789 } 1790 1791 private int uploadDir(String dir) 1792 { 1793 if(dir.endsWith("\\")) 1795 { 1796 System.out.println("Something's wrong with the selected directory - please report this bug!"); 1797 } 1798 1799 if(!dir.endsWith("/")) 1800 { 1801 dir = dir + "/"; 1802 } 1803 1804 if(StringUtils.isRelative(dir)) 1805 { 1806 dir = getLocalPath() + dir; 1807 } 1808 1809 String single = StringUtils.getDir(dir); 1810 String path = dir.substring(0, dir.indexOf(single)); 1811 1812 String remoteDir = getCachedPWD() + single; String oldDir = getCachedPWD(); 1814 1815 if(Settings.safeMode) 1816 { 1817 noop(); 1818 } 1819 1820 boolean successful = mkdir(remoteDir); 1821 1822 if(!successful) 1823 { 1824 return MKDIR_FAILED; 1825 } 1826 1827 if(Settings.safeMode) 1828 { 1829 noop(); 1830 } 1831 1832 chdirNoRefresh(remoteDir); 1833 1834 File f2 = new File (dir); 1835 String [] tmp = f2.list(); 1836 1837 for(int i = 0; i < tmp.length; i++) 1838 { 1839 String res = dir + tmp[i]; 1840 File f3 = new File (res); 1841 1842 if(f3.isDirectory()) 1843 { 1844 if(!work) 1845 { 1846 return TRANSFER_STOPPED; 1847 } 1848 1849 uploadDir(res); 1850 } 1851 else 1852 { 1853 if(!work) 1856 { 1857 return TRANSFER_STOPPED; 1858 } 1859 1860 fileCount++; 1861 1862 if(rawUpload(res) < 0) 1863 { 1864 ; } 1866 } 1867 } 1868 1869 chdirNoRefresh(oldDir); 1870 1871 return TRANSFER_SUCCESSFUL; 1872 } 1873 1874 private String parse(String file) 1875 { 1876 file = parseSymlink(file); 1877 1878 return file; 1879 } 1880 1881 1882 private int cleanDir(String dir, String path) 1883 { 1884 if(dir.equals("")) 1885 { 1886 return 0; 1887 } 1888 1889 if(!dir.endsWith("/")) 1890 { 1891 dir = dir + "/"; 1892 } 1893 1894 String remoteDir = StringUtils.removeStart(dir, path); 1895 1896 String oldDir = pwd; 1897 chdirNoRefresh(pwd + remoteDir); 1898 1899 try 1900 { 1901 list(); 1902 } 1903 catch(IOException ex) 1904 { 1905 return PERMISSION_DENIED; 1907 } 1908 1909 String [] tmp = sortLs(); 1910 chdirNoRefresh(oldDir); 1911 1912 if(tmp == null) 1913 { 1914 return GENERIC_FAILED; 1915 } 1916 1917 for(int i = 0; i < tmp.length; i++) 1918 { 1919 Log.out("cleanDir: " + tmp); 1920 1921 if(isSymlink(tmp[i])) 1922 { 1923 Log.debug("WARNING: Skipping symlink, remove failed."); 1924 Log.debug("This is necessary to prevent possible data loss when removing those symlinks."); 1925 1926 tmp[i] = null; 1927 } 1928 1929 if(tmp[i] != null) 1930 { 1931 tmp[i] = parseSymlink(tmp[i]); 1932 } 1933 1934 if((tmp[i] == null) || tmp[i].equals("./") || tmp[i].equals("../")) 1935 { 1936 continue; 1938 } 1939 1940 if(tmp[i].endsWith("/")) 1943 { 1944 cleanDir(dir + tmp[i], path); 1946 1947 int x = removeFileOrDir(dir + tmp[i]); 1948 1949 if(x < 0) 1950 { 1951 return x; 1952 } 1953 } 1954 else 1955 { 1956 int x = removeFileOrDir(dir + tmp[i]); 1958 1959 if(x < 0) 1960 { 1961 return x; 1962 } 1963 } 1964 } 1965 1966 return REMOVE_SUCCESSFUL; 1967 } 1968 1969 1975 public int removeFileOrDir(String file) 1976 { 1977 if(file == null) 1978 { 1979 return 0; 1980 } 1981 1982 if(file.trim().equals(".") || file.trim().equals("..")) 1983 { 1984 Log.debug("ERROR: Catching attempt to delete . or .. directories"); 1985 1986 return GENERIC_FAILED; 1987 } 1988 1989 if(isSymlink(file)) 1990 { 1991 Log.debug("WARNING: Skipping symlink, remove failed."); 1992 Log.debug("This is necessary to prevent possible data loss when removing those symlinks."); 1993 1994 return REMOVE_FAILED; 1995 } 1996 1997 file = parseSymlink(file); 1998 1999 if(file.endsWith("/")) 2000 { 2001 int ret = cleanDir(file, getCachedPWD()); 2002 2003 if(ret < 0) 2004 { 2005 return ret; 2006 } 2007 2008 jcon.send(RMD + " " + file); 2009 } 2010 else 2011 { 2012 jcon.send(DELE + " " + file); 2013 } 2014 2015 if(success(POSITIVE)) { 2017 return REMOVE_SUCCESSFUL; 2018 } 2019 else 2020 { 2021 return REMOVE_FAILED; 2022 } 2023 } 2024 2025 2031 public void disconnect() 2032 { 2033 jcon.send(QUIT); 2034 getLine(POSITIVE); connected = false; 2036 } 2037 2038 2044 public void sendRawCommand(String cmd) 2045 { 2046 noop(); 2047 Log.clearCache(); 2048 jcon.send(cmd); 2049 noop(); 2050 } 2051 2052 2058 public String getLine(String until) 2059 { 2060 return getLine(new String [] { until }); 2061 } 2062 2063 2067 public String getLine(String [] until) 2068 { 2069 BufferedReader in = null; 2070 2071 try 2072 { 2073 in = jcon.getReader(); 2074 } 2075 catch(Exception ex) 2076 { 2077 Log.debug(ex.toString() + " @FtpConnection::getLine"); 2078 } 2079 2080 String tmp; 2082 2083 while(true) 2084 { 2085 try 2086 { 2087 tmp = in.readLine(); 2088 2089 if(tmp == null) 2090 { 2091 break; 2092 } 2093 2094 Log.debug(tmp); 2095 2096 if(((tmp.startsWith(NEGATIVE) || (tmp.startsWith(NEGATIVE2))) && 2097 (tmp.charAt(3) != MORE_LINES_APPENDED)) || 2098 tmp.startsWith(PROCEED)) 2099 { 2100 return tmp; 2101 } 2102 else 2103 { 2104 for(int i = 0; i < until.length; i++) 2105 { 2106 if(tmp.startsWith(until[i])) 2107 { 2108 if(tmp.charAt(3) != MORE_LINES_APPENDED) 2111 { 2112 return tmp; 2113 } 2114 } 2115 } 2116 } 2117 } 2118 catch(Exception ex) 2119 { 2120 Log.debug(ex.toString() + " @FtpConnection::getLine"); 2121 2122 break; 2123 } 2124 } 2125 2126 return null; 2127 } 2128 2129 2134 public boolean isConnected() 2135 { 2136 return connected; 2137 } 2138 2139 2144 public String getPWD() 2145 { 2146 if(connected) 2147 { 2148 updatePWD(); 2149 } 2150 2151 if(TESTMODE) 2152 { 2153 return "HUGO.user."; 2154 } 2155 2156 return pwd; 2157 } 2158 2159 2164 public String getCachedPWD() 2165 { 2166 return pwd; 2167 } 2168 2169 2172 private void updatePWD() 2173 { 2174 jcon.send(PWD); 2175 2176 String tmp = getLine(POSITIVE); 2178 if(tmp == null) 2179 { 2180 return; 2181 } 2182 2183 if(TESTMODE) 2184 { 2185 tmp = "\"'T759F.'\""; 2186 } 2187 2188 String x1 = tmp; 2189 2190 if(x1.indexOf("\"") >= 0) { 2191 x1 = tmp.substring(tmp.indexOf("\"") + 1); 2192 x1 = x1.substring(0, x1.indexOf("\"")); 2193 } 2194 2195 if(getOsType().indexOf("MVS") >= 0) 2196 { 2197 Log.out("pwd: " + x1); 2202 } 2203 else if(!x1.endsWith("/")) 2204 { 2205 x1 = x1 + "/"; 2206 } 2207 2208 pwd = x1; 2209 } 2210 2211 2218 public boolean chdirRaw(String dirName) 2219 { 2220 jcon.send(CWD + " " + dirName); 2221 2222 return success(POSITIVE); } 2224 2225 private boolean success(String op) 2226 { 2227 String tmp = getLine(op); 2228 2229 if((tmp != null) && tmp.startsWith(op)) 2230 { 2231 return true; 2232 } 2233 else 2234 { 2235 return false; 2236 } 2237 } 2238 2239 2248 public boolean cdup() 2249 { 2250 jcon.send(CDUP); 2251 2252 return success(POSITIVE); } 2254 2255 2261 public boolean mkdir(String dirName) 2262 { 2263 jcon.send(MKD + " " + dirName); 2264 2265 boolean ret = success(POSITIVE); Log.out("mkdir(" + dirName + ") returned: " + ret); 2267 2268 fireDirectoryUpdate(this); 2270 2271 return ret; 2273 } 2274 2275 private int negotiatePort() throws IOException 2276 { 2277 String tmp = ""; 2278 2279 if(Settings.getFtpPasvMode()) 2280 { 2281 jcon.send(PASV); 2282 2283 tmp = getLine(FTP227_ENTERING_PASSIVE_MODE); 2284 2285 if((tmp != null) && !tmp.startsWith(NEGATIVE)) 2286 { 2287 return getPasvPort(tmp); 2288 } 2289 } 2290 2291 tmp = getActivePortCmd(); 2292 jcon.send(tmp); 2293 getLine(FTP200_OK); 2294 2295 return getActivePort(); 2296 } 2297 2298 2305 public void list() throws IOException 2306 { 2307 String oldType = ""; 2308 2309 try 2310 { 2311 BufferedReader in = jcon.getReader(); 2312 2313 int p = 0; 2314 2315 modeStream(); 2316 2317 oldType = getTypeNow(); 2318 ascii(); 2319 2320 p = negotiatePort(); 2321 dcon = new DataConnection(this, p, host, null, DataConnection.GET, false, true); 2323 while(dcon.getInputStream() == null) 2325 { 2326 pause(10); 2328 } 2329 2330 DataInputStream input = new DataInputStream (dcon.getInputStream()); 2331 2332 jcon.send(LIST); 2333 getLine(POSITIVE); 2335 String line; 2336 currentListing.removeAllElements(); 2337 2338 while((line = input.readLine()) != null) { 2339 if(!line.trim().equals("")) { 2341 currentListing.add(line); 2342 } 2343 } 2344 2345 input.close(); 2346 2347 if(!oldType.equals(ASCII)) 2349 { 2350 type(oldType); 2351 } 2352 } 2353 catch(Exception ex) 2354 { 2355 Log.debug("Cannot list remote directory!"); 2356 2357 if(!oldType.equals(ASCII)) 2358 { 2359 type(oldType); 2360 } 2361 2362 ex.printStackTrace(); 2363 throw new IOException (ex.getMessage()); 2364 } 2365 } 2366 2367 2373 public boolean chdir(String p) 2374 { 2375 String tmpPath = p; 2377 2378 boolean tmp = chdirWork(p); 2379 2380 if(!tmp) 2381 { 2382 return false; 2383 } 2384 else 2385 { 2386 fireDirectoryUpdate(this); 2387 2388 return true; 2389 } 2390 } 2391 2392 2397 public boolean chdirNoRefresh(String p) 2398 { 2399 return chdirWork(p); 2400 } 2401 2402 private boolean chdirWork(String p) 2403 { 2404 if(Settings.safeMode) 2405 { 2406 noop(); 2407 } 2408 2409 p = parseSymlinkBack(p); 2410 2411 if(getOsType().indexOf("OS/2") >= 0) 2412 { 2413 return chdirRaw(p); 2414 } 2415 else if(getOsType().indexOf("MVS") >= 0) 2416 { 2417 boolean cdup = false; 2418 2419 System.out.print("MVS parser: "+p+" -> "); 2420 2421 if(!getPWD().startsWith("/")) { 2424 if(p.endsWith("..")) { 2425 cdup = true; 2426 } 2427 2429 p = p.replaceAll("/", ""); 2430 boolean ew = p.startsWith("'"); 2431 String tmp = null; 2432 2433 if(p.startsWith("'") && !p.endsWith("'")) 2434 { 2435 if(cdup){ 2436 p = p.substring(0,p.length()-4); 2437 if(p.indexOf(".") > 0) { 2438 p = p.substring(0,p.lastIndexOf(".")); 2439 } 2440 p += "'"; 2441 } 2442 2443 tmp = p.substring(0, p.lastIndexOf("'")); 2444 p = p.substring(p.lastIndexOf("'")+1); 2445 ew = false; 2446 } 2447 else if(cdup){ 2448 p = p.substring(0,p.length()-3); 2449 if(p.indexOf(".") > 0) { 2450 p = p.substring(0,p.lastIndexOf(".")); 2451 } 2452 } 2453 2454 if(p.indexOf(".") > 0 && !ew) 2455 { 2456 p = p.substring(0, p.indexOf(".")); 2457 } 2458 2459 if(tmp != null) p = tmp+p+"'"; 2460 2461 System.out.println(p); 2462 Log.out("MVS parser: " + p); 2463 2464 return chdirRaw(p); 2465 } 2466 } 2467 2468 try 2469 { 2470 if(!p.startsWith("/") && !p.startsWith("~")) 2472 { 2473 p = pwd + p; 2474 } 2475 2476 if(p.endsWith("..")) 2478 { 2479 boolean home = p.startsWith("~"); 2480 StringTokenizer stok = new StringTokenizer (p, "/"); 2481 2482 if(stok.countTokens() > 2) 2484 { 2485 String pold1 = ""; 2486 String pold2 = ""; 2487 String pnew = ""; 2488 2489 while(stok.hasMoreTokens()) 2490 { 2491 pold1 = pold2; 2492 pold2 = pnew; 2493 pnew = pnew + "/" + stok.nextToken(); 2494 } 2495 2496 p = pold1; 2497 } 2498 else 2499 { 2500 p = "/"; 2501 } 2502 2503 if(home) 2504 { 2505 p = p.substring(1); 2506 } 2507 } 2508 2509 if(!chdirRaw(p)) 2511 { 2512 return false; 2513 } 2514 } 2515 catch(Exception ex) 2516 { 2517 Log.debug("(remote) Can not get pathname! " + pwd + ":" + p); 2518 ex.printStackTrace(); 2519 2520 return false; 2521 } 2522 2523 2525 updatePWD(); 2527 2528 2529 return true; 2530 } 2531 2532 2537 public void pause(int time) 2538 { 2539 try 2540 { 2541 Thread.sleep(time); 2542 } 2543 catch(Exception ex) 2544 { 2545 ex.printStackTrace(); 2546 } 2547 } 2548 2549 2554 public String getLocalPath() 2555 { 2556 return localPath; 2557 } 2558 2559 2565 public boolean setLocalPath(String newPath) 2566 { 2567 localPath = newPath; 2568 2569 if(!localPath.endsWith("/")) 2570 { 2571 localPath = localPath + "/"; 2572 } 2573 2574 return true; 2575 } 2576 2577 2583 public int exists(String file) 2584 { 2585 String dir = null; 2586 String tmpPWD = getCachedPWD(); 2587 2588 if(file.indexOf("/") >= 0) 2589 { 2590 dir = file.substring(0, file.lastIndexOf("/") + 1); 2591 Log.out("checking dir: " + dir); 2592 2593 if(!chdir(dir)) 2594 { 2595 return CHDIR_FAILED; 2596 } 2597 } 2598 2599 try 2600 { 2601 list(); 2602 } 2603 catch(IOException ex) 2604 { 2605 ex.printStackTrace(); 2606 2607 return PERMISSION_DENIED; 2608 } 2609 2610 String f = file.substring(file.lastIndexOf("/") + 1); 2611 Log.out("checking file: " + f); 2612 2613 String [] files = sortLs(); 2614 int[] perms = getPermissions(); 2615 2616 int y = -1; 2617 2618 for(int x = 0; x < files.length; x++) 2619 { 2620 if(files[x].equals(f)) 2621 { 2622 y = x; 2623 2624 break; 2625 } 2626 } 2627 2628 if(y == -1) 2629 { 2630 return FILE_NOT_FOUND; 2631 } 2632 2633 if(dir != null) 2634 { 2635 chdir(tmpPWD); 2636 } 2637 2638 return perms[y]; 2639 } 2640 2641 2646 public boolean rename(String from, String to) 2647 { 2648 jcon.send("RNFR " + from); 2649 2650 if(success(RC350)) 2651 { 2652 jcon.send("RNTO " + to); 2653 2654 if(success(POSITIVE)) { 2656 return true; 2657 } 2658 } 2659 2660 return false; 2661 } 2662 2663 2668 public int getPort() 2669 { 2670 return port; 2671 } 2672 2673 private int getPortA() 2674 { 2675 return porta; 2676 } 2677 2678 private int getPortB() 2679 { 2680 return portb; 2681 } 2682 2683 private void incrementPort() 2684 { 2685 portb++; 2686 } 2687 2688 2704 2705 private String getActivePortCmd() throws UnknownHostException , IOException 2706 { 2707 InetAddress ipaddr = jcon.getLocalAddress(); 2708 String ip = ipaddr.getHostAddress().replace('.', ','); 2709 2710 ServerSocket aSock = new ServerSocket (0); 2711 int availPort = aSock.getLocalPort(); 2712 aSock.close(); 2713 porta = availPort/256; 2714 portb = availPort%256; 2715 String ret = "PORT " + ip + "," + porta + "," + portb; 2716 2717 return ret; 2719 } 2720 2721 2724 public void binary() 2725 { type(BINARY); 2727 } 2728 2729 2732 public void ascii() 2733 { 2734 type(ASCII); 2735 } 2736 2737 2742 public boolean type(String code) 2743 { 2744 jcon.send(TYPE + " " + code); 2745 2746 String tmp = getLine(POSITIVE); 2748 if((tmp != null) && tmp.startsWith(POSITIVE)) { 2750 typeNow = code; 2751 2752 return true; 2753 } 2754 2755 return false; 2756 } 2757 2758 2763 public String getTypeNow() 2764 { 2765 return typeNow; 2766 } 2767 2768 2771 public void noop() 2772 { 2773 jcon.send(NOOP); 2774 getLine(POSITIVE); } 2776 2777 2780 public void abort() 2781 { 2782 jcon.send(ABOR); 2783 getLine(POSITIVE); } 2785 2786 2794 public String system() 2795 { jcon.send(SYST); 2797 2798 String response = getLine(POSITIVE); 2800 if(response != null) 2801 { 2802 setOsType(response); 2810 } 2811 else 2812 { 2813 setOsType("UNIX"); 2814 } 2815 2816 return response; 2817 } 2818 2819 2823 public void modeStream() 2824 { 2825 if(useStream && !modeStreamSet) 2826 { 2827 String ret = mode(STREAM); 2828 2829 if((ret != null) && ret.startsWith(NEGATIVE)) 2830 { 2831 useStream = false; 2832 } 2833 else 2834 { 2835 modeStreamSet = true; 2836 } 2837 } 2838 } 2839 2840 2843 public void modeBlocked() 2844 { 2845 if(useBlocked) 2846 { 2847 if(mode(BLOCKED).startsWith(NEGATIVE)) 2848 { 2849 useBlocked = false; 2850 } 2851 } 2852 } 2853 2854 2857 public void modeCompressed() 2858 { 2859 if(useCompressed) 2860 { 2861 if(mode(COMPRESSED).startsWith(NEGATIVE)) 2862 { 2863 useCompressed = false; 2864 } 2865 } 2866 } 2867 2868 2874 public String mode(String code) 2875 { 2876 jcon.send(MODE + " " + code); 2877 2878 String ret = ""; 2879 2880 try 2881 { 2882 ret = getLine(POSITIVE); } 2884 catch(Exception ex) 2885 { 2886 ex.printStackTrace(); 2887 } 2888 2889 return ret; 2890 } 2891 2892 2897 public String getHost() 2898 { 2899 return host; 2900 } 2901 2902 2907 public String getUsername() 2908 { 2909 return username; 2910 } 2911 2912 2917 public String getPassword() 2918 { 2919 return password; 2920 } 2921 2922 2928 public DataConnection getDataConnection() 2929 { 2930 return dcon; 2931 } 2932 2933 2938 public void addConnectionListener(ConnectionListener l) 2939 { 2940 listeners.add(l); 2941 } 2942 2943 2949 public void setConnectionListeners(Vector l) 2950 { 2951 listeners = l; 2952 } 2953 2954 2959 public void fireDirectoryUpdate(FtpConnection con) 2960 { 2961 if(listeners == null) 2962 { 2963 return; 2964 } 2965 else 2966 { 2967 for(int i = 0; i < listeners.size(); i++) 2968 { 2969 ((ConnectionListener) listeners.elementAt(i)).updateRemoteDirectory(con); 2970 } 2971 } 2972 } 2973 2974 2983 public void fireProgressUpdate(String file, String type, int bytes) 2984 { 2985 if(listeners == null) 2987 { 2988 return; 2989 } 2990 else 2991 { 2992 for(int i = 0; i < listeners.size(); i++) 2993 { 2994 ConnectionListener listener = (ConnectionListener) listeners.elementAt(i); 2995 2996 if(shortProgress && Settings.shortProgress) 2997 { 2998 if(type.startsWith(DataConnection.DFINISHED)) 2999 { 3000 listener.updateProgress(baseFile, 3001 DataConnection.DFINISHED + ":" + 3002 fileCount, bytes); 3003 } 3004 else if(isDirUpload) 3005 { 3006 listener.updateProgress(baseFile, 3007 DataConnection.PUTDIR + ":" + 3008 fileCount, bytes); 3009 } 3010 else 3011 { 3012 listener.updateProgress(baseFile, 3013 DataConnection.GETDIR + ":" + 3014 fileCount, bytes); 3015 } 3016 } 3017 else 3018 { 3019 listener.updateProgress(file, type, bytes); 3020 } 3021 } 3022 } 3023 } 3024 3025 3030 public void fireConnectionInitialized(FtpConnection con) 3031 { 3032 if(listeners == null) 3033 { 3034 return; 3035 } 3036 else 3037 { 3038 for(int i = 0; i < listeners.size(); i++) 3039 { 3040 ((ConnectionListener) listeners.elementAt(i)).connectionInitialized(con); 3041 } 3042 } 3043 } 3044 3045 3051 public void fireConnectionFailed(FtpConnection con, String why) 3052 { 3053 if(listeners == null) 3054 { 3055 return; 3056 } 3057 else 3058 { 3059 for(int i = 0; i < listeners.size(); i++) 3060 { 3061 ((ConnectionListener) listeners.elementAt(i)).connectionFailed(con, 3062 why); 3063 } 3064 } 3065 } 3066 3067 3072 public void fireActionFinished(FtpConnection con) 3073 { 3074 if(listeners == null) 3075 { 3076 return; 3077 } 3078 else 3079 { 3080 for(int i = 0; i < listeners.size(); i++) 3081 { 3082 ((ConnectionListener) listeners.elementAt(i)).actionFinished(con); 3083 } 3084 } 3085 } 3086 3087 3092 public ConnectionHandler getConnectionHandler() 3093 { 3094 return handler; 3095 } 3096 3097 3102 public void setConnectionHandler(ConnectionHandler h) 3103 { 3104 handler = h; 3105 } 3106 3107 3111 public FtpTransfer getLastInitiatedTransfer() 3112 { 3113 return lastTransfer; 3114 } 3115 3116 3120 public void abortTransfer() 3121 { 3122 try 3123 { 3124 DataConnection dcon = lastTransfer.getDataConnection(); 3125 3126 if(dcon == null) 3127 { 3128 Log.out("nothing to abort"); 3129 3130 return; 3131 } 3132 3133 dcon.getCon().work = false; 3134 dcon.sock.close(); 3135 } 3136 catch(Exception ex) 3137 { 3138 Log.debug("Exception during abort: " + ex.toString()); 3139 ex.printStackTrace(); 3140 } 3141 } 3142 3143 public Date [] sortDates() 3144 { 3145 if(dateVector.size() > 0) 3146 { 3147 return (Date []) dateVector.toArray(); 3148 } 3149 else 3150 { 3151 return null; 3152 } 3153 } 3154 3155 public String getCRLF() { 3156 return crlf; 3157 } 3158 3159 public BufferedReader getIn() { 3160 return in; 3161 } 3162 3163 public void setIn(BufferedReader in) { 3164 this.in = in; 3165 } 3166 3167 public BufferedReader getCommandInputReader() { 3168 return jcon.getIn(); 3169 } 3170 3171 public OutputStream getCommandOutputStream() { 3172 return jcon.getOut(); 3173 } 3174 3175} 3176 | Popular Tags |