//////////////////////////////////////////////////////////////////////////////// // ftpServer class. // //////////////////////////////////////////////////////////////////////////////// import java.net.*; import java.io.*; class ftpServer { public static void main (String argv[]) { System.out.println("ftpd started!!"); // Espera por conexões. // Listen na porta passada no primeiro parâmetro. // Diretório raiz passado no segundo parâmetro. ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(Integer.parseInt(argv[0])); } catch (IOException e) { System.out.println("Could not listen on port: " + argv[0] + ", " + e); System.exit(1); } Socket newSocket = null; // Fica em loop aceitando novas conexões de ftp. do { try { newSocket = serverSocket.accept(); } catch (IOException e) { System.out.println("Accept failed: " + argv[0] + ", " + e); System.exit(1); } // Thread para cuidar da conexao. new AppThread(newSocket, argv[1]).start(); } while(true); } // A ser discutido ... // Se for necessario fechar o serverSocket... public void finalize() { // Fecha o serverSocket. // try { // serverSocket.close(); // } catch (IOException e) { // System.out.println("close serverSocket failed! " + e); // System.exit(1); // } } } class AppThread extends Thread { Socket socket; String rootPath; public AppThread(Socket sock, String root) { //super(objName); socket = sock; rootPath = root; } public void run() { DataInputStream recvBuf = null; //Leitura. DataOutputStream sendBuf = null; //Escrita. System.out.println("FTP Thread started..."); // Cria os objetos para leitura e escrita. try { sendBuf = new DataOutputStream( new BufferedOutputStream(socket.getOutputStream())); recvBuf = new DataInputStream( new BufferedInputStream(socket.getInputStream())); } catch (IOException e) { System.out.println("IO Exception"); } //----------------------- // Quarda informações sobre o estado atual da sessão. ftpState sessionState = new ftpState(); sessionState.sendMesg = sendBuf; sessionState.remotePort = socket.getPort(); sessionState.remoteInetAddress = socket.getInetAddress(); if(rootPath.endsWith(File.separator)) { sessionState.rootPath = rootPath.substring(0,rootPath.length()-1); } else { sessionState.rootPath = rootPath; } sessionState.path = File.separator; sessionState.userLogged = false; sessionState.endSession = false; //----------------------- // String inicial. // Ack de conexão efetuada. try { sendBuf.writeBytes("220 FTP server (Versão 0.4b) Ok (login anonymous/ftp apenas).\r\n"); sendBuf.flush(); } catch (IOException e) { System.out.println("220 -IO Exception" + e); } String command = null; // String vinda do cliente. String ugaComm = null; // String com o comando a ser executado. Class funcClass; // Classe do comando a ser executado. ftpFunc func = null; // Instância do comando a ser executado. //----------------------- // Verifica o loggin. while(!sessionState.endSession && !sessionState.userLogged) { try { // Espera por um comando do cliente. command = recvBuf.readLine(); System.out.println("command: "+command); // Separa o comando do parâmetro. int ix = command.indexOf(" "); if(ix == -1) { ugaComm = command; sessionState.param = null; } else { ugaComm = command.substring(0,ix); sessionState.param = command.substring(ix+1); } } catch (IOException e) { System.out.println("IO Exception"); stop(); } // Executa os comandos de login. try { if(ugaComm.equalsIgnoreCase("USER") || ugaComm.equalsIgnoreCase("PASS") || ugaComm.equalsIgnoreCase("QUIT") || ugaComm.equalsIgnoreCase("SYST")) { funcClass = Class.forName(ugaComm.toUpperCase()+"comm"); func = (ftpFunc)funcClass.newInstance(); func.start(sessionState); } else { try { sendBuf.writeBytes("530 Use USER e PASS para logar.\r\n"); sendBuf.flush(); } catch (IOException e2) { System.out.println(e2); } } } catch (ClassNotFoundException e) { // Se a classe não existir, é porque o comando não foi reconhecido. try { sendBuf.writeBytes("530 Use USER e PASS para logar.\r\n"); sendBuf.flush(); } catch (IOException e2) { System.out.println(e2); } System.out.println("Classe não encontrada: "+e); } catch (IllegalAccessException e) { System.out.println(e); } catch (InstantiationException e) { System.out.println(e); } } //----------------------- // Conversa com o cliente. while(!sessionState.endSession) { try { // Espera por um comando do cliente. command = recvBuf.readLine(); System.out.println("command: "+command); // Separa o comando do parâmetro. int ix = command.indexOf(" "); if(ix == -1) { ugaComm = command; sessionState.param = null; } else { ugaComm = command.substring(0,ix); sessionState.param = command.substring(ix+1); } } catch (IOException e) { System.out.println("IO Exception"); stop(); } // Executa o comando. try { funcClass = Class.forName(ugaComm.toUpperCase()+"comm"); func = (ftpFunc)funcClass.newInstance(); func.start(sessionState); } catch (ClassNotFoundException e) { // Se a classe não existir, é porque o comando não foi reconhecido. try { sendBuf.writeBytes("500 "+ugaComm+": comando não entendido.\r\n"); sendBuf.flush(); } catch (IOException e2) { System.out.println(e2); } System.out.println("Classe não encontrada: "+e); } catch (Exception e) { System.out.println(e); // Se a classe não existir, é porque o comando não foi reconhecido. try { sendBuf.writeBytes("500 "+ugaComm+": comando não válido.\r\n"); sendBuf.flush(); } catch (IOException e2) { System.out.println(e2); } System.out.println("Classe não válida: "+e); } } //------------------ // Fecha o socket com o cliente. try { socket.close(); } catch (IOException e) { System.out.println("close socket failed! " + e); System.exit(1); } } } // 500 '': command not understood. // 331 Guest login ok, send your complete e-mail address as password. // 230 Guest login ok, access restrictions apply. // 530 Already logged in. // 257 "/pub" is current directory. (PWD) // 250 CWD command successful. // 221 Goodbye. // 215 UNIX Type: L8 (syst)