home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / win95 / sieciowe / hotja32.lzh / hotjava / classsrc / net / ftp / ftpclient.java next >
Text File  |  1995-08-11  |  8KB  |  293 lines

  1. /*
  2.  * @(#)FtpClient.java    1.25 95/05/10 Jonathan Payne
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package net.ftp;
  21.  
  22. import java.util.StringTokenizer;
  23. import java.io.*;
  24. import net.*;
  25.  
  26. /**
  27.  * This class implements the FTP client. 
  28.  *
  29.  * @version    1.25, 10 May 1995
  30.  * @author    Jonathan Payne
  31.  */
  32.  
  33. public class FtpClient extends TransferProtocolClient {
  34.     static int    FTP_SUCCESS = 1;
  35.     static int    FTP_TRY_AGAIN = 2;
  36.     static int    FTP_ERROR = 3;
  37.  
  38.     /** socket for data transfer */
  39.     private Socket    dataSocket = null;
  40.     private boolean    replyPending = false;
  41.     private boolean    binaryMode = false;
  42.  
  43.     /** user name for login */
  44.     String        user = null;
  45.     /** password for login */
  46.     String        password = null;
  47.  
  48.     /** last command issued */
  49.     String        command;
  50.  
  51.     /** The last reply code from the ftp daemon. */
  52.     int            lastReplyCode;
  53.  
  54.     /* these fields are used to determine whether ftp urls are sent to */
  55.     /* an http server instead of using a direct connection to the */
  56.     /* host. They aren't used directly here. */
  57.     public static boolean    useFtpProxy = false;
  58.     public static String    ftpProxyHost = null;
  59.     public static int        ftpProxyPort = 80;
  60.  
  61.     /** 
  62.      * issue the QUIT command to the FTP server and close the connection. 
  63.      */
  64.     public void closeServer() {
  65.     if (serverIsOpen()) {
  66.         issueCommand("QUIT");
  67.         super.closeServer();
  68.     }
  69.     }
  70.  
  71.     protected int issueCommand(String cmd) {
  72.     command = cmd;
  73.  
  74.     int reply;
  75.  
  76.     if (replyPending) {
  77.         if (readReply() == FTP_ERROR)
  78.         System.out.print("Error reading pending reply\n");
  79.     }
  80.     replyPending = false;
  81.     do {
  82.         sendServer(cmd + "\r\n");
  83.         reply = readReply();
  84.     } while (reply == FTP_TRY_AGAIN);
  85.     return reply;
  86.     }
  87.  
  88.     protected void issueCommandCheck(String cmd) {
  89.     if (issueCommand(cmd) != FTP_SUCCESS)
  90.         throw new FtpProtocolException(cmd);
  91.     }
  92.  
  93.     protected int readReply() {
  94.     lastReplyCode = readServerResponse();
  95.  
  96.     switch (lastReplyCode / 100) {
  97.     case 1:
  98.         replyPending = true;
  99.         /* falls into ... */
  100.  
  101.     case 2:
  102.     case 3:
  103.         return FTP_SUCCESS;
  104.  
  105.     case 5:
  106.         if (lastReplyCode == 530) {
  107.         if (user == null) {
  108.             throw new FtpLoginException("Not logged in");
  109.         }
  110.         return FTP_ERROR;
  111.         }
  112.         if (lastReplyCode == 550) {
  113.         throw new FileNotFoundException(command + ": " + getResponseString());
  114.         }
  115.     }
  116.  
  117.     /* this statement is not reached */
  118.     return FTP_ERROR;
  119.     }
  120.  
  121.     protected Socket openDataConnection(String cmd) {
  122.     Socket        portSocket;
  123.     String        portCmd;
  124.     InetAddress myAddress = InetAddress.getByName(InetAddress.localHostName);
  125.     int        addr = myAddress.address;
  126.     int        shift;
  127.     Exception   e;
  128.  
  129.     portSocket = new Socket(true);
  130.     portSocket.bindAnonymously(myAddress);
  131.     portSocket.listen(1);
  132.     portCmd = "PORT ";
  133.  
  134.     /* append host addr */
  135.     for (shift = 32; (shift -= 8) >= 0; )
  136.         portCmd = portCmd + ((addr >>> shift) & 0xff) + ",";
  137.  
  138.     /* append port number */
  139.     portCmd = portCmd + ((portSocket.port >>> 8) & 0xff) + ","
  140.         + (portSocket.port & 0xff);
  141.     if (issueCommand(portCmd) == FTP_ERROR) {
  142.         e = new FtpProtocolException("PORT");
  143.         portSocket.close();
  144.         throw e;
  145.     }
  146.     if (issueCommand(cmd) == FTP_ERROR) {
  147.         e = new FtpProtocolException(cmd);
  148.         portSocket.close();
  149.         throw e;
  150.     }
  151.     dataSocket = portSocket.accept();
  152.     portSocket.close();
  153.  
  154.     return dataSocket;
  155.     }
  156.  
  157.     /* public methods */
  158.  
  159.     /** open a FTP connection to host <i>host</i>. */
  160.     public void openServer(String host) {
  161.     int port = InetAddress.getPortByName("ftp");
  162.     String source = Firewall.verifyAccess(host, port);
  163.  
  164.     if (source != null) {
  165.         Firewall.securityError("Applet at " +
  166.                    source +
  167.                    " tried to open FTP connection to "
  168.                    + host + ":" + port);
  169.         return;
  170.     }
  171.     openServer(host, port);
  172.     }
  173.  
  174.     /** open a FTP connection to host <i>host</i> on port <i>port</i>. */
  175.     public void openServer(String host, int port) {
  176.     String source = Firewall.verifyAccess(host, port);
  177.  
  178.     if (source != null) {
  179.         Firewall.securityError("Applet at " +
  180.                    source +
  181.                    " tried to open FTP connection to "
  182.                    + host + ":" + port);
  183.         return;
  184.     }
  185.     super.openServer(host, port);
  186.     if (readReply() == FTP_ERROR)
  187.         throw new FtpProtocolException("Welcome message");
  188.     }
  189.  
  190.  
  191.     /** 
  192.      * login user to a host with username <i>user</i> and password 
  193.      * <i>password</i> 
  194.      */
  195.     public void login(String user, String password) {
  196.     /* This is bogus.  It shouldn't send a password unless it
  197.            needs to. */
  198.  
  199.     if (!serverIsOpen())
  200.         throw new FtpLoginException("not connected to host");
  201.     this.user = user;
  202.     this.password = password;
  203.     if (issueCommand("USER " + user) == FTP_ERROR)
  204.         throw new FtpLoginException("user");
  205.     if (password != null && issueCommand("PASS " + password) == FTP_ERROR)
  206.         throw new FtpLoginException("password");
  207.     }
  208.  
  209.     /** GET a file from the FTP server */
  210.     public TelnetInputStream get(String filename) {
  211.     Socket    s;
  212.  
  213.     try {
  214. //        throw new FileNotFoundException("Just kidding!");
  215.         s = openDataConnection("RETR " + filename);
  216.     } catch (FileNotFoundException fileException) {
  217.         /* Well, "/" might not be the file delimitor for this
  218.            particular ftp server, so let's try a series of
  219.            "cd" commands to get to the right place. */
  220.         StringTokenizer t = new StringTokenizer(filename, "/");
  221.         String        pathElement = null;
  222.  
  223.         while (t.hasMoreElements()) {
  224.         pathElement = t.nextToken();
  225.  
  226.         if (!t.hasMoreElements()) {
  227.             /* This is the file component.  Look it up now. */
  228.             break;
  229.         }
  230.         try {
  231.             cd(pathElement);
  232.         } catch (FtpProtocolException e) {
  233.             /* Giving up. */
  234.             throw fileException;
  235.         }
  236.         }
  237.         if (pathElement != null) {
  238.         s = openDataConnection("RETR " + pathElement);
  239.         } else {
  240.         throw fileException;
  241.         }
  242.     }
  243.  
  244.     return new FtpInputStream(this, s.inputStream, binaryMode);
  245.     }
  246.  
  247.     /** PUT a file to the FTP server */
  248.     public TelnetOutputStream put(String filename) {
  249.     Socket s = openDataConnection("STOR " + filename);
  250.  
  251.     return new TelnetOutputStream(s.outputStream, binaryMode);
  252.     }
  253.  
  254.     /** LIST files on a remote FTP server */
  255.     public TelnetInputStream list() {
  256.     Socket s = openDataConnection("LIST");
  257.  
  258.     return new TelnetInputStream(s.inputStream, binaryMode);
  259.     }
  260.  
  261.     /** CD to a specific directory on a remote FTP server */
  262.     public void cd(String remoteDirectory) {
  263.     issueCommandCheck("CWD " + remoteDirectory);
  264.     }
  265.  
  266.     /** Set transfer type to 'I' */
  267.     public void binary() {
  268.     issueCommandCheck("TYPE I");
  269.     binaryMode = true;
  270.     }
  271.  
  272.     /** Set transfer type to 'A' */
  273.     public void ascii() {
  274.     issueCommandCheck("TYPE A");
  275.     binaryMode = false;
  276.     }
  277.  
  278.     /** New FTP client connected to host <i>host</i>. */
  279.     public FtpClient(String host) {
  280.     super();
  281.     openServer(host, InetAddress.getPortByName("ftp"));
  282.     }
  283.  
  284.     /** New FTP client connected to host <i>host</i>, port <i>port</i>. */
  285.     public FtpClient(String host, int port) {
  286.     super();
  287.     openServer(host, port);
  288.     }
  289.  
  290.     /** Create an uninitialized FTP client. */
  291.     public FtpClient() {}
  292. }
  293.