示例#1
0
  /**
   * Default constructor. Create a new FTP client and connect to a specified server.
   *
   * @param server Address of an FTP server
   */
  public Ftp(String server) {
    serverAddr = server;
    debug = true;

    try {
      sock = new Socket(server, 21);
      System.out.println("Connected to " + server);

      out = new PrintWriter(sock.getOutputStream(), true);
      in = new BufferedReader(new InputStreamReader(sock.getInputStream()));

      System.out.println(getResponse());
    } catch (IOException e) {
      System.err.println(e.getMessage());
      System.exit(1);
    }
  }
示例#2
0
  /**
   * Main method which is in charge of parsing and interpreting user input and interacting with the
   * FTP client.
   *
   * @param args Command line arguments; should only contain the server
   */
  public static void main(String args[]) {
    boolean eof = false;
    String input = null;
    Scanner in = new Scanner(System.in);

    if (args.length != 1) {
      System.err.println("Usage: java Ftp <server>");
      System.exit(1);
    }

    /* Create a new FTP client */
    Ftp client = new Ftp(args[0]);

    do {
      try {
        System.out.print(prompt);
        input = in.nextLine();
      } catch (NoSuchElementException e) {
        eof = true;
      }

      /* Keep going if we have not hit end of file */
      if (!eof && input.length() > 0) {
        int cmd = -1;
        String argv[] = input.split("\\s+");

        for (int i = 0; i < commands.length && cmd == -1; i++)
          if (commands[i].equalsIgnoreCase(argv[0])) cmd = i;

        /* Execute the command */
        switch (cmd) {
          case ASCII:
            client.ascii();
            break;
          case BINARY:
            client.binary();
            break;
          case CD:
            client.cd(argv[1]);
            break;
          case CDUP:
            client.cdup();
            break;
          case DEBUG:
            client.toggleDebug();
            break;
          case DIR:
            client.dir();
            break;
          case GET:
            client.get(argv[1]);
            break;
          case HELP:
            for (int i = 0; i < HELP_MESSAGE.length; i++) System.out.println(HELP_MESSAGE[i]);
            break;
          case PASSIVE:
            client.pasv();
            break;
          case PWD:
            client.pwd();
            break;
          case QUIT:
            eof = true;
            break;
          case USER:
            client.user(argv[1]);
            String password = PasswordField.getPassword("Password:  "******"Invalid command");
        }
      }
    } while (!eof);

    /* Clean up */
    client.close();
  }
示例#3
0
/**
 * A basic implementation of the FTP client protocol (RFC959).
 *
 * @author Luke Macken ([email protected])
 */
public class Ftp {
  public static final String prompt = ">> ";

  public static final String line_sep = System.getProperties().getProperty("line.separator");

  public static final String commands[] = {
    "ascii", "binary", "cd", "cdup", "debug", "dir", "get", "help",
    "passive", "put", "pwd", "quit", "user", "pass", "pasv", "list"
  };

  public static final int ASCII = 0;
  public static final int BINARY = 1;
  public static final int CD = 2;
  public static final int CDUP = 3;
  public static final int DEBUG = 4;
  public static final int DIR = 5;
  public static final int GET = 6;
  public static final int HELP = 7;
  public static final int PASSIVE = 8;
  public static final int PUT = 9;
  public static final int PWD = 10;
  public static final int QUIT = 11;
  public static final int USER = 12;
  public static final int PASS = 13;
  public static final int PASV = 14;
  public static final int LIST = 15;

  public static final String[] HELP_MESSAGE = {
    "ascii        --> Set ASCII transfer type",
    "binary       --> Set binary transfer type",
    "cd <path>    --> Change the remote working directory",
    "cdup         --> Change the remote working directory to the",
    "                 parent directory (i.e., cd ..)",
    "debug        --> Toggle debug mode",
    "dir          --> List the contents of the remote directory",
    "get <path>   --> Get a remote file",
    "help         --> Displays this text",
    "passive      --> Toggle passive/active mode",
    "put <path>   --> Transfer the specified file to the server",
    "pwd          --> Print the working directory on the server",
    "quit         --> Close the connection to the server and terminate",
    "user <login> --> Specify the user name (will prompt for password)"
  };

  /* The IP/hostname of the FTP server we are connecting to */
  private String serverAddr;

  /* Debugging mode */
  private boolean debug;

  /* ASCII transfer mode */
  private boolean ascii = true;

  /* If we are in passive or active mode */
  private boolean passive = true;

  /* I/O communication objects */
  private Socket sock;
  private Socket pasvSock = null;
  private ServerSocket activeSock = null;
  private BufferedReader pasvIn;
  private BufferedReader in;
  private PrintWriter out;

  /**
   * Default constructor. Create a new FTP client and connect to a specified server.
   *
   * @param server Address of an FTP server
   */
  public Ftp(String server) {
    serverAddr = server;
    debug = true;

    try {
      sock = new Socket(server, 21);
      System.out.println("Connected to " + server);

      out = new PrintWriter(sock.getOutputStream(), true);
      in = new BufferedReader(new InputStreamReader(sock.getInputStream()));

      System.out.println(getResponse());
    } catch (IOException e) {
      System.err.println(e.getMessage());
      System.exit(1);
    }
  }

  /** Toggle debugging mode. */
  public void toggleDebug() {
    if (debug) {
      debug("Debugging output off");
      debug = false;
    } else {
      debug = true;
      debug("Debugging output on");
    }
  }

  /** Close the client connect to the server. */
  public void close() {
    try {
      debug("Closing connect to server");
      System.out.println("=> QUIT");
      out.println("QUIT");
      System.out.println(getResponse());
      out.close();
      in.close();
      sock.close();
      if (pasvSock != null && !pasvSock.isClosed()) {
        pasvIn.close();
        pasvSock.close();
      }
      if (activeSock != null && !activeSock.isClosed()) {
        activeSock.close();
      }
    } catch (IOException e) {
      System.err.println(e.getMessage());
    }
  }

  /**
   * Receive a single line response from the server.
   *
   * @return the response from the server
   */
  private String getResponse() {
    try {
      return in.readLine();
    } catch (IOException e) {
      System.err.println("Error reading server response: " + e.getMessage());
    }

    return null;
  }

  /**
   * Log a debugging message to the console if the user has specified that debug mode should be
   * enabled. If it is not, then this method is essentially a nop.
   *
   * @param msg the debugging message to log
   */
  private void debug(String msg) {
    if (debug) System.err.println(msg);
  }

  /**
   * Send a given username to the server.
   *
   * @param username the username to login with
   */
  public void user(String username) {
    out.println(commands[USER] + " " + username);
    System.out.println(getResponse());
  }

  /**
   * Send a given password to the server.
   *
   * @param password the password for the user.
   */
  public void pass(String password) {
    out.println(commands[PASS] + " " + password);
    System.out.println(getResponse());
  }

  /** Request a directory listing from the server. */
  public void dir() {
    String userInput;
    BufferedReader srvIn;
    Socket srv = null;

    /* Setup the appropriate sockets */
    setupTransferMode();

    out.println(commands[LIST]);
    System.out.println("=> LIST");
    System.out.println(getResponse());

    try {
      /* Setup the proper input streams based on the transfer mode */
      if (passive) {
        srvIn = pasvIn;
      } else {
        srv = activeSock.accept();
        srvIn = new BufferedReader(new InputStreamReader(srv.getInputStream()));
      }

      /* Display the directory listing */
      while ((userInput = srvIn.readLine()) != null) {
        System.out.println(userInput);
      }

      srvIn.close();
      if (srv != null) {
        srv.close();
      }
    } catch (IOException e) {
      System.err.println("Error recieving data from server: " + e.getMessage());
    }

    /* Clean up */
    closeTransferMode();
    System.out.println(getResponse());
  }

  /** Set the transfer type to ASCII. */
  public void ascii() {
    ascii = true;
    System.out.println("=> TYPE A");
    out.println("TYPE A");
    System.out.println(getResponse());
  }

  /** Toggle passive/active modes. */
  public void pasv() {
    passive = (passive) ? false : true;
    System.out.println(((passive) ? "Passive" : "Active") + " mode enabled");
  }

  /** Close any sockets associated with the current transfer mode. */
  private void closeTransferMode() {
    try {
      if (passive) {
        if (pasvSock != null && !pasvSock.isClosed()) {
          debug("Closing passive connection");
          pasvIn.close();
          pasvSock.close();
        }
      } else {
        if (activeSock != null && !activeSock.isClosed()) {
          debug("Closing active connection");
          activeSock.close();
        }
      }
    } catch (IOException e) {
      System.err.println("Error closing transfer mode: " + e.getMessage());
    }
  }

  /** Setup the sockets needed for the given transfer mode (either passive or active). */
  private void setupTransferMode() {
    String resp = "";

    if (passive) {
      debug("Switching to passive mode");
      System.out.println("=> PASV");
      out.println(commands[PASV]);
      resp = getResponse();
      System.out.println(resp);

      /* If we've successfully entered passive mode, setup the socket */
      if (resp.startsWith("227")) {
        String[] foo = resp.split(",");
        int pasvPort =
            new Integer(foo[4]) * 256 + new Integer(foo[5].replaceAll("[a-zA-Z).]+", ""));

        debug("Opening passive socket on " + serverAddr + ":" + pasvPort);

        try {
          pasvSock = new Socket(serverAddr, pasvPort, null, sock.getLocalPort() + 1);
          pasvIn = new BufferedReader(new InputStreamReader(pasvSock.getInputStream()));
        } catch (IOException e) {
          System.err.println(e.getMessage());
        }
      } else {
        debug("Got invalid response from PASV command");
      }
    } else {
      /* Active mode */
      debug("Switching to active mode");

      try {
        activeSock = new ServerSocket(0);
      } catch (IOException e) {
        System.err.println("Error creating active socket: " + e.getMessage());
      }

      byte[] addr = sock.getLocalAddress().getAddress();
      debug("Listening on local port " + activeSock.getLocalPort());

      String portCmd =
          "PORT "
              + ((int) addr[0] & 0xFF)
              + ","
              + ((int) addr[1] & 0xFF)
              + ","
              + ((int) addr[2] & 0xFF)
              + ","
              + ((int) addr[3] & 0xFF)
              + ","
              + activeSock.getLocalPort() / 256
              + ","
              + activeSock.getLocalPort() % 256;

      System.out.println("=> " + portCmd);
      out.println(portCmd);
      System.out.println(getResponse());
    }
  }

  /** Print out the current working directory on the server. */
  public void pwd() {
    System.out.println("=> PWD");
    out.println("PWD");
    System.out.println(getResponse());
  }

  /** Set the transfer type to binary. */
  public void binary() {
    ascii = false;
    System.out.println("=> TYPE I");
    out.println("TYPE I");
    System.out.println(getResponse());
  }

  /**
   * Tell the server to change working directories.
   *
   * @param dir the directory to change to. if dir is '..', then this function will call cdup()
   *     instead.
   */
  public void cd(String dir) {
    System.out.println("=> CWD " + dir);
    out.println("CWD " + dir);
    System.out.println(getResponse());
  }

  /** Tell the server to go up a directory. */
  public void cdup() {
    System.out.println("=> CDUP");
    out.println("CDUP");
    System.out.println(getResponse());
  }

  /**
   * Request a specified file from the server.
   *
   * @param path The path to the file to acquire
   */
  public void get(String path) {
    String userInput, resp;
    BufferedReader srvIn;
    InputStream inStr;
    Socket srv = null;

    /* Initialize the appropriate transfer mode */
    setupTransferMode();

    /* Request the file */
    System.out.println("=> RETR " + path);
    out.println("RETR " + path);

    /* Spit out the response */
    resp = getResponse();
    System.out.println(resp);

    /* Validate response */
    if (!resp.startsWith("150")) {
      debug("Invalid response from RETR command; aborting transfer");
      closeTransferMode();
      return;
    }

    try {
      /* Point to the appropriate input streams based on transfer mode */
      if (passive) {
        srvIn = pasvIn;
        inStr = pasvSock.getInputStream();
      } else {
        srv = activeSock.accept();
        inStr = srv.getInputStream();
      }

      /* ASCII transfer */
      if (ascii) {
        FileWriter outFile = new FileWriter(new File(path).getName());
        srvIn = new BufferedReader(new InputStreamReader(inStr));

        while ((userInput = srvIn.readLine()) != null) {
          outFile.write(userInput + line_sep);
        }

        outFile.close();
        srvIn.close();
      } else {
        /* Binary transfer */
        int bytesRead = 0;
        byte[] buf = new byte[512];

        FileOutputStream outFile = new FileOutputStream(new File(path).getName());
        BufferedInputStream binIn = new BufferedInputStream(inStr);

        while ((bytesRead = binIn.read(buf, 0, 512)) != -1) {
          outFile.write(buf, 0, bytesRead);
        }

        outFile.close();
        binIn.close();
      }

      if (srv != null) {
        srv.close();
      }
    } catch (IOException e) {
      System.err.println("Error acquiring file: " + e.getMessage());
    }

    /* Clean up */
    closeTransferMode();
    System.out.println(getResponse());
  }

  /**
   * Main method which is in charge of parsing and interpreting user input and interacting with the
   * FTP client.
   *
   * @param args Command line arguments; should only contain the server
   */
  public static void main(String args[]) {
    boolean eof = false;
    String input = null;
    Scanner in = new Scanner(System.in);

    if (args.length != 1) {
      System.err.println("Usage: java Ftp <server>");
      System.exit(1);
    }

    /* Create a new FTP client */
    Ftp client = new Ftp(args[0]);

    do {
      try {
        System.out.print(prompt);
        input = in.nextLine();
      } catch (NoSuchElementException e) {
        eof = true;
      }

      /* Keep going if we have not hit end of file */
      if (!eof && input.length() > 0) {
        int cmd = -1;
        String argv[] = input.split("\\s+");

        for (int i = 0; i < commands.length && cmd == -1; i++)
          if (commands[i].equalsIgnoreCase(argv[0])) cmd = i;

        /* Execute the command */
        switch (cmd) {
          case ASCII:
            client.ascii();
            break;
          case BINARY:
            client.binary();
            break;
          case CD:
            client.cd(argv[1]);
            break;
          case CDUP:
            client.cdup();
            break;
          case DEBUG:
            client.toggleDebug();
            break;
          case DIR:
            client.dir();
            break;
          case GET:
            client.get(argv[1]);
            break;
          case HELP:
            for (int i = 0; i < HELP_MESSAGE.length; i++) System.out.println(HELP_MESSAGE[i]);
            break;
          case PASSIVE:
            client.pasv();
            break;
          case PWD:
            client.pwd();
            break;
          case QUIT:
            eof = true;
            break;
          case USER:
            client.user(argv[1]);
            String password = PasswordField.getPassword("Password:  "******"Invalid command");
        }
      }
    } while (!eof);

    /* Clean up */
    client.close();
  }
}