home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 25 / CDROM25.iso / Share / prog / VJ11 / VJTRIAL.EXE / IE30Java.exe / classd.exe / sun / net / ftp / FtpClient.java < prev    next >
Encoding:
Java Source  |  1997-01-27  |  8.9 KB  |  323 lines

  1. /*
  2.  * @(#)FtpClient.java    1.35 96/01/25 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 sun.net.ftp;
  21.  
  22. import java.util.StringTokenizer;
  23. import java.io.*;
  24. import java.net.*;
  25. import sun.net.TransferProtocolClient;
  26. import sun.net.TelnetInputStream;
  27. import sun.net.TelnetOutputStream;
  28.  
  29. /**
  30.  * This class implements the FTP client. 
  31.  *
  32.  * @version    1.35, 01/25/96
  33.  * @author    Jonathan Payne
  34.  */
  35.  
  36. public class FtpClient extends TransferProtocolClient {
  37.     public static final int FTP_PORT = 21;
  38.  
  39.     static int    FTP_SUCCESS = 1;
  40.     static int    FTP_TRY_AGAIN = 2;
  41.     static int    FTP_ERROR = 3;
  42.  
  43.     /** socket for data transfer */
  44.     private Socket    dataSocket = null;
  45.     private boolean    replyPending = false;
  46.     private boolean    binaryMode = false;
  47.  
  48.     /** user name for login */
  49.     String        user = null;
  50.     /** password for login */
  51.     String        password = null;
  52.  
  53.     /** last command issued */
  54.     String        command;
  55.  
  56.     /** The last reply code from the ftp daemon. */
  57.     int            lastReplyCode;
  58.  
  59.     /** Welcome message from the server, if any. */
  60.     public String    welcomeMsg;
  61.  
  62.     /* these fields are used to determine whether ftp urls are sent to */
  63.     /* an http server instead of using a direct connection to the */
  64.     /* host. They aren't used directly here. */
  65.     public static boolean    useFtpProxy = Boolean.getBoolean("ftpProxySet");
  66.     public static String    ftpProxyHost = System.getProperty("ftpProxyHost");
  67.     public static int        ftpProxyPort = Integer.getInteger("ftpProxyPort", 80).intValue();
  68.  
  69.     /** 
  70.      * issue the QUIT command to the FTP server and close the connection. 
  71.      */
  72.     public void closeServer() throws IOException {
  73.     if (serverIsOpen()) {
  74.         issueCommand("QUIT");
  75.         super.closeServer();
  76.     }
  77.     }
  78.  
  79.     protected int issueCommand(String cmd) throws IOException {
  80.     command = cmd;
  81.  
  82.     int reply;
  83.  
  84.     if (replyPending) {
  85.         if (readReply() == FTP_ERROR)
  86.         System.out.print("Error reading pending reply\n");
  87.     }
  88.     replyPending = false;
  89.     do {
  90.         sendServer(cmd + "\r\n");
  91.         reply = readReply();
  92.     } while (reply == FTP_TRY_AGAIN);
  93.     return reply;
  94.     }
  95.  
  96.     protected void issueCommandCheck(String cmd) throws IOException {
  97.     if (issueCommand(cmd) != FTP_SUCCESS)
  98.         throw new FtpProtocolException(cmd);
  99.     }
  100.  
  101.     protected int readReply() throws IOException {
  102.     lastReplyCode = readServerResponse();
  103.  
  104.     switch (lastReplyCode / 100) {
  105.     case 1:
  106.         replyPending = true;
  107.         /* falls into ... */
  108.  
  109.     case 2:
  110.     case 3:
  111.         return FTP_SUCCESS;
  112.  
  113.     case 5:
  114.         if (lastReplyCode == 530) {
  115.         if (user == null) {
  116.             throw new FtpLoginException("Not logged in");
  117.         }
  118.         return FTP_ERROR;
  119.         }
  120.         if (lastReplyCode == 550) {
  121.         throw new FileNotFoundException(command + ": " + getResponseString());
  122.         }
  123.     }
  124.  
  125.     /* this statement is not reached */
  126.     return FTP_ERROR;
  127.     }
  128.  
  129.     protected Socket openDataConnection(String cmd) throws IOException {
  130.     ServerSocket portSocket;
  131.     String        portCmd;
  132.     InetAddress myAddress = InetAddress.getLocalHost();
  133.     byte        addr[] = myAddress.getAddress();
  134.     int        shift;
  135.     IOException e;
  136.  
  137.     portSocket = new ServerSocket(0, 1);
  138.     portCmd = "PORT ";
  139.  
  140.     /* append host addr */
  141.     for (int i = 0; i < addr.length; i++) {
  142.         portCmd = portCmd + (addr[i] & 0xFF) + ",";
  143.     }
  144.  
  145.     /* append port number */
  146.     portCmd = portCmd + ((portSocket.getLocalPort() >>> 8) & 0xff) + ","
  147.         + (portSocket.getLocalPort() & 0xff);
  148.     if (issueCommand(portCmd) == FTP_ERROR) {
  149.         e = new FtpProtocolException("PORT");
  150.         portSocket.close();
  151.         throw e;
  152.     }
  153.     if (issueCommand(cmd) == FTP_ERROR) {
  154.         e = new FtpProtocolException(cmd);
  155.         portSocket.close();
  156.         throw e;
  157.     }
  158.     dataSocket = portSocket.accept();
  159.     portSocket.close();
  160.  
  161.     return dataSocket;
  162.     }
  163.  
  164.     /* public methods */
  165.  
  166.     /** open a FTP connection to host <i>host</i>. */
  167.     public void openServer(String host) throws IOException {
  168.     int port = FTP_PORT;
  169.  
  170.     /*
  171.     String source = Firewall.verifyAccess(host, port);
  172.  
  173.     if (source != null) {
  174.         Firewall.securityError("Applet at " +
  175.                    source +
  176.                    " tried to open FTP connection to "
  177.                    + host + ":" + port);
  178.         return;
  179.     }
  180.     */
  181.     openServer(host, port);
  182.     }
  183.  
  184.     /** open a FTP connection to host <i>host</i> on port <i>port</i>. */
  185.     public void openServer(String host, int port) throws IOException {
  186.     /*
  187.     String source = Firewall.verifyAccess(host, port);
  188.  
  189.     if (source != null) {
  190.         Firewall.securityError("Applet at " +
  191.                    source +
  192.                    " tried to open FTP connection to "
  193.                    + host + ":" + port);
  194.         return;
  195.     }
  196.     */
  197.     super.openServer(host, port);
  198.     if (readReply() == FTP_ERROR)
  199.         throw new FtpProtocolException("Welcome message");
  200.     }
  201.  
  202.  
  203.     /** 
  204.      * login user to a host with username <i>user</i> and password 
  205.      * <i>password</i> 
  206.      */
  207.     public void login(String user, String password) throws IOException {
  208.     /* This is bogus.  It shouldn't send a password unless it
  209.            needs to. */
  210.  
  211.     if (!serverIsOpen())
  212.         throw new FtpLoginException("not connected to host");
  213.     this.user = user;
  214.     this.password = password;
  215.     if (issueCommand("USER " + user) == FTP_ERROR)
  216.         throw new FtpLoginException("user");
  217.     if (password != null && issueCommand("PASS " + password) == FTP_ERROR)
  218.         throw new FtpLoginException("password");
  219.     // keep the welcome message around so we can
  220.     // put it in the resulting HTML page.
  221.     String l;
  222.     for (int i = 0; i < serverResponse.size(); i++) {
  223.         l = (String)serverResponse.elementAt(i);
  224.         if (l != null) {
  225.         if (l.charAt(3) != '-') {
  226.             break;
  227.         }
  228.         // get rid of the "230-" prefix
  229.         l = l.substring(4);
  230.         if (welcomeMsg == null) {
  231.             welcomeMsg = l;
  232.         } else {
  233.             welcomeMsg += l;
  234.         }
  235.         }
  236.     }
  237.     }
  238.  
  239.     /** GET a file from the FTP server */
  240.     public TelnetInputStream get(String filename) throws IOException {
  241.     Socket    s;
  242.  
  243.     try {
  244. //        throw new FileNotFoundException("Just kidding!");
  245.         s = openDataConnection("RETR " + filename);
  246.     } catch (FileNotFoundException fileException) {
  247.         /* Well, "/" might not be the file delimitor for this
  248.            particular ftp server, so let's try a series of
  249.            "cd" commands to get to the right place. */
  250.         StringTokenizer t = new StringTokenizer(filename, "/");
  251.         String        pathElement = null;
  252.  
  253.         while (t.hasMoreElements()) {
  254.         pathElement = t.nextToken();
  255.  
  256.         if (!t.hasMoreElements()) {
  257.             /* This is the file component.  Look it up now. */
  258.             break;
  259.         }
  260.         try {
  261.             cd(pathElement);
  262.         } catch (FtpProtocolException e) {
  263.             /* Giving up. */
  264.             throw fileException;
  265.         }
  266.         }
  267.         if (pathElement != null) {
  268.         s = openDataConnection("RETR " + pathElement);
  269.         } else {
  270.         throw fileException;
  271.         }
  272.     }
  273.  
  274.     return new FtpInputStream(this, s.getInputStream(), binaryMode);
  275.     }
  276.  
  277.     /** PUT a file to the FTP server */
  278.     public TelnetOutputStream put(String filename) throws IOException {
  279.     Socket s = openDataConnection("STOR " + filename);
  280.  
  281.     return new TelnetOutputStream(s.getOutputStream(), binaryMode);
  282.     }
  283.  
  284.     /** LIST files on a remote FTP server */
  285.     public TelnetInputStream list() throws IOException {
  286.     Socket s = openDataConnection("LIST");
  287.  
  288.     return new TelnetInputStream(s.getInputStream(), binaryMode);
  289.     }
  290.  
  291.     /** CD to a specific directory on a remote FTP server */
  292.     public void cd(String remoteDirectory) throws IOException {
  293.     issueCommandCheck("CWD " + remoteDirectory);
  294.     }
  295.  
  296.     /** Set transfer type to 'I' */
  297.     public void binary() throws IOException {
  298.     issueCommandCheck("TYPE I");
  299.     binaryMode = true;
  300.     }
  301.  
  302.     /** Set transfer type to 'A' */
  303.     public void ascii() throws IOException {
  304.     issueCommandCheck("TYPE A");
  305.     binaryMode = false;
  306.     }
  307.  
  308.     /** New FTP client connected to host <i>host</i>. */
  309.     public FtpClient(String host) throws IOException {
  310.     super();
  311.     openServer(host, FTP_PORT);
  312.     }
  313.  
  314.     /** New FTP client connected to host <i>host</i>, port <i>port</i>. */
  315.     public FtpClient(String host, int port) throws IOException {
  316.     super();
  317.     openServer(host, port);
  318.     }
  319.  
  320.     /** Create an uninitialized FTP client. */
  321.     public FtpClient() {}
  322. }
  323.