KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jftp > net > FtpServerSocket


1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  */

16 package net.sf.jftp.net;
17
18 import net.sf.jftp.system.logging.Log;
19
20 import java.io.*;
21
22 import java.lang.reflect.*;
23
24 import java.net.*;
25
26 import java.text.*;
27
28 import java.util.*;
29
30
31 /**
32  *
33  */

34 public class FtpServerSocket extends Thread JavaDoc
35 {
36     public final static int port = 21;
37     public final static int dataPort = 20;
38     private static ArrayList commands = null;
39
40     static
41     {
42         commands = new ArrayList();
43         commands.add("auth");
44         commands.add("cdup");
45         commands.add("cwd");
46         commands.add("feat");
47         commands.add("help");
48         commands.add("lang");
49         commands.add("list");
50         commands.add("mkd");
51         commands.add("mode");
52         commands.add("motd");
53         commands.add("nlst");
54         commands.add("noop");
55         commands.add("opts");
56         commands.add("pass");
57         commands.add("pasv");
58         commands.add("port");
59         commands.add("pwd");
60         commands.add("quit");
61         commands.add("rein");
62         commands.add("smnt");
63         commands.add("stat");
64         commands.add("stru");
65         commands.add("syst");
66         commands.add("type");
67         commands.add("user");
68     }
69
70     private Socket socket = null;
71     private BufferedReader in = null;
72     private PrintWriter out = null;
73     private Hashtable methods = new Hashtable();
74     private File directory = new File(".");
75     private ResourceBundle bundle = ResourceBundle.getBundle("responses",
76                                                              Locale.US);
77     private ServerSocket pasvSocket = null;
78     private boolean passive = false;
79     private int activePort = 0;
80     private String JavaDoc structure = "file";
81     private String JavaDoc transferMode = "stream";
82     private String JavaDoc type = "ascii";
83     private String JavaDoc rootDir = null;
84     private String JavaDoc currentDir = null;
85
86     public FtpServerSocket(Socket s) throws IOException
87     {
88         socket = s;
89
90         try
91         {
92             in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
93             out = new PrintWriter(socket.getOutputStream(), true);
94         }
95         catch(IOException ioe)
96         {
97             throw ioe;
98         }
99
100         Method[] m = this.getClass().getDeclaredMethods();
101         String JavaDoc methodName = null;
102
103         for(int i = 0; i < m.length; i++)
104         {
105             methodName = m[i].getName();
106
107             if(commands.contains(methodName))
108             {
109                 methods.put(methodName, m[i]);
110             }
111         }
112
113         this.start();
114     }
115
116     private void send(String JavaDoc bundleId)
117     {
118         out.print(bundle.getString(bundleId));
119         out.flush();
120     }
121
122     private void send(String JavaDoc bundleId, Object JavaDoc[] args)
123     {
124         MessageFormat fmt = new MessageFormat(bundle.getString(bundleId));
125         out.print(fmt.format(args));
126         out.flush();
127     }
128
129     public void motd()
130     {
131         send("220motd");
132     }
133
134     public void user(String JavaDoc line)
135     {
136         send("331user");
137     }
138
139     public void pass(String JavaDoc line)
140     {
141         send("230pass");
142     }
143
144     public void syst(String JavaDoc line)
145     {
146         send("215syst");
147     }
148
149     public void type(String JavaDoc line)
150     { // needs work A, E, I, L, C, T, N
151

152         Object JavaDoc[] args = { "I" };
153         send("200type", args);
154     }
155
156     public void stru(String JavaDoc line)
157     { // needs work - check for F, R, or P
158

159         Object JavaDoc[] args = { line.toUpperCase() };
160         send("200ok", args);
161     }
162
163     public void mode(String JavaDoc line)
164     { // check for S, B, or C
165

166         Object JavaDoc[] args = { line.toUpperCase() };
167         send("200ok", args);
168     }
169
170     public void rein(String JavaDoc line)
171     {
172         Object JavaDoc[] args = { "REIN" };
173         send("502", args);
174     }
175
176     public void smnt(String JavaDoc line)
177     {
178         Object JavaDoc[] args = { "SMNT" };
179         send("502", args);
180     }
181
182     public void quit(String JavaDoc line)
183     {
184         out.print("221-You have transferred 0 bytes in 0 files.\r\n");
185         out.print("221-Total traffic for this session was 0 bytes in 0 transfers.\r\n");
186         out.print("221 Thank you for using the FTP service on pikachu.\r\n");
187         out.flush();
188
189         try
190         {
191             socket.close();
192         }
193         catch(Exception JavaDoc e)
194         {
195         }
196     }
197
198     public void pwd(String JavaDoc line)
199     {
200         Object JavaDoc[] args = { currentDir };
201         send("257pwd", args);
202     }
203
204     public void cwd(String JavaDoc line)
205     {
206         String JavaDoc arg = line.substring(4);
207         String JavaDoc tmpDir;
208
209         if(arg.startsWith("/"))
210         {
211             tmpDir = removeTrailingSlash(rootDir) + arg;
212         }
213         else
214         {
215             tmpDir = addTrailingSlash(currentDir) + arg;
216         }
217
218         File tmp = new File(tmpDir);
219
220         if(tmp.exists() && tmp.isDirectory())
221         {
222             currentDir = tmpDir;
223             send("250cwd");
224         }
225         else
226         {
227             out.print("550 " + arg + ": No such file or directory.\r\n");
228             out.flush();
229         }
230     }
231
232     public void cdup(String JavaDoc line)
233     {
234         Object JavaDoc[] args = { "CDUP" };
235         File tmp = directory.getParentFile();
236
237         if(tmp != null)
238         {
239             directory = tmp;
240         }
241
242         send("200", args);
243     }
244
245     public void noop(String JavaDoc line)
246     {
247         Object JavaDoc[] args = { "NOOP" };
248         send("200", args);
249     }
250
251     public void help(String JavaDoc line)
252     {
253         out.print("214-The following commands are recognized.\r\n");
254
255         /*
256            USER PORT STOR RNTO NLST MKD CDUP
257            PASS PASV APPE ABOR SITE XMKD XCUP
258            TYPE DELE SYST RMD STOU
259            STRU ALLO CWD STAT XRMD SIZE
260            MODE REST XCWD HELP PWD MDTM
261            QUIT RETR RNFR LIST NOOP XPWD
262         */

263         out.print("214 Direct comments to root@localhost.\r\n");
264         out.flush();
265     }
266
267     public void stat(String JavaDoc line)
268     {
269         out.print("211-FTP server status:\r\n");
270
271         /*
272              Version wu-2.6.1-16
273              Connected to pikachu (127.0.0.1)
274              Logged in as gary
275              TYPE: ASCII, FORM: Nonprint; STRUcture: File; transfer MODE: Stream
276              No data connection
277              0 data bytes received in 0 files
278              0 data bytes transmitted in 0 files
279              0 data bytes total in 0 files
280              82 traffic bytes received in 0 transfers
281              2502 traffic bytes transmitted in 1 transfers
282              2634 traffic bytes total in 1 transfers
283              Disk quota: 0 disk blocks in use, 0 quota, 0 limit - time left
284              Inode quota: 0 inodes in use, 0 quota, 0 limit - time left
285         */

286         out.print("211 End of status\r\n");
287         out.flush();
288     }
289
290     private String JavaDoc addTrailingSlash(String JavaDoc s)
291     {
292         if(s.endsWith("/"))
293         {
294             return s;
295         }
296         else
297         {
298             return s + "/";
299         }
300     }
301
302     private String JavaDoc removeTrailingSlash(String JavaDoc s)
303     {
304         if(s.endsWith("/"))
305         {
306             return s.substring(0, s.length() - 1);
307         }
308         else
309         {
310             return s;
311         }
312     }
313
314     public void mkd(String JavaDoc line)
315     {
316         String JavaDoc arg = line.substring(4);
317
318         if(arg.startsWith("/"))
319         {
320             arg = removeTrailingSlash(rootDir) + arg;
321         }
322         else
323         {
324             arg = addTrailingSlash(currentDir) + arg;
325         }
326
327         File f = new File(arg);
328         MessageFormat fmt = null;
329         Object JavaDoc[] args = { f.getAbsolutePath() };
330
331         if(f.exists())
332         {
333             send("521mkd", args);
334         }
335         else if(f.mkdirs())
336         {
337             send("257mkd", args);
338         }
339         else
340         {
341             send("550mkd", args);
342         }
343     }
344
345     public void feat(String JavaDoc line)
346     {
347         out.print("211-Extensions supported\r\n");
348         out.print(" LANG EN*;FR\r\n");
349         out.print("211 END\r\n");
350         out.flush();
351     }
352
353     public void pasv(String JavaDoc line)
354     {
355         InetAddress address = socket.getLocalAddress();
356         String JavaDoc pasvAddress = address.getHostAddress().replace('.', ',');
357
358         try
359         {
360             pasvSocket = new ServerSocket(0, 5, address);
361             passive = true;
362         }
363         catch(IOException ioe)
364         {
365         }
366
367         int pasvPort = pasvSocket.getLocalPort();
368         Object JavaDoc[] args =
369                         {
370                             pasvAddress + "," + ((int) pasvPort / 256) + "," +
371                             (pasvPort % 256)
372                         };
373         send("227pasv", args);
374     }
375
376     public void list(String JavaDoc line)
377     {
378         send("150list");
379
380         if(!passive)
381         {
382             try
383             {
384                 Socket activeSocket = new Socket(socket.getInetAddress(),
385                                                  activePort);
386                 PrintStream ps = new PrintStream(activeSocket.getOutputStream());
387                 ps.print("bleah\r\n");
388                 ps.print("bleah\r\n");
389                 ps.print("bleah\r\n");
390                 ps.print("bleah\r\n");
391                 ps.print("bleah\r\n");
392                 ps.flush();
393                 ps.close();
394                 send("226");
395             }
396             catch(Exception JavaDoc e)
397             {
398             }
399         }
400     }
401
402     public void nlst(String JavaDoc line)
403     {
404         send("150nlst");
405
406         if(!passive)
407         {
408             try
409             {
410                 Socket activeSocket = new Socket(socket.getInetAddress(),
411                                                  activePort);
412                 PrintStream ps = new PrintStream(activeSocket.getOutputStream());
413                 ps.print("bleah\r\n");
414                 ps.print("bleah\r\n");
415                 ps.print("bleah\r\n");
416                 ps.print("bleah\r\n");
417                 ps.print("bleah\r\n");
418                 ps.flush();
419                 ps.close();
420                 send("225");
421             }
422             catch(Exception JavaDoc e)
423             {
424             }
425         }
426     }
427
428     public void port(String JavaDoc line)
429     {
430         int start = line.lastIndexOf(",");
431         int end = line.length();
432         String JavaDoc lo = null; // lo-ordered byte
433

434         if((start != -1) && (end != -1))
435         {
436             lo = line.substring(start + 1, end);
437         }
438
439         end = start;
440         start = line.lastIndexOf(",", start - 1);
441
442         String JavaDoc hi = null; // hi-ordered byte
443

444         if((start != -1) && (end != -1))
445         {
446             hi = line.substring(start + 1, end);
447         }
448
449         activePort = ((Integer.parseInt(hi) * 256) + Integer.parseInt(lo));
450
451         Object JavaDoc[] args = { "PORT" };
452         send("200", args);
453     }
454
455     public void opts(String JavaDoc line)
456     {
457         // return 200, 451 or 501
458
}
459
460     public void lang(String JavaDoc line)
461     {
462         out.print("200 Responses changed to english\r\n");
463         out.flush();
464     }
465
466     public void auth(String JavaDoc line)
467     {
468     }
469
470     public void setRoot(String JavaDoc line)
471     {
472         if(new File(line).exists())
473         {
474             rootDir = line;
475         }
476         else
477         {
478             System.err.println("invalid root directory");
479         }
480     }
481
482     public void run()
483     {
484         try
485         {
486             String JavaDoc line = null;
487             motd();
488
489             while((line = in.readLine()) != null)
490             {
491                 System.out.println(line);
492
493                 int index = line.indexOf(' ');
494
495                 if(index == -1)
496                 {
497                     index = line.length();
498                 }
499
500                 String JavaDoc command = line.substring(0, index).toLowerCase();
501                 Method o = (Method) methods.get(command);
502
503                 if(o != null)
504                 {
505                     try
506                     {
507                         o.invoke(this, new Object JavaDoc[] { line });
508                     }
509                     catch(Exception JavaDoc e)
510                     {
511                     }
512                 }
513                 else
514                 {
515                     send("500");
516                 }
517             }
518         }
519         catch(IOException ioe)
520         {
521             Log.debug("Socket error: " + ioe);
522         }
523     }
524
525     public static void main(String JavaDoc[] args)
526     {
527     }
528 }
529
Popular Tags