KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > drftpd > master > command > plugins > Dir


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

18 package net.sf.drftpd.master.command.plugins;
19
20 import java.io.FileNotFoundException JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.text.SimpleDateFormat JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Date JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.StringTokenizer JavaDoc;
27
28 import net.sf.drftpd.Bytes;
29 import net.sf.drftpd.Checksum;
30 import net.sf.drftpd.NoAvailableSlaveException;
31 import net.sf.drftpd.FileExistsException;
32 import net.sf.drftpd.event.DirectoryFtpEvent;
33 import net.sf.drftpd.master.BaseFtpConnection;
34 import net.sf.drftpd.master.FtpReply;
35 import net.sf.drftpd.master.FtpRequest;
36 import net.sf.drftpd.master.UploaderPosition;
37 import net.sf.drftpd.master.command.CommandHandlerBundle;
38 import net.sf.drftpd.master.command.CommandManager;
39 import net.sf.drftpd.master.command.CommandManagerFactory;
40 import net.sf.drftpd.master.usermanager.NoSuchUserException;
41 import net.sf.drftpd.master.usermanager.User;
42 import net.sf.drftpd.master.usermanager.UserFileException;
43 import net.sf.drftpd.remotefile.LinkedRemoteFile;
44 import net.sf.drftpd.remotefile.LinkedRemoteFileInterface;
45 import net.sf.drftpd.remotefile.LinkedRemoteFile.NonExistingFile;
46 import net.sf.drftpd.util.ListUtils;
47 import net.sf.drftpd.util.ReplacerUtils;
48
49 import org.apache.log4j.Level;
50 import org.apache.log4j.Logger;
51 import org.drftpd.commands.CommandHandler;
52 import org.drftpd.commands.UnhandledCommandException;
53 import org.drftpd.plugins.SiteBot;
54 import org.tanesha.replacer.FormatterException;
55 import org.tanesha.replacer.ReplacerEnvironment;
56 import org.tanesha.replacer.ReplacerFormat;
57
58 /**
59  * @author mog
60  * @version $Id: Dir.java,v 1.29 2004/06/01 15:40:30 mog Exp $
61  */

62 public class Dir implements CommandHandlerBundle, Cloneable JavaDoc {
63     private final static SimpleDateFormat JavaDoc DATE_FMT =
64         new SimpleDateFormat JavaDoc("yyyyMMddHHmmss.SSS");
65
66     private static final Logger logger = Logger.getLogger(Dir.class);
67     protected LinkedRemoteFileInterface _renameFrom = null;
68
69     public Dir() {
70         super();
71     }
72
73     /**
74      * <code>CDUP &lt;CRLF&gt;</code><br>
75      *
76      * This command is a special case of CWD, and is included to
77      * simplify the implementation of programs for transferring
78      * directory trees between operating systems having different
79      * syntaxes for naming the parent directory. The reply codes
80      * shall be identical to the reply codes of CWD.
81      */

82     private FtpReply doCDUP(BaseFtpConnection conn) {
83
84         // change directory
85
try {
86             conn.setCurrentDirectory(
87                 conn.getCurrentDirectory().getParentFile());
88         } catch (FileNotFoundException JavaDoc ex) {
89         }
90
91         return new FtpReply(
92             200,
93             "Directory changed to " + conn.getCurrentDirectory().getPath());
94     }
95
96     /**
97      * <code>CWD &lt;SP&gt; &lt;pathname&gt; &lt;CRLF&gt;</code><br>
98      *
99      * This command allows the user to work with a different
100      * directory for file storage or retrieval without
101      * altering his login or accounting information. Transfer
102      * parameters are similarly unchanged. The argument is a
103      * pathname specifying a directory.
104      */

105     private FtpReply doCWD(BaseFtpConnection conn) {
106         FtpRequest request = conn.getRequest();
107
108         if (!request.hasArgument()) {
109             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
110         }
111
112         LinkedRemoteFile newCurrentDirectory;
113         try {
114             newCurrentDirectory =
115                 conn.getCurrentDirectory().lookupFile(request.getArgument());
116         } catch (FileNotFoundException JavaDoc ex) {
117             return new FtpReply(550, ex.getMessage());
118         }
119         if (!conn
120             .getConfig()
121             .checkPrivPath(conn.getUserNull(), newCurrentDirectory)) {
122             return new FtpReply(550, request.getArgument() + ": Not found");
123             // reply identical to FileNotFoundException.getMessage() above
124
}
125
126         if (!newCurrentDirectory.isDirectory()) {
127             return new FtpReply(
128                 550,
129                 request.getArgument() + ": Not a directory");
130         }
131         conn.setCurrentDirectory(newCurrentDirectory);
132
133         FtpReply response =
134             new FtpReply(
135                 250,
136                 "Directory changed to " + newCurrentDirectory.getPath());
137         conn.getConfig().directoryMessage(
138             response,
139             conn.getUserNull(),
140             newCurrentDirectory);
141         try {
142             Collection JavaDoc uploaders =
143                 SiteBot.userSort(newCurrentDirectory.lookupSFVFile().getFiles(), "bytes", "high");
144
145             ReplacerFormat format = null;
146             try {
147                 format = ReplacerUtils.finalFormat(Dir.class, "cwd.uploaders");
148             } catch (FormatterException e1) {
149             }
150             ReplacerEnvironment env =
151                 BaseFtpConnection.getReplacerEnvironment(
152                     null,
153                     conn.getUserNull());
154             for (Iterator JavaDoc iter = uploaders.iterator(); iter.hasNext();) {
155                 UploaderPosition stat = (UploaderPosition) iter.next();
156
157                 User user;
158                 try {
159                     user =
160                         conn.getConnectionManager().getUserManager().getUserByName(stat.getUsername());
161                 } catch (NoSuchUserException e2) {
162                     continue;
163                 } catch (UserFileException e2) {
164                     logger.log(Level.FATAL, "Error reading userfile", e2);
165                     continue;
166                 }
167
168                 env.add("speed", Bytes.formatBytes(stat.getXferspeed())+"/s");
169                 env.add("targetuser", stat.getUsername());
170                 env.add("targetgroup", user.getGroupName());
171                 env.add("files", "" + stat.getFiles());
172                 env.add("bytes", Bytes.formatBytes(stat.getBytes()));
173                 //response.addComment(conn.jprintf(Dir.class.getName(), "cwd.uploaders"));
174
try {
175                     if (format == null) {
176                         response.addComment("cwd.uploaders");
177                     } else {
178                         response.addComment(
179                             ReplacerUtils.finalJprintf(format, env));
180                     }
181                 } catch (FormatterException e) {
182                     response.addComment("cwd.uploaders");
183                 }
184
185             }
186         } catch (RuntimeException JavaDoc ex) {
187             logger.error("", ex);
188         } catch (IOException JavaDoc e) {
189             //Error fetching SFV, ignore
190
} catch (NoAvailableSlaveException e) {
191             //Error fetching SFV, ignore
192
}
193         return response;
194     }
195
196     /**
197      * <code>DELE &lt;SP&gt; &lt;pathname&gt; &lt;CRLF&gt;</code><br>
198      *
199      * This command causes the file specified in the pathname to be
200      * deleted at the server site.
201      */

202     private FtpReply doDELE(BaseFtpConnection conn) {
203         FtpRequest request = conn.getRequest();
204
205         // argument check
206
if (!request.hasArgument()) {
207             //out.print(FtpResponse.RESPONSE_501_SYNTAX_ERROR);
208
return FtpReply.RESPONSE_501_SYNTAX_ERROR;
209         }
210
211         // get filenames
212
String JavaDoc fileName = request.getArgument();
213         LinkedRemoteFile requestedFile;
214         try {
215             //requestedFile = getVirtualDirectory().lookupFile(fileName);
216
requestedFile = conn.getCurrentDirectory().lookupFile(fileName);
217         } catch (FileNotFoundException JavaDoc ex) {
218             return new FtpReply(550, "File not found: " + ex.getMessage());
219         }
220         // check permission
221
if (requestedFile
222             .getUsername()
223             .equals(conn.getUserNull().getUsername())) {
224             if (!conn
225                 .getConfig()
226                 .checkDeleteOwn(conn.getUserNull(), requestedFile)) {
227                 return FtpReply.RESPONSE_530_ACCESS_DENIED;
228             }
229         } else if (
230             !conn.getConfig().checkDelete(conn.getUserNull(), requestedFile)) {
231             return FtpReply.RESPONSE_530_ACCESS_DENIED;
232         }
233
234         FtpReply reply = (FtpReply) FtpReply.RESPONSE_250_ACTION_OKAY.clone();
235
236         User uploader;
237         try {
238             uploader =
239                 conn.getConnectionManager().getUserManager().getUserByName(
240                     requestedFile.getUsername());
241             uploader.updateCredits(
242                 (long) - (requestedFile.length() * uploader.getRatio()));
243         } catch (UserFileException e) {
244             reply.addComment("Error removing credits: " + e.getMessage());
245         } catch (NoSuchUserException e) {
246             reply.addComment("Error removing credits: " + e.getMessage());
247         }
248
249         conn.getConnectionManager().dispatchFtpEvent(
250             new DirectoryFtpEvent(conn.getUserNull(), "DELE", requestedFile));
251         requestedFile.delete();
252         return reply;
253     }
254
255     /**
256      * <code>MDTM &lt;SP&gt; &lt;pathname&gt; &lt;CRLF&gt;</code><br>
257      *
258      * Returns the date and time of when a file was modified.
259      */

260     private FtpReply doMDTM(BaseFtpConnection conn) {
261         FtpRequest request = conn.getRequest();
262         // argument check
263
if (!request.hasArgument()) {
264             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
265         }
266
267         // get filenames
268
String JavaDoc fileName = request.getArgument();
269         LinkedRemoteFile reqFile;
270         try {
271             reqFile = conn.getCurrentDirectory().lookupFile(fileName);
272         } catch (FileNotFoundException JavaDoc ex) {
273             return FtpReply.RESPONSE_550_REQUESTED_ACTION_NOT_TAKEN;
274         }
275         //fileName = user.getVirtualDirectory().getAbsoluteName(fileName);
276
//String physicalName =
277
// user.getVirtualDirectory().getPhysicalName(fileName);
278
//File reqFile = new File(physicalName);
279

280         // now print date
281
//if (reqFile.exists()) {
282
return new FtpReply(
283             213,
284             DATE_FMT.format(new Date JavaDoc(reqFile.lastModified())));
285         //out.print(ftpStatus.getResponse(213, request, user, args));
286
//} else {
287
// out.write(ftpStatus.getResponse(550, request, user, null));
288
//}
289
}
290
291     /**
292      * <code>MKD &lt;SP&gt; &lt;pathname&gt; &lt;CRLF&gt;</code><br>
293      *
294      * This command causes the directory specified in the pathname
295      * to be created as a directory (if the pathname is absolute)
296      * or as a subdirectory of the current working directory (if
297      * the pathname is relative).
298      *
299      *
300      * MKD
301      * 257
302      * 500, 501, 502, 421, 530, 550
303      */

304     private FtpReply doMKD(BaseFtpConnection conn) {
305         FtpRequest request = conn.getRequest();
306
307         // argument check
308
if (!request.hasArgument()) {
309             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
310         }
311         if(!conn.getSlaveManager().hasAvailableSlaves()) {
312             return FtpReply.RESPONSE_450_SLAVE_UNAVAILABLE;
313         }
314         LinkedRemoteFile.NonExistingFile ret =
315             conn.getCurrentDirectory().lookupNonExistingFile(
316                 request.getArgument(), true);
317         LinkedRemoteFile dir = ret.getFile();
318         if(dir.isDeleted()) {
319             dir.setLastModified(System.currentTimeMillis());
320             dir.setOwner(conn.getUserNull().getUsername());
321             dir.setGroup(conn.getUserNull().getGroupName());
322             dir.setDeleted(false);
323             conn.getConnectionManager().dispatchFtpEvent(
324                     new DirectoryFtpEvent(conn.getUserNull(), "MKD", dir));
325             return new FtpReply(
326                     257,
327                     "\"" + dir.getPath() + "\" no longer deleted.");
328         } else {
329
330             if (!ret.hasPath()) {
331                 return new FtpReply(
332                         550,
333                         "Requested action not taken. "
334                         + request.getArgument()
335                         + " already exists");
336             }
337
338             String JavaDoc createdDirName =
339                 conn.getConnectionManager().getConfig().getDirName(ret.getPath());
340             if (!ListUtils.isLegalFileName(createdDirName)) {
341                 return FtpReply.RESPONSE_553_REQUESTED_ACTION_NOT_TAKEN;
342             }
343             if (!conn.getConfig().checkMakeDir(conn.getUserNull(), dir)) {
344                 return FtpReply.RESPONSE_530_ACCESS_DENIED;
345             }
346
347             try {
348                 LinkedRemoteFile createdDir =
349                     dir.createDirectory(
350                             conn.getUserNull().getUsername(),
351                             conn.getUserNull().getGroupName(),
352                             createdDirName);
353                 
354                 conn.getConnectionManager().dispatchFtpEvent(
355                         new DirectoryFtpEvent(conn.getUserNull(), "MKD", createdDir));
356                 return new FtpReply(
357                         257,
358                         "\"" + createdDir.getPath() + "\" created.");
359             } catch (FileExistsException ex) {
360                 return new FtpReply(
361                         550,
362                         "directory " + createdDirName + " already exists");
363             }
364         }
365     }
366
367     /**
368      * <code>PWD &lt;CRLF&gt;</code><br>
369      *
370      * This command causes the name of the current working
371      * directory to be returned in the reply.
372      */

373     private FtpReply doPWD(BaseFtpConnection conn) {
374         return new FtpReply(
375             257,
376             "\""
377                 + conn.getCurrentDirectory().getPath()
378                 + "\" is current directory");
379     }
380
381     /**
382      * <code>RMD &lt;SP&gt; &lt;pathname&gt; &lt;CRLF&gt;</code><br>
383      *
384      * This command causes the directory specified in the pathname
385      * to be removed as a directory (if the pathname is absolute)
386      * or as a subdirectory of the current working directory (if
387      * the pathname is relative).
388      */

389     private FtpReply doRMD(BaseFtpConnection conn) {
390         FtpRequest request = conn.getRequest();
391
392         // argument check
393
if (!request.hasArgument()) {
394             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
395         }
396
397         // get file names
398
String JavaDoc fileName = request.getArgument();
399         LinkedRemoteFile requestedFile;
400         try {
401             requestedFile = conn.getCurrentDirectory().lookupFile(fileName);
402         } catch (FileNotFoundException JavaDoc e) {
403             return new FtpReply(550, fileName + ": " + e.getMessage());
404         }
405
406         if (requestedFile
407             .getUsername()
408             .equals(conn.getUserNull().getUsername())) {
409             if (!conn
410                 .getConfig()
411                 .checkDeleteOwn(conn.getUserNull(), requestedFile)) {
412                 return FtpReply.RESPONSE_530_ACCESS_DENIED;
413             }
414         } else if (
415             !conn.getConfig().checkDelete(conn.getUserNull(), requestedFile)) {
416             return FtpReply.RESPONSE_530_ACCESS_DENIED;
417         }
418
419         if (!requestedFile.isDirectory()) {
420             return new FtpReply(550, fileName + ": Not a directory");
421         }
422         if (requestedFile.dirSize() != 0) {
423             return new FtpReply(550, fileName + ": Directory not empty");
424         }
425
426         // now delete
427
//if (conn.getConfig().checkDirLog(conn.getUserNull(), requestedFile)) {
428
conn.getConnectionManager().dispatchFtpEvent(
429             new DirectoryFtpEvent(conn.getUserNull(), "RMD", requestedFile));
430         //}
431
requestedFile.delete();
432         return FtpReply.RESPONSE_250_ACTION_OKAY;
433     }
434
435     /**
436      * <code>RNFR &lt;SP&gt; &lt;pathname&gt; &lt;CRLF&gt;</code><br>
437      *
438      * This command specifies the old pathname of the file which is
439      * to be renamed. This command must be immediately followed by
440      * a "rename to" command specifying the new file pathname.
441      *
442      * RNFR
443                   450, 550
444                   500, 501, 502, 421, 530
445                   350
446     
447      */

448     private FtpReply doRNFR(BaseFtpConnection conn) {
449         FtpRequest request = conn.getRequest();
450
451         // argument check
452
if (!request.hasArgument()) {
453             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
454         }
455
456         // set state variable
457

458         // get filenames
459
//String fileName = request.getArgument();
460
//fileName = user.getVirtualDirectory().getAbsoluteName(fileName);
461
//mstRenFr = user.getVirtualDirectory().getPhysicalName(fileName);
462

463         try {
464             _renameFrom =
465                 conn.getCurrentDirectory().lookupFile(request.getArgument());
466         } catch (FileNotFoundException JavaDoc e) {
467             return FtpReply.RESPONSE_550_REQUESTED_ACTION_NOT_TAKEN;
468         }
469
470         //check permission
471
if (_renameFrom
472             .getUsername()
473             .equals(conn.getUserNull().getUsername())) {
474             if (!conn
475                 .getConfig()
476                 .checkRenameOwn(conn.getUserNull(), _renameFrom)) {
477                 return FtpReply.RESPONSE_530_ACCESS_DENIED;
478             }
479         } else if (
480             !conn.getConfig().checkRename(conn.getUserNull(), _renameFrom)) {
481             return FtpReply.RESPONSE_530_ACCESS_DENIED;
482         }
483         return new FtpReply(350, "File exists, ready for destination name");
484     }
485
486     /**
487      * <code>RNTO &lt;SP&gt; &lt;pathname&gt; &lt;CRLF&gt;</code><br>
488      *
489      * This command specifies the new pathname of the file
490      * specified in the immediately preceding "rename from"
491      * command. Together the two commands cause a file to be
492      * renamed.
493      */

494     private FtpReply doRNTO(BaseFtpConnection conn) {
495         FtpRequest request = conn.getRequest();
496
497         // argument check
498
if (!request.hasArgument()) {
499             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
500         }
501
502         // set state variables
503
if (_renameFrom == null) {
504             return FtpReply.RESPONSE_503_BAD_SEQUENCE_OF_COMMANDS;
505         }
506
507         NonExistingFile ret =
508             conn.getCurrentDirectory().lookupNonExistingFile(
509                 request.getArgument(), true);
510         LinkedRemoteFileInterface toDir = ret.getFile();
511         String JavaDoc name = ret.getPath();
512         if(toDir.isDeleted()) {
513             return new FtpReply(530, "Target file has been queued for deletion, can't overwrite");
514         }
515
516         LinkedRemoteFileInterface fromFile = _renameFrom;
517
518         if (name == null)
519             name = fromFile.getName();
520         //String to = toDir.getPath() + "/" + name;
521

522         // check permission
523
if (_renameFrom
524             .getUsername()
525             .equals(conn.getUserNull().getUsername())) {
526             if (!conn.getConfig().checkRenameOwn(conn.getUserNull(), toDir)) {
527                 return FtpReply.RESPONSE_530_ACCESS_DENIED;
528             }
529         } else if (!conn.getConfig().checkRename(conn.getUserNull(), toDir)) {
530             return FtpReply.RESPONSE_530_ACCESS_DENIED;
531         }
532
533         try {
534             fromFile.renameTo(toDir.getPath(), name);
535         } catch (IOException JavaDoc e) {
536             logger.warn("", e);
537             return new FtpReply(553, e.getMessage());
538             //return FtpReply.RESPONSE_553_REQUESTED_ACTION_NOT_TAKEN;
539
}
540
541         //out.write(FtpResponse.RESPONSE_250_ACTION_OKAY.toString());
542
return new FtpReply(
543             250,
544             request.getCommand() + " command successfull.");
545     }
546
547     private FtpReply doSITE_CHOWN(BaseFtpConnection conn)
548         throws UnhandledCommandException {
549         FtpRequest req = conn.getRequest();
550         StringTokenizer JavaDoc st =
551             new StringTokenizer JavaDoc(conn.getRequest().getArgument());
552         String JavaDoc owner = st.nextToken();
553         String JavaDoc group = null;
554         int pos = owner.indexOf('.');
555         if (pos != -1) {
556             group = owner.substring(pos + 1);
557             owner = owner.substring(0, pos);
558         } else if ("SITE CHGRP".equals(req.getCommand())) {
559             group = owner;
560             owner = null;
561         } else if (!"SITE CHOWN".equals(req.getCommand())) {
562             throw UnhandledCommandException.create(Dir.class, req);
563         }
564         FtpReply reply = new FtpReply(200);
565
566         while (st.hasMoreTokens()) {
567             try {
568                 LinkedRemoteFileInterface file =
569                     conn.getCurrentDirectory().lookupFile(st.nextToken());
570                 if (owner != null)
571                     file.setOwner(owner);
572                 if (group != null)
573                     file.setGroup(group);
574             } catch (FileNotFoundException JavaDoc e) {
575                 reply.addComment(e.getMessage());
576             }
577         }
578         return FtpReply.RESPONSE_200_COMMAND_OK;
579     }
580
581     /**
582      * USAGE: site wipe [-r] <file/directory>
583      *
584      * This is similar to the UNIX rm command.
585      * In glftpd, if you just delete a file, the uploader loses credits and
586      * upload stats for it. There are many people who didn't like that and
587      * were unable/too lazy to write a shell script to do it for them, so I
588      * wrote this command to get them off my back.
589      *
590      * If the argument is a file, it will simply be deleted. If it's a
591      * directory, it and the files it contains will be deleted. If the
592      * directory contains other directories, the deletion will be aborted.
593      *
594      * To remove a directory containing subdirectories, you need to use
595      * "site wipe -r dirname". BE CAREFUL WHO YOU GIVE ACCESS TO THIS COMMAND.
596      * Glftpd will check if the parent directory of the file/directory you're
597      * trying to delete is writable by its owner. If not, wipe will not
598      * execute, so to protect directories from being wiped, make their parent
599      * 555.
600      *
601      * Also, wipe will only work where you have the right to delete (in
602      * glftpd.conf). Delete right and parent directory's mode of 755/777/etc
603      * will cause glftpd to SWITCH TO ROOT UID and wipe the file/directory.
604      * "site wipe -r /" will not work, but "site wipe -r /incoming" WILL, SO
605      * BE CAREFUL.
606      *
607      * This command will remove the deleted files/directories from the dirlog
608      * and dupefile databases.
609      *
610      * To give access to this command, add "-wipe -user flag =group" to the
611      * config file (similar to other site commands).
612      *
613      * @param request
614      * @param out
615      */

616     private FtpReply doSITE_WIPE(BaseFtpConnection conn) {
617         if (!conn.getUserNull().isAdmin()) {
618             return FtpReply.RESPONSE_530_ACCESS_DENIED;
619         }
620         if (!conn.getRequest().hasArgument()) {
621             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
622         }
623
624         String JavaDoc arg = conn.getRequest().getArgument();
625
626         boolean recursive;
627         if (arg.startsWith("-r ")) {
628             arg = arg.substring(3);
629             recursive = true;
630         } else {
631             recursive = false;
632         }
633
634         LinkedRemoteFile wipeFile;
635         try {
636             wipeFile = conn.getCurrentDirectory().lookupFile(arg);
637         } catch (FileNotFoundException JavaDoc e) {
638             return new FtpReply(
639                 200,
640                 "Can't wipe: "
641                     + arg
642                     + " does not exist or it's not a plain file/directory");
643         }
644         if (wipeFile.isDirectory() && wipeFile.dirSize() != 0 && !recursive) {
645             return new FtpReply(200, "Can't wipe, directory not empty");
646         }
647         //if (conn.getConfig().checkDirLog(conn.getUserNull(), wipeFile)) {
648
conn.getConnectionManager().dispatchFtpEvent(
649             new DirectoryFtpEvent(conn.getUserNull(), "WIPE", wipeFile));
650         //}
651
wipeFile.delete();
652         return FtpReply.RESPONSE_200_COMMAND_OK;
653     }
654
655     /**
656      * <code>SIZE &lt;SP&gt; &lt;pathname&gt; &lt;CRLF&gt;</code><br>
657      *
658      * Returns the size of the file in bytes.
659      */

660     private FtpReply doSIZE(BaseFtpConnection conn) {
661         FtpRequest request = conn.getRequest();
662         if (!request.hasArgument()) {
663             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
664         }
665         LinkedRemoteFile file;
666         try {
667             file = conn.getCurrentDirectory().lookupFile(request.getArgument());
668         } catch (FileNotFoundException JavaDoc ex) {
669             return FtpReply.RESPONSE_550_REQUESTED_ACTION_NOT_TAKEN;
670         }
671         return new FtpReply(213, Long.toString(file.length()));
672     }
673
674     /**
675      * http://www.southrivertech.com/support/titanftp/webhelp/xcrc.htm
676      *
677      * Originally implemented by CuteFTP Pro and Globalscape FTP Server
678      */

679     private FtpReply doXCRC(BaseFtpConnection conn) {
680         FtpRequest request = conn.getRequest();
681         if (!request.hasArgument()) {
682             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
683         }
684         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(request.getArgument());
685         LinkedRemoteFile myFile;
686         try {
687             myFile = conn.getCurrentDirectory().lookupFile(st.nextToken());
688         } catch (FileNotFoundException JavaDoc e) {
689             return FtpReply.RESPONSE_550_REQUESTED_ACTION_NOT_TAKEN;
690         }
691
692         if (st.hasMoreTokens()) {
693             if (!st.nextToken().equals("0")
694                 || !st.nextToken().equals(Long.toString(myFile.length()))) {
695                 return FtpReply.RESPONSE_504_COMMAND_NOT_IMPLEMENTED_FOR_PARM;
696             }
697         }
698         try {
699             return new FtpReply(
700                 250,
701                 "XCRC Successful. "
702                     + Checksum.formatChecksum(myFile.getCheckSum()));
703         } catch (NoAvailableSlaveException e1) {
704             logger.warn("", e1);
705             return new FtpReply(550, "NoAvailableSlaveException: " + e1.getMessage());
706         }
707
708     }
709
710     public FtpReply execute(BaseFtpConnection conn)
711         throws UnhandledCommandException {
712         FtpRequest request = conn.getRequest();
713         String JavaDoc cmd = request.getCommand();
714         if ("CDUP".equals(cmd))
715             return doCDUP(conn);
716         if ("CWD".equals(cmd))
717             return doCWD(conn);
718         if ("MKD".equals(cmd))
719             return doMKD(conn);
720         if ("PWD".equals(cmd))
721             return doPWD(conn);
722         if ("RMD".equals(cmd))
723             return doRMD(conn);
724         if ("RNFR".equals(cmd))
725             return doRNFR(conn);
726         if ("RNTO".equals(cmd))
727             return doRNTO(conn);
728         if ("SITE WIPE".equals(cmd))
729             return doSITE_WIPE(conn);
730         if ("XCRC".equals(cmd))
731             return doXCRC(conn);
732         if ("MDTM".equals(cmd))
733             return doMDTM(conn);
734         if ("SIZE".equals(cmd))
735             return doSIZE(conn);
736         if ("DELE".equals(cmd))
737             return doDELE(conn);
738         if ("SITE CHOWN".equals(cmd) || "SITE CHGRP".equals(cmd))
739             return doSITE_CHOWN(conn);
740         throw UnhandledCommandException.create(Dir.class, request);
741
742     }
743
744     public String JavaDoc[] getFeatReplies() {
745         return null;
746     }
747
748     public CommandHandler initialize(
749         BaseFtpConnection conn,
750         CommandManager initializer) {
751         try {
752             return (Dir) clone();
753         } catch (CloneNotSupportedException JavaDoc e) {
754             throw new RuntimeException JavaDoc(e);
755         }
756     }
757     public void load(CommandManagerFactory initializer) {
758     }
759     public void unload() {
760     }
761 }
762
Popular Tags