001: /*
002: * This file is part of DrFTPD, Distributed FTP Daemon.
003: *
004: * DrFTPD is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * DrFTPD is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with DrFTPD; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018: package net.sf.drftpd.master.command.plugins;
019:
020: import java.io.FileNotFoundException;
021: import java.io.IOException;
022: import java.lang.reflect.Field;
023: import java.net.MalformedURLException;
024: import java.net.URL;
025: import java.util.ArrayList;
026: import java.util.Collections;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030: import java.util.ResourceBundle;
031:
032: import net.sf.drftpd.event.ConnectionEvent;
033: import net.sf.drftpd.event.FtpListener;
034: import net.sf.drftpd.master.BaseFtpConnection;
035: import net.sf.drftpd.master.command.CommandManager;
036: import net.sf.drftpd.master.command.CommandManagerFactory;
037:
038: import org.apache.log4j.Level;
039: import org.apache.log4j.LogManager;
040: import org.apache.log4j.Logger;
041: import org.apache.log4j.helpers.OptionConverter;
042: import org.drftpd.PropertyHelper;
043: import org.drftpd.commands.CommandHandler;
044: import org.drftpd.commands.CommandHandlerFactory;
045: import org.drftpd.commands.Reply;
046: import org.drftpd.commands.ReplyException;
047: import org.drftpd.commands.UnhandledCommandException;
048: import org.drftpd.remotefile.LinkedRemoteFileInterface;
049:
050: /**
051: * @author mog
052: * @author zubov
053: * @version $Id: SiteManagement.java 1256 2005-09-08 21:53:08Z zubov $
054: */
055: public class SiteManagement implements CommandHandler,
056: CommandHandlerFactory {
057: private static final Logger logger = Logger
058: .getLogger(SiteManagement.class);
059:
060: private Reply doSITE_LIST(BaseFtpConnection conn) {
061: if (!conn.getUserNull().isAdmin()) {
062: return Reply.RESPONSE_530_ACCESS_DENIED;
063: }
064:
065: Reply response = (Reply) Reply.RESPONSE_200_COMMAND_OK.clone();
066:
067: // .getMap().values() to get the .isDeleted files as well.
068: LinkedRemoteFileInterface dir = conn.getCurrentDirectory();
069:
070: if (conn.getRequest().hasArgument()) {
071: try {
072: dir = dir.lookupFile(conn.getRequest().getArgument());
073: } catch (FileNotFoundException e) {
074: logger.debug("", e);
075:
076: return new Reply(200, e.getMessage());
077: }
078: }
079:
080: List files;
081: if (dir.isFile()) {
082: files = Collections.singletonList(dir);
083: } else {
084: files = new ArrayList(dir.getMap().values());
085: }
086: Collections.sort(files);
087:
088: for (Iterator iter = files.iterator(); iter.hasNext();) {
089: LinkedRemoteFileInterface file = (LinkedRemoteFileInterface) iter
090: .next();
091:
092: // if (!key.equals(file.getName()))
093: // response.addComment(
094: // "WARN: " + key + " not equals to " + file.getName());
095: // response.addComment(key);
096: response.addComment(file.toString());
097: }
098:
099: return response;
100: }
101:
102: private Reply doSITE_LOADPLUGIN(BaseFtpConnection conn) {
103: if (!conn.getUserNull().isAdmin()) {
104: return Reply.RESPONSE_530_ACCESS_DENIED;
105: }
106:
107: if (!conn.getRequest().hasArgument()) {
108: return new Reply(500, "Usage: site load className");
109: }
110:
111: FtpListener ftpListener = getFtpListener(conn.getRequest()
112: .getArgument());
113:
114: if (ftpListener == null) {
115: return new Reply(500,
116: "Was not able to find the class you are trying to load");
117: }
118:
119: conn.getGlobalContext().addFtpListener(ftpListener);
120:
121: return new Reply(200, "Successfully loaded your plugin");
122: }
123:
124: private Reply doSITE_PLUGINS(BaseFtpConnection conn) {
125: if (!conn.getUserNull().isAdmin()) {
126: return Reply.RESPONSE_530_ACCESS_DENIED;
127: }
128:
129: Reply ftpReply = new Reply(200, "Command ok");
130: ftpReply.addComment("Plugins loaded:");
131: for (FtpListener listener : conn.getGlobalContext()
132: .getFtpListeners()) {
133: ftpReply.addComment(listener.getClass().getName());
134: }
135: return ftpReply;
136: }
137:
138: private Reply doSITE_RELOAD(BaseFtpConnection conn)
139: throws ReplyException {
140: if (!conn.getUserNull().isAdmin()) {
141: return Reply.RESPONSE_530_ACCESS_DENIED;
142: }
143:
144: try {
145: conn.getGlobalContext().getSectionManager().reload();
146: conn.getGlobalContext().reloadFtpConfig();
147: conn.getGlobalContext().getSlaveSelectionManager().reload();
148:
149: try {
150: conn.getGlobalContext().getJobManager().reload();
151: } catch (IllegalStateException e1) {
152: // not loaded, don't reload
153: }
154:
155: conn.getGlobalContext().getConnectionManager()
156: .getCommandManagerFactory().reload();
157:
158: } catch (IOException e) {
159: logger.log(Level.FATAL, "Error reloading config", e);
160:
161: return new Reply(200, e.getMessage());
162: }
163:
164: conn.getGlobalContext().dispatchFtpEvent(
165: new ConnectionEvent(conn.getUserNull(), "RELOAD"));
166:
167: // ugly hack to clear resourcebundle cache
168: // see
169: // http://developer.java.sun.com/developer/bugParade/bugs/4212439.html
170: try {
171: Field cacheList = ResourceBundle.class
172: .getDeclaredField("cacheList");
173: cacheList.setAccessible(true);
174: ((Map) cacheList.get(ResourceBundle.class)).clear();
175: cacheList.setAccessible(false);
176: } catch (Exception e) {
177: logger.error("", e);
178: }
179:
180: try {
181: OptionConverter.selectAndConfigure(new URL(PropertyHelper
182: .getProperty(System.getProperties(),
183: "log4j.configuration")), null, LogManager
184: .getLoggerRepository());
185: } catch (MalformedURLException e) {
186: throw new ReplyException(e);
187: } finally {
188: }
189: return Reply.RESPONSE_200_COMMAND_OK;
190: }
191:
192: private Reply doSITE_SHUTDOWN(BaseFtpConnection conn) {
193: if (!conn.getUserNull().isAdmin()) {
194: return Reply.RESPONSE_530_ACCESS_DENIED;
195: }
196:
197: String message;
198:
199: if (!conn.getRequest().hasArgument()) {
200: message = "Service shutdown issued by "
201: + conn.getUserNull().getName();
202: } else {
203: message = conn.getRequest().getArgument();
204: }
205:
206: conn.getGlobalContext().shutdown(message);
207:
208: return Reply.RESPONSE_200_COMMAND_OK;
209: }
210:
211: private Reply doSITE_UNLOADPLUGIN(BaseFtpConnection conn) {
212: if (!conn.getUserNull().isAdmin()) {
213: return Reply.RESPONSE_530_ACCESS_DENIED;
214: }
215:
216: if (!conn.getRequest().hasArgument()) {
217: return new Reply(500, "Usage: site unload className");
218: }
219: for (FtpListener ftpListener : conn.getGlobalContext()
220: .getFtpListeners()) {
221: if (ftpListener.getClass().getName().equals(
222: "org.drftpd.plugins."
223: + conn.getRequest().getArgument())
224: || ftpListener.getClass().getName().equals(
225: conn.getRequest().getArgument())) {
226: try {
227: ftpListener.unload();
228: } catch (RuntimeException e) {
229: return new Reply(200,
230: "Exception unloading plugin, plugin removed");
231: } finally {
232: conn.getGlobalContext().delFtpListener(ftpListener);
233: }
234: return new Reply(200,
235: "Successfully unloaded your plugin");
236: }
237: }
238:
239: return new Reply(500, "Could not find your plugin on the site");
240: }
241:
242: public Reply execute(BaseFtpConnection conn) throws ReplyException {
243: String cmd = conn.getRequest().getCommand();
244:
245: if ("SITE RELOAD".equals(cmd)) {
246: return doSITE_RELOAD(conn);
247: }
248:
249: if ("SITE SHUTDOWN".equals(cmd)) {
250: return doSITE_SHUTDOWN(conn);
251: }
252:
253: if ("SITE LIST".equals(cmd)) {
254: return doSITE_LIST(conn);
255: }
256:
257: if ("SITE LOADPLUGIN".equals(cmd)) {
258: return doSITE_LOADPLUGIN(conn);
259: }
260:
261: if ("SITE UNLOADPLUGIN".equals(cmd)) {
262: return doSITE_UNLOADPLUGIN(conn);
263: }
264:
265: if ("SITE PLUGINS".equals(cmd)) {
266: return doSITE_PLUGINS(conn);
267: }
268:
269: throw UnhandledCommandException.create(SiteManagement.class,
270: conn.getRequest());
271: }
272:
273: public String[] getFeatReplies() {
274: return null;
275: }
276:
277: private FtpListener getFtpListener(String arg) {
278: FtpListener ftpListener = null;
279:
280: try {
281: ftpListener = (FtpListener) Class.forName(
282: "org.drftpd.plugins." + arg).newInstance();
283: } catch (InstantiationException e) {
284: logger
285: .error(
286: "Was not able to create an instance of the class, did not load",
287: e);
288:
289: return null;
290: } catch (IllegalAccessException e) {
291: logger.error("This will not happen, I do not exist", e);
292: return null;
293: } catch (ClassNotFoundException e) {
294: }
295:
296: if (ftpListener == null) {
297: try {
298: ftpListener = (FtpListener) Class.forName(arg)
299: .newInstance();
300: } catch (InstantiationException e) {
301: logger
302: .error(
303: "Was not able to create an instance of the class, did not load",
304: e);
305:
306: return null;
307: } catch (IllegalAccessException e) {
308: logger.error("This will not happen, I do not exist", e);
309:
310: return null;
311: } catch (ClassNotFoundException e) {
312: return null;
313: }
314: }
315:
316: return ftpListener;
317: }
318:
319: public CommandHandler initialize(BaseFtpConnection conn,
320: CommandManager initializer) {
321: return this ;
322: }
323:
324: public void load(CommandManagerFactory initializer) {
325: }
326:
327: public void unload() {
328: }
329: }
|