InspIRCd  3.0
modules.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2009-2010 Daniel De Graaf <[email protected]>
5  * Copyright (C) 2006-2007, 2009 Dennis Friis <[email protected]>
6  * Copyright (C) 2003-2008 Craig Edwards <[email protected]>
7  * Copyright (C) 2008 Thomas Stagner <[email protected]>
8  * Copyright (C) 2007 Robin Burchell <[email protected]>
9  * Copyright (C) 2006-2007 Oliver Lupton <[email protected]>
10  * Copyright (C) 2003 randomdan <[email protected]???>
11  *
12  * This file is part of InspIRCd. InspIRCd is free software: you can
13  * redistribute it and/or modify it under the terms of the GNU General Public
14  * License as published by the Free Software Foundation, version 2.
15  *
16  * This program is distributed in the hope that it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19  * details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24 
25 
26 #pragma once
27 
28 #include "dynamic.h"
29 #include "base.h"
30 #include "ctables.h"
31 #include "inspsocket.h"
32 #include <string>
33 #include <deque>
34 #include <sstream>
35 #include "timer.h"
36 #include "mode.h"
37 
40 enum ModuleFlags {
41  VF_NONE = 0, // module is not special at all
42  VF_VENDOR = 2, // module is a vendor module (came in the original tarball, not 3rd party)
43  VF_COMMON = 4, // module needs to be common on all servers in a network to link
44  VF_OPTCOMMON = 8, // module should be common on all servers for unsurprising behavior
45  VF_CORE = 16 // module is a core command, can be assumed loaded on all servers
46 };
47 
50 enum TargetTypeFlags {
51  TYPE_USER = 1,
52  TYPE_CHANNEL,
53  TYPE_SERVER,
54  TYPE_OTHER
55 };
56 
59 enum MessageType {
60  MSG_PRIVMSG = 0,
61  MSG_NOTICE = 1
62 };
63 
64 #define MOD_RES_ALLOW (ModResult(1))
65 #define MOD_RES_PASSTHRU (ModResult(0))
66 #define MOD_RES_DENY (ModResult(-1))
67 
72 struct ModResult {
73  int res;
74  ModResult() : res(0) {}
75  explicit ModResult(int r) : res(r) {}
76  inline bool operator==(const ModResult& r) const
77  {
78  return res == r.res;
79  }
80  inline bool operator!=(const ModResult& r) const
81  {
82  return res != r.res;
83  }
84  inline bool operator!() const
85  {
86  return !res;
87  }
88  inline bool check(bool def) const
89  {
90  return (res == 1 || (res == 0 && def));
91  }
95  inline ModResult operator+(const ModResult& r) const
96  {
97  if (res == r.res || r.res == 0)
98  return *this;
99  if (res == 0)
100  return r;
101  // they are different, and neither is passthru
102  return MOD_RES_ALLOW;
103  }
104 };
105 
109 #define INSPIRCD_VERSION_MAJ 202
110 
116 #define INSPIRCD_VERSION_API 1
117 
123 #define FOREACH_MOD(y,x) do { \
124  const IntModuleList& _handlers = ServerInstance->Modules->EventHandlers[I_ ## y]; \
125  for (IntModuleList::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
126  { \
127  _next = _i+1; \
128  try \
129  { \
130  (*_i)->y x ; \
131  } \
132  catch (CoreException& modexcept) \
133  { \
134  ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + modexcept.GetReason()); \
135  } \
136  } \
137 } while (0);
138 
145 #define DO_EACH_HOOK(n,v,args) \
146 do { \
147  const IntModuleList& _handlers = ServerInstance->Modules->EventHandlers[I_ ## n]; \
148  for (IntModuleList::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
149  { \
150  _next = _i+1; \
151  try \
152  { \
153  v = (*_i)->n args;
154 
155 #define WHILE_EACH_HOOK(n) \
156  } \
157  catch (CoreException& except_ ## n) \
158  { \
159  ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + (except_ ## n).GetReason()); \
160  } \
161  } \
162 } while(0)
163 
171 #define FIRST_MOD_RESULT(n,v,args) do { \
172  v = MOD_RES_PASSTHRU; \
173  DO_EACH_HOOK(n,v,args) \
174  { \
175  if (v != MOD_RES_PASSTHRU) \
176  break; \
177  } \
178  WHILE_EACH_HOOK(n); \
179 } while (0)
180 
185 class CoreExport Version
186 {
187  public:
190  const std::string description;
191 
194  const int Flags;
195 
197  const std::string link_data;
198 
200  Version(const std::string &desc, int flags = VF_NONE);
201 
203  Version(const std::string &desc, int flags, const std::string& linkdata);
204 };
205 
206 class CoreExport DataProvider : public ServiceProvider
207 {
208  public:
209  DataProvider(Module* Creator, const std::string& Name)
210  : ServiceProvider(Creator, Name, SERVICE_DATA) {}
211 };
212 
215 enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
216 
219 enum Implementation
220 {
221  I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart,
222  I_OnSendSnotice, I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper, I_OnInfo,
223  I_OnUserPreInvite, I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNick,
224  I_OnUserMessage, I_OnMode, I_OnSyncUser,
225  I_OnSyncChannel, I_OnDecodeMetaData, I_OnAcceptConnection, I_OnUserInit,
226  I_OnChangeHost, I_OnChangeName, I_OnAddLine, I_OnDelLine, I_OnExpireLine,
227  I_OnUserPostNick, I_OnPreMode, I_On005Numeric, I_OnKill, I_OnLoadModule,
228  I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite,
229  I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan, I_OnExtBanCheck,
230  I_OnStats, I_OnChangeLocalUserHost, I_OnPreTopicChange,
231  I_OnPostTopicChange, I_OnPostConnect,
232  I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
233  I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnPostCommand, I_OnPostJoin,
234  I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
235  I_OnText, I_OnPassCompare, I_OnNamesListItem, I_OnNumeric,
236  I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent, I_OnSetUserIP,
237  I_END
238 };
239 
245 class CoreExport Module : public classbase, public usecountbase
246 {
250  void DetachEvent(Implementation i);
251 
252  public:
255  std::string ModuleSourceFile;
259 
263  bool dying;
264 
269  Module();
270 
274  virtual void init() {}
275 
279  virtual CullResult cull() CXX11_OVERRIDE;
280 
284  virtual ~Module();
285 
286  virtual void Prioritize()
287  {
288  }
289 
295  virtual void ReadConfig(ConfigStatus& status);
296 
301  virtual Version GetVersion() = 0;
302 
307  virtual void OnUserConnect(LocalUser* user);
308 
317  virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message);
318 
325  virtual void OnUserDisconnect(LocalUser* user);
326 
331  virtual ModResult OnChannelPreDelete(Channel *chan);
332 
336  virtual void OnChannelDelete(Channel* chan);
337 
347  virtual void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except_list);
348 
354  virtual void OnPostJoin(Membership* memb);
355 
363  virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& except_list);
364 
375  virtual void OnPreRehash(User* user, const std::string &parameter);
376 
385  virtual void OnModuleRehash(User* user, const std::string &parameter);
386 
394  virtual ModResult OnSendSnotice(char &snomask, std::string &type, const std::string &message);
395 
416  virtual ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven);
417 
427  virtual ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason);
428 
437  virtual void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list);
438 
445  virtual void OnOper(User* user, const std::string &opertype);
446 
455  virtual void OnPostOper(User* user, const std::string &opername, const std::string &opertype);
456 
467  virtual void OnInfo(User* user);
468 
479  virtual ModResult OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout);
480 
491  virtual void OnUserInvite(User* source, User* dest, Channel* channel, time_t timeout, unsigned int notifyrank, CUList& notifyexcepts);
492 
510  virtual ModResult OnUserPreMessage(User* user,void* dest,int target_type, std::string &text,char status, CUList &exempt_list, MessageType msgtype);
511 
521  virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions);
522 
530  virtual ModResult OnUserPreNick(LocalUser* user, const std::string& newnick);
531 
543  virtual void OnUserMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list, MessageType msgtype);
544 
558  virtual void OnText(User* user, void* dest, int target_type, const std::string &text, char status, CUList &exempt_list);
559 
572  virtual void OnMode(User* user, User* usertarget, Channel* chantarget, const Modes::ChangeList& changelist, ModeParser::ModeProcessFlag processflags, const std::string& output_mode);
573 
582  virtual void OnSyncUser(User* user, ProtocolServer& server);
583 
593  virtual void OnSyncChannel(Channel* chan, ProtocolServer& server);
594 
601  virtual void OnSyncNetwork(ProtocolServer& server);
602 
609  virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
610 
616  virtual void OnChangeHost(User* user, const std::string &newhost);
617 
623  virtual void OnChangeName(User* user, const std::string &gecos);
624 
630  virtual void OnChangeIdent(User* user, const std::string &ident);
631 
637  virtual void OnAddLine(User* source, XLine* line);
638 
644  virtual void OnDelLine(User* source, XLine* line);
645 
650  virtual void OnExpireLine(XLine *line);
651 
661  virtual void OnCleanup(int target_type, void* item);
662 
672  virtual void OnUserPostNick(User* user, const std::string &oldnick);
673 
685  virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes);
686 
691  virtual void On005Numeric(std::map<std::string, std::string>& tokens);
692 
706  virtual ModResult OnKill(User* source, User* dest, const std::string &reason);
707 
719  virtual void OnLoadModule(Module* mod);
720 
732  virtual void OnUnloadModule(Module* mod);
733 
740  virtual void OnBackgroundTimer(time_t curtime);
741 
759  virtual ModResult OnPreCommand(std::string &command, std::vector<std::string>& parameters, LocalUser *user, bool validated, const std::string &original_line);
760 
772  virtual void OnPostCommand(Command* command, const std::vector<std::string>& parameters, LocalUser* user, CmdResult result, const std::string& original_line);
773 
777  virtual void OnUserInit(LocalUser* user);
778 
789  virtual ModResult OnCheckReady(LocalUser* user);
790 
800  virtual ModResult OnUserRegister(LocalUser* user);
801 
810  virtual ModResult OnCheckInvite(User* user, Channel* chan);
811 
823  virtual ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding);
824 
835  virtual ModResult OnCheckKey(User* user, Channel* chan, const std::string &keygiven);
836 
845  virtual ModResult OnCheckLimit(User* user, Channel* chan);
846 
854  virtual ModResult OnCheckChannelBan(User* user, Channel* chan);
855 
864  virtual ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask);
865 
870  virtual ModResult OnExtBanCheck(User* user, Channel* chan, char type);
871 
877  virtual ModResult OnStats(Stats::Context& stats);
878 
885  virtual ModResult OnChangeLocalUserHost(LocalUser* user, const std::string &newhost);
886 
893  virtual ModResult OnChangeLocalUserGECOS(LocalUser* user, const std::string &newhost);
894 
903  virtual ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic);
904 
911  virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
912 
923  virtual ModResult OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype);
924 
931  virtual void OnPostConnect(User* user);
932 
940  virtual ModResult OnAcceptConnection(int fd, ListenSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
941 
950  virtual ModResult OnSetAway(User* user, const std::string &awaymsg);
951 
957  virtual void OnGarbageCollect();
958 
963  virtual ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass);
964 
965 #ifdef INSPIRCD_ENABLE_TESTSUITE
966 
969  virtual void OnRunTestSuite();
970 #endif
971 
982  virtual ModResult OnNamesListItem(User* issuer, Membership* item, std::string& prefixes, std::string& nick);
983 
984  virtual ModResult OnNumeric(User* user, const Numeric::Numeric& numeric);
985 
994  virtual ModResult OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, Membership* memb, Numeric::Numeric& numeric);
995 
1000  virtual void OnSetUserIP(LocalUser* user);
1001 };
1002 
1005 typedef std::vector<Module*> IntModuleList;
1006 
1010 class CoreExport ModuleManager : public fakederef<ModuleManager>
1011 {
1012  public:
1013  typedef std::vector<ServiceProvider*> ServiceList;
1014 
1015  private:
1018  std::string LastModuleError;
1019 
1023  std::map<std::string, Module*> Modules;
1024 
1025  enum {
1026  PRIO_STATE_FIRST,
1027  PRIO_STATE_AGAIN,
1028  PRIO_STATE_LAST
1029  } prioritizationState;
1030 
1033  void LoadCoreModules(std::map<std::string, ServiceList>& servicemap);
1034 
1038  bool PrioritizeHooks();
1039 
1044  void UnregisterModes(Module* mod, ModeType modetype);
1045 
1046  public:
1047  typedef std::map<std::string, Module*> ModuleMap;
1048 
1052  IntModuleList EventHandlers[I_END];
1053 
1055  std::multimap<std::string, ServiceProvider*> DataProviders;
1056 
1065  ServiceList* NewServices;
1066 
1072  static std::string ExpandModName(const std::string& modname);
1073 
1076  ModuleManager();
1077 
1080  ~ModuleManager();
1081 
1098  bool SetPriority(Module* mod, Implementation i, Priority s, Module* which = NULL);
1099 
1108  void SetPriority(Module* mod, Priority s);
1109 
1117  bool Attach(Implementation i, Module* mod);
1118 
1126  bool Detach(Implementation i, Module* mod);
1127 
1133  void Attach(Implementation* i, Module* mod, size_t sz);
1134 
1138  void DetachAll(Module* mod);
1139 
1143  void AttachAll(Module* mod);
1144 
1148  std::string& LastError();
1149 
1155  bool Load(const std::string& filename, bool defer = false);
1156 
1162  bool Unload(Module* module);
1163 
1166  void LoadAll();
1167  void UnloadAll();
1168  void DoSafeUnload(Module*);
1169 
1175  bool CanUnload(Module* mod);
1176 
1182  Module* Find(const std::string &name);
1183 
1185  void AddService(ServiceProvider&);
1186 
1188  void DelService(ServiceProvider&);
1189 
1193  void AddServices(const ServiceList& list);
1194 
1195  inline void AddServices(ServiceProvider** list, int count)
1196  {
1197  for(int i=0; i < count; i++)
1198  AddService(*list[i]);
1199  }
1200 
1204  ServiceProvider* FindService(ServiceType Type, const std::string& name);
1205 
1206  template<typename T> inline T* FindDataService(const std::string& name)
1207  {
1208  return static_cast<T*>(FindService(SERVICE_DATA, name));
1209  }
1210 
1214  const ModuleMap& GetModules() const { return Modules; }
1215 
1220  void AddReferent(const std::string& name, ServiceProvider* service);
1221 
1225  void DelReferent(ServiceProvider* service);
1226 };
1227 
1231 #define MODULE_INIT_STR MODULE_INIT_STR_FN_2(MODULE_INIT_SYM)
1232 #define MODULE_INIT_STR_FN_2(x) MODULE_INIT_STR_FN_1(x)
1233 #define MODULE_INIT_STR_FN_1(x) #x
1234 #define MODULE_INIT_SYM MODULE_INIT_SYM_FN_2(INSPIRCD_VERSION_MAJ, INSPIRCD_VERSION_API)
1235 #define MODULE_INIT_SYM_FN_2(x,y) MODULE_INIT_SYM_FN_1(x,y)
1236 #define MODULE_INIT_SYM_FN_1(x,y) inspircd_module_ ## x ## _ ## y
1237 
1238 #ifdef INSPIRCD_STATIC
1239 
1240 struct AllCommandList {
1241  typedef Command* (*fn)(Module*);
1242  AllCommandList(fn cmd);
1243 };
1244 #define COMMAND_INIT(x) static Command* MK_ ## x(Module* m) { return new x(m); } \
1245  static const AllCommandList PREP_ ## x(&MK_ ## x);
1246 
1247 struct AllModuleList {
1248  typedef Module* (*fn)();
1249  fn init;
1250  std::string name;
1251  AllModuleList(fn mod, const std::string& Name);
1252 };
1253 
1254 #define MODULE_INIT(x) static Module* MK_ ## x() { return new x; } \
1255  static const AllModuleList PREP_ ## x(&MK_ ## x, MODNAME ".so");
1256 
1257 #else
1258 
1263 #ifdef _WIN32
1264 
1265 #define MODULE_INIT(y) \
1266  extern "C" DllExport Module * MODULE_INIT_SYM() \
1267  { \
1268  return new y; \
1269  } \
1270  BOOLEAN WINAPI DllMain(HINSTANCE hDllHandle, DWORD nReason, LPVOID Reserved) \
1271  { \
1272  switch ( nReason ) \
1273  { \
1274  case DLL_PROCESS_ATTACH: \
1275  case DLL_PROCESS_DETACH: \
1276  break; \
1277  } \
1278  return TRUE; \
1279  } \
1280  extern "C" DllExport const char inspircd_src_version[] = INSPIRCD_VERSION;
1281 
1282 #else
1283 
1284 #define MODULE_INIT(y) \
1285  extern "C" DllExport Module * MODULE_INIT_SYM() \
1286  { \
1287  return new y; \
1288  } \
1289  extern "C" DllExport const char inspircd_src_version[] = INSPIRCD_VERSION;
1290 #endif
1291 
1292 #define COMMAND_INIT(c) MODULE_INIT(CommandModule<c>)
1293 
1294 #endif
Definition: modules.h:185
Definition: mode.h:95
Definition: base.h:108
const ModuleMap & GetModules() const
Definition: modules.h:1214
std::multimap< std::string, ServiceProvider * > DataProviders
Definition: modules.h:1055
Definition: numeric.h:29
Definition: extensible.h:90
Definition: users.h:224
bool dying
Definition: modules.h:263
ServiceList * NewServices
Definition: modules.h:1065
Definition: users.h:66
Definition: ctables.h:204
Definition: users.h:742
Definition: socket.h:57
Definition: base.h:41
virtual void init()
Definition: modules.h:274
Definition: membership.h:32
const std::string description
Definition: modules.h:190
Definition: modules.h:1010
const int Flags
Definition: modules.h:194
const std::string link_data
Definition: modules.h:197
Definition: modules.h:245
Definition: modules.h:72
DLLManager * ModuleDLLManager
Definition: modules.h:258
std::string ModuleSourceFile
Definition: modules.h:255
Definition: inspircd.h:59
Definition: dynamic.h:28
Definition: modules.h:206
ModResult operator+(const ModResult &r) const
Definition: modules.h:95
Definition: xline.h:32
Definition: base.h:244
Definition: configreader.h:525
Definition: modechange.h:51
Definition: base.h:31
Definition: socket.h:130
Definition: protocol.h:29
Definition: channels.h:37