package rene.util.ftp; import java.io.*; import java.net.*; import java.util.*; /** An FTP protocol handler. See main for an example. */ public class FTP { String Server; int Port; Socket S; BufferedReader In; PrintWriter Out; Answer A; /** Just denote the server and port (default is 21). The connection has to be opened and closed! */ public FTP (String server, int port) { Server=server; Port=port; } public FTP (String server) { this(server,21); } /** Open the connection to the server, getting the control data streams. */ public void open () throws IOException,UnknownHostException { S=new Socket(Server,Port); In=new BufferedReader(new InputStreamReader( new DataInputStream(S.getInputStream()))); Out=new PrintWriter(S.getOutputStream()); if (getreply()/100!=2) throw new IOException("Illegal reply."); } /** Open the server and connect as user with the password. */ public void open (String user, String password) throws IOException,UnknownHostException { open(); if (!command("USER "+user)) throw new IOException("User not accepted."); if (!command("PASS "+password)) throw new IOException("Wrong Password"); } /** Close the connection to the server and the control data streams. */ public void close () throws IOException { send("QUIT"); In.close(); Out.close(); S.close(); } /** Wait for reply from the server. @return the reply code (1xx,2xx,3xx are OK). */ public int getreply () throws IOException { A=new Answer(); A.get(In); //System.out.println(A.code()); //System.out.println(A.text()); return A.code(); } /** Send a command to the server and wait for a direct reply. This will set the Answer field for checking. @return true if the command succeeded immediately. */ public boolean command (String s) throws IOException { send(s); return (getreply()/100<4); } /** This returns the Answer to the previous command. The meanings of Answer.code() are: <ul> <li> 1xx - Another reply will follow <li> 2xx - The answer is positive <li> 3xx - The answer is positive, but needs more action <li> 4xx - The answer is negative, but one can try again <li> 5xx - The answer is negative </ul> A.text() will contain the text, the server sent. In case of multiline text, this will be separated by \n. */ public Answer answer () { return A; } /** Send a command to the server. */ public void send (String s) throws IOException { Out.println(s); Out.flush(); } /** Tell the server to wait for a data connection on a port of his discretion. The return of the server is scanned for the IP and the port and a Socket is generated. @return Socket for the data connection to the server */ public Socket passive () throws IOException,UnknownHostException, NumberFormatException { if (!command("PASV")) throw new IOException("Passive mode not supported."); StringTokenizer p=new StringTokenizer(A.text(),"(,)"); if (!p.hasMoreTokens()) throw new IOException("Wrong answer from server."); else p.nextToken(); int N[]=new int[4]; for (int i=0; i<4; i++) { N[i]=Integer.parseInt(p.nextToken()); } int k=Integer.parseInt(p.nextToken()); int P=k*256+Integer.parseInt(p.nextToken()); String server=N[0]+"."+N[1]+"."+N[2]+"."+N[3]; return new Socket(server,P); } Socket DSocket; /** Get an input stream to the file. getClose() must be called! */ public InputStream getFile (String file) throws IOException,UnknownHostException { DSocket=passive(); if (!command("TYPE I")) throw new IOException("Type I not supported?"); send("RETR "+file); getreply(); if (A.code()/100>=4) throw new IOException("Get failed."); return DSocket.getInputStream(); } /** Get an input stream to the list. getClose() must be called! */ public InputStream getDir (String path) throws IOException,UnknownHostException { DSocket=passive(); if (!command("TYPE A")) throw new IOException("Type A not supported?"); if (!path.equals("")) send("LIST "+path); else send("LIST"); getreply(); if (A.code()/100>=4) throw new IOException("ls failed."); return DSocket.getInputStream(); } /** Get an input stream to the list. getClose() must be called! */ public InputStream getLs(String path) throws IOException,UnknownHostException { DSocket=passive(); if (!command("TYPE A")) throw new IOException("Type A not supported?"); if (!path.equals("")) send("NLST "+path); else send("NLST"); getreply(); if (A.code()/100>=4) throw new IOException("ls failed."); return DSocket.getInputStream(); } /** Close the data socket after a get command and wait for the transfer complete message. */ public void getClose () throws IOException { DSocket.close(); while (true) { getreply(); if (A.code()==226) return; if (A.code()>=400) throw new IOException("Put failed."); } } /** Get an output stream to the file. putClose() must be called! */ public OutputStream putFile (String file) throws IOException,UnknownHostException { DSocket=passive(); if (!command("TYPE I")) throw new IOException("Type I not supported?"); send("STOR "+file); getreply(); if (A.code()/100>=4) throw new IOException("Put failed."); return DSocket.getOutputStream(); } /** Close the date socket after a put command and wait for the transfer complete message. */ public void putClose () throws IOException { DSocket.close(); while (true) { getreply(); if (A.code()==226) return; if (A.code()>=400) throw new IOException("Put failed."); } } /** Cange the directory to the specified one. */ public void changeDirectory (String dir) throws IOException { if (!command("CWD "+dir)) throw new IOException("Directory change failed."); } public Vector getDirectory (String dir) throws IOException { Vector v=new Vector(); try { BufferedReader In=new BufferedReader( new InputStreamReader(getDir(dir))); while (true) { String s=In.readLine(); if (s==null) break; v.addElement(s); } In.close(); } catch (Exception e) { throw new IOException("Directory list failed."); } getClose(); return v; } public Vector getCurrentDirectory () throws IOException { return getDirectory("."); } static public void main (String args[]) { try { //FTP ftp=new FTP("mathsrv.ku-eichstaett.de"); //ftp.open("",""); FTP ftp=new FTP("localhost"); ftp.open("",""); testPut(ftp.putFile("test")); ftp.putClose(); testGet(ftp.getFile("test")); ftp.getClose(); Enumeration e=ftp.getCurrentDirectory().elements(); while (e.hasMoreElements()) { System.out.println((String)e.nextElement()); } ftp.close(); } catch (Exception e) { System.out.println(e); } } static void testGet (InputStream in) throws IOException { BufferedReader In=new BufferedReader( new InputStreamReader(in)); while (true) { String s=In.readLine(); if (s==null) break; System.out.println(s); } In.close(); } static void testPut (OutputStream out) throws IOException { PrintWriter Out=new PrintWriter(out); Out.println("Erste Zeile: Test"); Out.println("Zweite Zeile: Test"); Out.print("Dritte Zeile"); Out.flush(); Out.close(); } }