1 /* 2 * This file is part of Licq, an instant messaging client for UNIX. 3 * Copyright (C) 2010-2013 Licq developers <licq-dev@googlegroups.com> 4 * 5 * Licq is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * Licq is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with Licq; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 #ifndef LICQDAEMON_PLUGINMANAGER_H 21 #define LICQDAEMON_PLUGINMANAGER_H 22 23 #include <licq/plugin/pluginmanager.h> 24 #include <licq/thread/mutex.h> 25 26 #include "../utils/dynamiclibrary.h" 27 #include "generalplugin.h" 28 #include "generalplugininstance.h" 29 #include "pluginthread.h" 30 #include "protocolplugin.h" 31 #include "protocolplugininstance.h" 32 33 #include <map> 34 #include <queue> 35 36 namespace LicqDaemon 37 { 38 39 class PluginManager : public Licq::PluginManager 40 { 41 public: 42 static const unsigned int MAX_WAIT_PLUGIN = 10; 43 44 PluginManager(); 45 ~PluginManager(); 46 setGuiThread(PluginThread::Ptr guiThread)47 void setGuiThread(PluginThread::Ptr guiThread) { myGuiThread = guiThread; } 48 49 GeneralPlugin::Ptr loadGeneralPlugin( 50 const std::string& name, int argc, char** argv, bool keep = true); 51 ProtocolPlugin::Ptr loadProtocolPlugin( 52 const std::string& name, bool keep = true); 53 54 /// Start all plugins that have been loaded 55 void startAllPlugins(); 56 57 /// Send shutdown signal to all the plugins 58 void shutdownAllPlugins(); 59 60 /// Shutdown specific protocol instance 61 void shutdownProtocolInstance(const Licq::UserId& ownerId); 62 63 /// Notify the manager that a plugin has exited 64 void pluginHasExited(int id); 65 66 /** 67 * Remove a plugin that has exited 68 * Called by main thread when notified about a plugin termination 69 */ 70 void reapPlugin(); 71 72 /// Cancel all plugins' threads. 73 void cancelAllPlugins(); 74 75 size_t getGeneralPluginsCount() const; 76 77 /// Get number of plugins (general and protocol) 78 size_t pluginCount() const; 79 80 /** 81 * Create a protocol specific user object 82 * Wrapper so ProtocolPlugin doesn't have to friend UserManager 83 * Called by UserManager 84 * 85 * @param id User id 86 * @param temporary True if user isn't added permanently to contact list 87 * @return A newly created user object 88 */ 89 Licq::User* createProtocolUser(const Licq::UserId& id, bool temporary = false); 90 91 /** 92 * Create a protocol specific owner object 93 * Wrapper so ProtocolPlugin doesn't have to friend UserManager 94 * 95 * @param id Owner user id 96 * @return A newly created owner object 97 */ 98 Licq::Owner* createProtocolOwner(const Licq::UserId& id); 99 100 // From Licq::PluginManager 101 void getGeneralPluginsList(Licq::GeneralPluginsList& plugins) const; 102 void getProtocolPluginsList(Licq::ProtocolPluginsList& plugins) const; 103 void getAvailableGeneralPlugins(Licq::StringList& plugins, 104 bool includeLoaded = true) const; 105 void getAvailableProtocolPlugins(Licq::StringList& plugins, 106 bool includeLoaded = true) const; 107 Licq::ProtocolPlugin::Ptr getProtocolPlugin(unsigned long protocolId) const; 108 Licq::ProtocolPluginInstance::Ptr getProtocolInstance( 109 const Licq::UserId& ownerId) const; 110 bool startGeneralPlugin(const std::string& name, int argc, char** argv); 111 bool startProtocolPlugin(const std::string& name); 112 void unloadGeneralPlugin(Licq::GeneralPlugin::Ptr plugin); 113 void unloadProtocolPlugin(Licq::ProtocolPlugin::Ptr plugin); 114 void pushPluginEvent(Licq::Event* event); 115 void pushPluginSignal(Licq::PluginSignal* signal); 116 void pushProtocolSignal(Licq::ProtocolSignal* signal); 117 118 private: 119 void getAvailablePlugins(Licq::StringList& plugins, 120 const std::string& prefix) const; 121 122 DynamicLibrary::Ptr loadPlugin(PluginThread::Ptr pluginThread, 123 const std::string& name, 124 const std::string& prefix); 125 bool verifyPluginMagic(const std::string& name, char magic[4]); 126 bool verifyPluginVersion(const std::string& name, int version); 127 int getNewPluginId(); 128 129 void startInstance(GeneralPluginInstance::Ptr instance); 130 void startInstance(ProtocolPluginInstance::Ptr instance); 131 132 bool reapGeneralInstance(int exitId); 133 bool reapProtocolInstance(int exitId); 134 135 int myNextPluginId; 136 PluginThread::Ptr myGuiThread; 137 bool myIsProtocolsStarted; 138 139 mutable Licq::Mutex myGeneralPluginsMutex; 140 std::list<GeneralPlugin::Ptr> myGeneralPlugins; 141 std::list<GeneralPluginInstance::Ptr> myGeneralInstances; 142 143 mutable Licq::Mutex myProtocolPluginsMutex; 144 std::list<ProtocolPlugin::Ptr> myProtocolPlugins; 145 typedef std::map<Licq::UserId, ProtocolPluginInstance::Ptr> 146 ProtocolOwnerInstances; 147 ProtocolOwnerInstances myProtocolInstances; 148 149 Licq::Mutex myExitListMutex; 150 std::queue<int> myExitList; 151 }; 152 153 extern PluginManager gPluginManager; 154 155 } // namespace LicqDaemon 156 157 #endif 158