1 16 package net.sf.jftp.net; 17 18 import java.io.BufferedInputStream ; 19 import java.io.BufferedOutputStream ; 20 import java.io.File ; 21 import java.io.FileOutputStream ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.io.RandomAccessFile ; 25 import java.io.StreamTokenizer ; 26 import java.net.ServerSocket ; 27 import java.net.Socket ; 28 29 import net.sf.jftp.config.Settings; 30 import net.sf.jftp.system.logging.Log; 31 32 33 37 public class DataConnection implements Runnable 38 { 39 public final static String GET = "GET"; 40 public final static String PUT = "PUT"; 41 public final static String FAILED = "FAILED"; 42 public final static String FINISHED = "FINISHED"; 43 public final static String DFINISHED = "DFINISHED"; 44 public final static String GETDIR = "DGET"; 45 public final static String PUTDIR = "DPUT"; 46 47 private BufferedInputStream in = null; 48 private BufferedOutputStream out = null; 49 private Thread reciever; 50 private int port = 7000; 51 public Socket sock = null; 52 private ServerSocket ssock = null; 53 private String type; 54 private String file; 55 private String host; 56 private boolean resume = false; 57 public boolean finished = false; 58 private boolean isThere = false; 59 private long start; 60 private FtpConnection con; 61 private int skiplen = 0; 62 private boolean justStream = false; 63 private boolean ok = true; 64 private String localfile = null; 65 private String newLine = null; 67 private String LINEEND = System.getProperty("line.separator"); 68 69 public DataConnection(FtpConnection con, int port, String host, 70 String file, String type) 71 { 72 this.con = con; 73 this.file = file; 74 this.host = host; 75 this.port = port; 76 this.type = type; 77 reciever = new Thread (this); 78 reciever.start(); 79 } 80 81 public DataConnection(FtpConnection con, int port, String host, 82 String file, String type, boolean resume) 83 { 84 this.con = con; 85 this.file = file; 86 this.host = host; 87 this.port = port; 88 this.type = type; 89 this.resume = resume; 90 91 reciever = new Thread (this); 93 reciever.start(); 94 } 95 96 public DataConnection(FtpConnection con, int port, String host, 97 String file, String type, boolean resume, 98 boolean justStream) 99 { 100 this.con = con; 101 this.file = file; 102 this.host = host; 103 this.port = port; 104 this.type = type; 105 this.resume = resume; 106 this.justStream = justStream; 107 108 reciever = new Thread (this); 110 reciever.start(); 111 } 112 113 public DataConnection(FtpConnection con, int port, String host, 114 String file, String type, boolean resume, 115 String localfile) 116 { 117 this.con = con; 118 this.file = file; 119 this.host = host; 120 this.port = port; 121 this.type = type; 122 this.resume = resume; 123 this.localfile = localfile; 124 125 reciever = new Thread (this); 127 reciever.start(); 128 } 129 130 public DataConnection(FtpConnection con, int port, String host, 131 String file, String type, boolean resume, int skiplen) 132 { 133 this.con = con; 134 this.file = file; 135 this.host = host; 136 this.port = port; 137 this.type = type; 138 this.resume = resume; 139 this.skiplen = skiplen; 140 141 reciever = new Thread (this); 143 reciever.start(); 144 } 145 146 public DataConnection(FtpConnection con, int port, String host, 147 String file, String type, boolean resume, 148 int skiplen, InputStream i) 149 { 150 this.con = con; 151 this.file = file; 152 this.host = host; 153 this.port = port; 154 this.type = type; 155 this.resume = resume; 156 this.skiplen = skiplen; 157 158 if(i != null) 159 { 160 this.in = new BufferedInputStream (i); 161 } 162 163 reciever = new Thread (this); 165 reciever.start(); 166 } 167 168 public void run() 169 { 170 try 171 { 172 newLine = con.getCRLF(); 173 175 if(Settings.getFtpPasvMode()) 176 { 177 try 178 { 179 sock = new Socket (host, port); 180 sock.setSoTimeout(Settings.getSocketTimeout()); 181 } 182 catch(Exception ex) 183 { 184 ok = false; 185 debug("Can't open Socket on port " + port); 186 } 187 } 188 else 189 { 190 try 192 { 193 ssock = new ServerSocket (port); 194 } 195 catch(Exception ex) 196 { 197 ok = false; 198 Log.debug("Can't open ServerSocket on port " + port); 199 } 200 } 201 } 202 catch(Exception ex) 203 { 204 debug(ex.toString()); 205 } 206 207 isThere = true; 208 209 boolean ok = true; 210 211 RandomAccessFile fOut = null; 212 BufferedOutputStream bOut = null; 213 RandomAccessFile fIn = null; 214 215 try 216 { 217 if(!Settings.getFtpPasvMode()) 218 { 219 int retry = 0; 220 221 while((retry++ < 5) && (sock == null)) 222 { 223 try 224 { 225 ssock.setSoTimeout(Settings.connectionTimeout); 226 sock = ssock.accept(); 227 } 228 catch(IOException e) 229 { 230 sock = null; 231 debug("Got IOException while trying to open a socket!"); 232 233 if(retry == 5) 234 { 235 debug("Connection failed, tried 5 times - maybe try a higher timeout in Settings.java..."); 236 } 237 238 finished = true; 239 240 throw e; 241 } 242 finally 243 { 244 ssock.close(); 245 } 246 247 debug("Attempt timed out, retrying..."); 248 } 249 } 250 251 if(ok) 252 { 253 byte[] buf = new byte[Settings.bufferSize]; 254 start = System.currentTimeMillis(); 255 256 int buflen = 0; 257 258 if(type.equals(GET) || type.equals(GETDIR)) 260 { 261 if(!justStream) 262 { 263 try 264 { 265 if(resume) 266 { 267 File f = new File (file); 268 fOut = new RandomAccessFile (file, "rw"); 269 fOut.skipBytes((int) f.length()); 270 buflen = (int) f.length(); 271 } 272 else 273 { 274 if(localfile == null) 275 { 276 localfile = file; 277 } 278 279 File f2 = new File (Settings.appHomeDir); 280 f2.mkdirs(); 281 282 File f = new File (localfile); 283 284 if(f.exists()) 285 { 286 f.delete(); 287 } 288 289 bOut = new BufferedOutputStream (new FileOutputStream (localfile), 290 Settings.bufferSize); 291 } 292 } 293 catch(Exception ex) 294 { 295 debug("Can't create outputfile: " + file); 296 ok = false; 297 ex.printStackTrace(); 298 } 299 } 300 301 if(ok) 302 { 303 try 304 { 305 in = new BufferedInputStream (sock.getInputStream(), 306 Settings.bufferSize); 307 308 if(justStream) 309 { 310 return; 311 } 312 } 313 catch(Exception ex) 314 { 315 ok = false; 316 debug("Can't get InputStream"); 317 } 318 319 if(ok) 320 { 321 try 322 { 323 int len = buflen; 324 325 if(fOut != null) 326 { 327 while(true) 328 { 329 int read = -2; 331 332 try 333 { 334 read = in.read(buf); 335 } 336 catch(IOException es) 337 { 338 Log.out("got a IOException"); 339 ok = false; 340 fOut.close(); 341 finished = true; 342 con.fireProgressUpdate(file, 343 FAILED, -1); 344 345 Log.out("last read: " + read + 346 ", len: " + (len + read)); 347 es.printStackTrace(); 348 349 return; 350 } 351 352 len += read; 353 354 if(read == -1) 355 { 356 break; 357 } 358 359 if(newLine != null) 360 { 361 byte[] buf2 = modifyGet(buf, read); 362 fOut.write(buf2, 0, buf2.length); 363 } 364 else 365 { 366 fOut.write(buf, 0, read); 367 } 368 369 con.fireProgressUpdate(file, type, len); 370 371 if(time()) 372 { 373 } 375 376 if(read == StreamTokenizer.TT_EOF) 377 { 378 break; 379 } 380 } 381 382 } 384 else 385 { 386 while(true) 388 { 389 int read = -2; 391 392 try 393 { 394 read = in.read(buf); 395 } 396 catch(IOException es) 397 { 398 Log.out("got a IOException"); 399 ok = false; 400 bOut.close(); 401 finished = true; 402 con.fireProgressUpdate(file, 403 FAILED, -1); 404 405 Log.out("last read: " + read + 406 ", len: " + (len + read)); 407 es.printStackTrace(); 408 409 return; 410 } 411 412 len += read; 413 414 if(read == -1) 415 { 416 break; 417 } 418 419 if(newLine != null) 420 { 421 byte[] buf2 = modifyGet(buf, read); 422 bOut.write(buf2, 0, buf2.length); 423 } 424 else 425 { 426 bOut.write(buf, 0, read); 427 } 428 429 con.fireProgressUpdate(file, type, len); 430 431 if(time()) 432 { 433 } 435 436 if(read == StreamTokenizer.TT_EOF) 437 { 438 break; 439 } 440 } 441 442 bOut.flush(); 443 444 } 446 } 447 catch(IOException ex) 448 { 449 ok = false; 450 debug("Old connection removed"); 451 con.fireProgressUpdate(file, FAILED, -1); 452 453 ex.printStackTrace(); 455 } 456 } 457 } 458 } 459 460 if(type.equals(PUT) || type.equals(PUTDIR)) 462 { 463 if(in == null) 464 { 465 try 466 { 467 fIn = new RandomAccessFile (file, "r"); 468 469 if(resume) 470 { 471 fIn.skipBytes(skiplen); 472 } 473 474 } 476 catch(Exception ex) 477 { 478 debug("Can't open inputfile: " + " (" + ex + ")"); 479 ok = false; 480 } 481 } 482 483 if(ok) 484 { 485 try 486 { 487 out = new BufferedOutputStream (sock.getOutputStream()); 488 } 489 catch(Exception ex) 490 { 491 ok = false; 492 debug("Can't get OutputStream"); 493 } 494 495 if(ok) 496 { 497 try 498 { 499 int len = skiplen; 500 char b; 501 502 while(true) 503 { 504 int read; 505 506 if(in != null) 507 { 508 read = in.read(buf); 509 } 510 else 511 { 512 read = fIn.read(buf); 513 } 514 515 len += read; 516 517 if(read == -1) 519 { 520 break; 521 } 522 523 if(newLine != null) 524 { 525 byte[] buf2 = modifyPut(buf, read); 526 out.write(buf2, 0, buf2.length); 527 } 528 else 529 { 530 out.write(buf, 0, read); 531 } 532 533 con.fireProgressUpdate(file, type, len); 534 535 if(time()) 536 { 537 } 539 540 if(read == StreamTokenizer.TT_EOF) 541 { 542 break; 543 } 544 } 545 546 out.flush(); 547 548 } 550 catch(IOException ex) 551 { 552 ok = false; 553 debug("Error: Data connection closed."); 554 con.fireProgressUpdate(file, FAILED, -1); 555 ex.printStackTrace(); 556 } 557 } 558 } 559 } 560 } 561 } 562 catch(IOException ex) 563 { 564 Log.debug("Can't connect socket to ServerSocket"); 565 ex.printStackTrace(); 566 } 567 finally 568 { 569 try 570 { 571 if(out != null) 572 { 573 out.flush(); 574 out.close(); 575 } 576 } 577 catch(Exception ex) 578 { 579 ex.printStackTrace(); 580 } 581 582 try 583 { 584 if(bOut != null) 585 { 586 bOut.flush(); 587 bOut.close(); 588 } 589 } 590 catch(Exception ex) 591 { 592 ex.printStackTrace(); 593 } 594 595 try 596 { 597 if(fOut != null) 598 { 599 fOut.close(); 600 } 601 } 602 catch(Exception ex) 603 { 604 ex.printStackTrace(); 605 } 606 607 try 608 { 609 if(in != null && !justStream) 610 { 611 in.close(); 612 } 613 614 if(fIn != null) 615 { 616 fIn.close(); 617 } 618 } 619 catch(Exception ex) 620 { 621 ex.printStackTrace(); 622 } 623 } 624 625 try 626 { 627 sock.close(); 628 } 629 catch(Exception ex) 630 { 631 debug(ex.toString()); 632 } 633 634 if(!Settings.getFtpPasvMode()) 635 { 636 try 637 { 638 ssock.close(); 639 } 640 catch(Exception ex) 641 { 642 debug(ex.toString()); 643 } 644 } 645 646 finished = true; 647 648 if(ok) 649 { 650 con.fireProgressUpdate(file, FINISHED, -1); 651 } 652 else 653 { 654 con.fireProgressUpdate(file, FAILED, -1); 655 } 656 } 657 658 public InputStream getInputStream() 659 { 660 return in; 661 } 662 663 public FtpConnection getCon() 664 { 665 return con; 666 } 667 668 private void debug(String msg) 669 { 670 Log.debug(msg); 671 } 672 673 public void reset() 674 { 675 reciever.destroy(); 676 reciever = new Thread (this); 677 reciever.start(); 678 } 679 680 private void pause(int time) 681 { 682 try 683 { 684 reciever.sleep(time); 685 } 686 catch(Exception ex) 687 { 688 System.out.println(ex); 689 } 690 } 691 692 private boolean time() 693 { 694 long now = System.currentTimeMillis(); 695 long offset = now - start; 696 697 if(offset > Settings.statusMessageAfterMillis) 698 { 699 start = now; 700 701 return true; 702 } 703 704 return false; 705 } 706 707 public boolean isThere() 708 { 709 if(finished) 710 { 711 return true; 712 } 713 714 return isThere; 715 } 716 717 public void setType(String tmp) 718 { 719 type = tmp; 720 } 721 722 public boolean isOK() 723 { 724 return ok; 725 } 726 727 public void interrupt() 728 { 729 if(Settings.getFtpPasvMode() && 730 (type.equals(GET) || type.equals(GETDIR))) 731 { 732 try 733 { 734 reciever.join(); 735 } 736 catch(InterruptedException ex) 737 { 738 ex.printStackTrace(); 739 } 740 } 741 } 742 743 private byte[] modifyPut(byte[] buf, int len) 744 { 745 if(newLine == null) return buf; 747 748 String s = (new String (buf)).substring(0,len); 749 s = s.replaceAll(LINEEND, newLine); 750 752 return s.getBytes(); 753 } 754 755 private byte[] modifyGet(byte[] buf, int len) 756 { 757 if(newLine == null) return buf; 759 760 String s = (new String (buf)).substring(0,len); 761 s = s.replaceAll(newLine, LINEEND); 762 764 return s.getBytes(); 765 } 766 } 767 | Popular Tags |