Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: FTreeP/FTPCommandRelay.java


1   package FTreeP;
2   
3   import java.io.*;
4   import java.net.*;
5   import java.util.*;
6   
7   import java.awt.*;
8   import java.awt.event.*;
9   
10  import javax.swing.*;
11  import javax.swing.tree.*;
12  import javax.swing.event.*;
13  
14  import DirectoryIndexer.*;
15  
16  class FTPCommandRelay
17  extends Thread
18  {
19    private Socket command_in_socket = null, command_out_socket = null;
20    private BufferedReader cmd_in_in = null, cmd_out_in = null;
21    private BufferedWriter cmd_in_out = null, cmd_out_out = null;
22  
23    private String mode = "STREAM",
24            pwd = "/",
25            type = "ASCII";
26  
27    private String current_host = "";
28    private int current_host_port = 0;
29  
30    private boolean quit = false;
31  
32    private FTPConsole console = null;
33  
34    public FTPCommandRelay(Socket command_in_socket) throws Exception
35    {
36      FTPBase.system_println("Incoming connection detected, spawning FTPCommandRelay instance.");
37      this.command_in_socket = command_in_socket;
38  
39      if(FTPBase.gui) createGUIElements();
40    }
41  
42    public void run()
43    {
44      try {
45  
46        cmd_in_in = new BufferedReader(new InputStreamReader(command_in_socket.getInputStream()));
47        cmd_in_out = new BufferedWriter(new OutputStreamWriter(command_in_socket.getOutputStream()));
48  
49        respond(cmd_in_out, 220, "Connected to FTreeP");
50  
51        boolean quit = false;
52  
53        while(!quit && command_in_socket != null && cmd_in_in != null && cmd_in_out != null)
54        {
55          String cmd = cmd_in_in.readLine();
56  
57          if(FTPBase.DEBUG) console.println("COMMAND: " + cmd);
58  
59          interpret(cmd);
60        }
61  
62        FTPBase.system_println("Outgoing connection terminated, killing FTPCommandRelay instance.");
63  
64      } catch(Exception e) {}
65  
66      if(FTPBase.gui) destroyGUIElements();
67    }
68  
69    private void interpret(String cmd) throws Exception
70    {
71      String argument = "";
72  
73      if(cmd.indexOf(" ") != -1)
74        argument = cmd.substring(cmd.indexOf(" ") + 1);
75  
76      cmd = cmd.toLowerCase();
77  
78      if(cmd.startsWith("cdup"))    cdup();
79      else if(cmd.startsWith("cwd"))  cwd(argument);
80      else if(cmd.startsWith("list"))  list(argument);
81      else if(cmd.startsWith("mode"))  mode(argument);
82      else if(cmd.startsWith("noop"))  noop();
83      else if(cmd.startsWith("pasv"))  pasv();
84      else if(cmd.startsWith("port"))  port(argument);
85      else if(cmd.startsWith("pwd") | cmd.startsWith("xpwd"))  pwd();
86      else if(cmd.startsWith("quit"))  quit();
87      else if(cmd.startsWith("retr"))  retr(argument);
88      else if(cmd.startsWith("size"))  size(argument);
89      else if(cmd.startsWith("type"))  type(argument);
90      else if(cmd.startsWith("user"))  user(argument);
91      else
92      {
93        respond(cmd_in_out, 502, "Command not implemented.");
94      }
95    }
96  
97    private Resource getResourceFromPath(String path) throws Exception
98    {
99      Resource r = null;
100 
101     int score = -1;
102     StringTokenizer score_tokens = null;
103 
104     for(int i = 0; i < FTPBase.directory_index.size(); i++)
105     {
106       String virtual_directory = FTPBase.directory_index.get(i).getVirtualDirectory();
107 
108       if(path.startsWith(virtual_directory))
109       {
110         score_tokens = new StringTokenizer(virtual_directory, "/");
111         if(score_tokens.countTokens() > score)
112         {
113           r = FTPBase.directory_index.get(i);
114           score = score_tokens.countTokens();
115         }
116       }
117     }
118 
119     if(FTPBase.DEBUG && r == null) FTPBase.system_println("DEBUG: Error, could not locate appropriate Resource!");
120 
121     return r;
122   }
123 
124   private void connectToHostWithResource(String resource) throws Exception
125   {
126     Resource r = getResourceFromPath(resource);
127 
128     if(current_host.equals(r.getHost()) && current_host_port == r.getPort())
129     {
130       if(FTPBase.DEBUG) console.println("DEBUG: Already connected to the desired host.");
131       return;
132     } else if(FTPBase.DEBUG) console.print("DEBUG: Connecting to Data Host providing " + resource + "... ");
133 
134     if(command_out_socket != null && cmd_out_in != null && cmd_out_out != null)
135     {
136       relay(cmd_out_out, "QUIT");
137       command_out_socket = null;
138       cmd_out_in = null;
139       cmd_out_out = null;
140     }
141 
142     command_out_socket = new Socket(r.getHost(), r.getPort());
143 
144     cmd_out_in = new BufferedReader(new InputStreamReader(command_out_socket.getInputStream()));
145     cmd_out_out = new BufferedWriter(new OutputStreamWriter(command_out_socket.getOutputStream()));
146 
147     current_host = r.getHost();
148     current_host_port = r.getPort();
149 
150     if(FTPBase.DEBUG) console.println("Done!");
151   }
152 
153   // Make a path into its simplist form; the most direct representation
154   // of a directory from the root directory '/'.  All paths end up in
155   // the form: '/dir1/dir2/dir3/'.
156   private String simplifyPath(String path) throws Exception
157   {
158     if(path.equals("")) return path;
159 
160     StringTokenizer st = new StringTokenizer(path, "/");
161 
162     ArrayList d = new ArrayList();
163 
164     while(st.hasMoreTokens())
165     {
166       String s = st.nextToken();
167 
168       if(s.equals(".")) continue;
169       else if(s.equals(".."))
170       {
171         if(d.size() >= 1) d.remove(d.size() - 1);
172       }
173       else d.add(s);
174     }
175 
176     String p = "/";
177 
178     int i = 0;
179     for(i = 0; i < d.size() - 1; i++)
180       p = p + (String) d.get(i) + "/";
181 
182     if(d.size() >= 1) p = p + (String) d.get(i);
183 
184     return p;
185   }
186 
187   // Reply to a machine with a message comprised of the response_code and
188   // the message over the given BufferedWriter.  Terminte the response with a CRLF.
189   public void respond(BufferedWriter cmd_out, int response_code, String message) throws Exception
190   {
191     cmd_out.write(response_code + " " + message + FTPBase.CRLF);
192     cmd_out.flush();
193 
194     if(FTPBase.DEBUG) console.println("RESPOND: " + response_code + " " + message);
195   }
196 
197   // Reply to a machine with a message comprised of the message over the given Socket.
198   // Terminte the response with a CRLF.
199   public void relay(BufferedWriter cmd_out, String message) throws Exception
200   {
201     cmd_out.write(message + FTPBase.CRLF);
202     cmd_out.flush();
203 
204     if(FTPBase.DEBUG) console.println("RELAY: " + message);
205   }
206 
207   private void createGUIElements()
208   {
209     console = new FTPConsole();
210 
211     FTPBase.tabbed_pane.addTab("FTPCommandRelay", console);
212   }
213 
214   private void destroyGUIElements()
215   {
216     //FTPBase.tabbed_pane.remove(console);
217 
218     //console = null;
219   }
220 
221 /*
222  --------------
223 | FTP COMMANDS |
224  --------------
225 */
226 
227 // Handle the CDUP command.
228   private void cdup() throws Exception
229   {
230     cwd("..");
231   }
232 
233 // Handle the CWD command.
234   private void cwd(String directory) throws Exception
235   {
236     if(!directory.startsWith("/")) directory = pwd + "/" + directory;
237 
238     directory = simplifyPath(directory);
239 
240     connectToHostWithResource(directory);
241 
242     relay(cmd_out_out, "CWD " + directory);
243     relay(cmd_in_out, cmd_out_in.readLine());
244 
245     pwd = directory;
246   }
247 
248 // Handle the LIST command.
249   private void list(String directory) throws Exception
250   {
251     if(!directory.startsWith("/")) directory = pwd + "/" + directory;
252 
253     directory = simplifyPath(directory);
254 
255     relay(cmd_out_out, "LIST " + directory);
256     relay(cmd_in_out, cmd_out_in.readLine());
257     relay(cmd_in_out, cmd_out_in.readLine());
258   }
259 
260 // Handle the MODE command.
261   private void mode(String mode) throws Exception
262   {
263     if(mode.equalsIgnoreCase("S"))    this.mode = "STREAM";
264     else if(mode.equalsIgnoreCase("B"))  this.mode = "BLOCK";
265     else if(mode.equalsIgnoreCase("C"))  this.mode = "COMPRESSED";
266     else
267     {
268       // FIX - Find the appropriate response here...
269       return;
270     }
271 
272     respond(cmd_in_out, 200, "Mode set to " + this.mode + ".");
273   }
274 
275 // Handle the NOOP command.
276   private void noop() throws Exception
277   {
278     respond(cmd_in_out, 200, "Command okay.");
279   }
280 
281 // Handle the PASV command.
282   private void pasv() throws Exception
283   {
284     connectToHostWithResource(pwd);
285 
286     relay(cmd_out_out, "PASV");
287     relay(cmd_in_out, cmd_out_in.readLine());
288   }
289 
290 // Handle the PORT command.
291   private void port(String port_text) throws Exception
292   {
293     connectToHostWithResource(pwd);
294 
295     relay(cmd_out_out, "PORT " + port_text);
296     relay(cmd_in_out, cmd_out_in.readLine());
297   }
298 
299 // Handle the PWD command.
300   private void pwd() throws Exception
301   {
302     respond(cmd_in_out, 257, "\"" + pwd + "\" is current directory.");
303   }
304 
305 // Handle the QUIT command.
306   private void quit() throws Exception
307   {
308     relay(cmd_out_out, "QUIT");
309     respond(cmd_in_out, 221, "Goodbye!");
310 
311     this.quit = true;
312 
313     if(command_in_socket != null)
314     {
315       command_in_socket.close();
316       command_in_socket = null;
317 
318       cmd_in_in = null;
319       cmd_in_out = null;
320     }
321 
322     if(command_out_socket != null)
323     {
324       command_out_socket.close();
325       command_out_socket = null;
326 
327       cmd_out_in = null;
328       cmd_out_out = null;
329     }
330   }
331 
332 // Handle the RETR command.
333   private void retr(String file) throws Exception
334   {
335     if(!file.startsWith("/")) file = pwd + "/" + file;
336     file = simplifyPath(file);
337 
338     relay(cmd_out_out, "RETR" + "_" + this.type + " " + file);
339 
340     relay(cmd_in_out, cmd_out_in.readLine());
341     relay(cmd_in_out, cmd_out_in.readLine());
342   }
343 
344 // Handle the SIZE command.
345   private void size(String file) throws Exception
346   {
347     if(!file.startsWith("/")) file = pwd + file;
348     file = simplifyPath(file);
349 
350     connectToHostWithResource(file);
351 
352     relay(cmd_out_out, "SIZE " + file);
353     relay(cmd_in_out, cmd_out_in.readLine());
354   }
355 
356 // Handle the TYPE command.
357   private void type(String type) throws Exception
358   {
359     if(type.equalsIgnoreCase("A"))    this.type = "ASCII";
360     else if(type.equalsIgnoreCase("I"))  this.type = "IMAGE";
361     else
362     {
363       // FIX - Find the appropriate response here...
364       return;
365     }
366 
367     respond(cmd_in_out, 200, "Type set to " + this.type + ".");
368   }
369 
370 // Handle the USER command.
371   private void user(String user) throws Exception
372   {
373     respond(cmd_in_out, 230, "Login ocomplete.  Anonymous user rights granted.");
374   }
375 }