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 
39 enum ModuleFlags
40 {
42  VF_NONE = 0,
43 
45  VF_CORE = 1,
46 
47  /* The module is included with InspIRCd. */
48  VF_VENDOR = 2,
49 
51  VF_COMMON = 4,
52 
54  VF_OPTCOMMON = 8
55 };
56 
57 #define MOD_RES_ALLOW (ModResult(1))
58 #define MOD_RES_PASSTHRU (ModResult(0))
59 #define MOD_RES_DENY (ModResult(-1))
60 
65 struct ModResult {
66  int res;
67  ModResult() : res(0) {}
68  explicit ModResult(int r) : res(r) {}
69  inline bool operator==(const ModResult& r) const
70  {
71  return res == r.res;
72  }
73  inline bool operator!=(const ModResult& r) const
74  {
75  return res != r.res;
76  }
77  inline bool operator!() const
78  {
79  return !res;
80  }
81  inline bool check(bool def) const
82  {
83  return (res == 1 || (res == 0 && def));
84  }
88  inline ModResult operator+(const ModResult& r) const
89  {
90  if (res == r.res || r.res == 0)
91  return *this;
92  if (res == 0)
93  return r;
94  // they are different, and neither is passthru
95  return MOD_RES_ALLOW;
96  }
97 };
98 
102 #define INSPIRCD_VERSION_MAJ 300
103 
110 #define INSPIRCD_VERSION_API 7
111 
117 #define FOREACH_MOD(y,x) do { \
118  const Module::List& _handlers = ServerInstance->Modules->EventHandlers[I_ ## y]; \
119  for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
120  { \
121  _next = _i+1; \
122  try \
123  { \
124  if (!(*_i)->dying) \
125  (*_i)->y x ; \
126  } \
127  catch (CoreException& modexcept) \
128  { \
129  ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + modexcept.GetReason()); \
130  } \
131  } \
132 } while (0);
133 
140 #define DO_EACH_HOOK(n,v,args) \
141 do { \
142  const Module::List& _handlers = ServerInstance->Modules->EventHandlers[I_ ## n]; \
143  for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
144  { \
145  _next = _i+1; \
146  try \
147  { \
148  if (!(*_i)->dying) \
149  v = (*_i)->n args;
150 
151 #define WHILE_EACH_HOOK(n) \
152  } \
153  catch (CoreException& except_ ## n) \
154  { \
155  ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + (except_ ## n).GetReason()); \
156  } \
157  } \
158 } while(0)
159 
167 #define FIRST_MOD_RESULT(n,v,args) do { \
168  v = MOD_RES_PASSTHRU; \
169  DO_EACH_HOOK(n,v,args) \
170  { \
171  if (v != MOD_RES_PASSTHRU) \
172  break; \
173  } \
174  WHILE_EACH_HOOK(n); \
175 } while (0)
176 
181 class CoreExport Version
182 {
183  public:
186  const std::string description;
187 
190  const int Flags;
191 
193  const std::string link_data;
194 
196  Version(const std::string &desc, int flags = VF_NONE);
197 
199  Version(const std::string &desc, int flags, const std::string& linkdata);
200 };
201 
202 class CoreExport DataProvider : public ServiceProvider
203 {
204  public:
205  DataProvider(Module* Creator, const std::string& Name)
206  : ServiceProvider(Creator, Name, SERVICE_DATA) {}
207 };
208 
211 enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
212 
215 enum Implementation
216 {
217  I_OnUserConnect, I_OnUserPreQuit, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart,
218  I_OnSendSnotice, I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper,
219  I_OnUserPreInvite, I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNick,
220  I_OnUserPostMessage, I_OnUserMessageBlocked, I_OnMode, I_OnShutdown,
221  I_OnDecodeMetaData, I_OnAcceptConnection, I_OnUserInit, I_OnUserPostInit,
222  I_OnChangeHost, I_OnChangeRealName, I_OnAddLine, I_OnDelLine, I_OnExpireLine,
223  I_OnUserPostNick, I_OnPreMode, I_On005Numeric, I_OnKill, I_OnLoadModule,
224  I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite,
225  I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan, I_OnExtBanCheck,
226  I_OnPreChangeHost, I_OnPreTopicChange, I_OnConnectionFail,
227  I_OnPostTopicChange, I_OnPostConnect, I_OnPostDeoper,
228  I_OnPreChangeRealName, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
229  I_OnPostOper, I_OnPostCommand, I_OnPostJoin,
230  I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
231  I_OnUserMessage, I_OnPassCompare, I_OnNumeric,
232  I_OnPreRehash, I_OnModuleRehash, I_OnChangeIdent, I_OnSetUserIP,
233  I_OnServiceAdd, I_OnServiceDel, I_OnUserWrite,
234  I_END
235 };
236 
242 class CoreExport Module : public classbase, public usecountbase
243 {
247  void DetachEvent(Implementation i);
248 
249  public:
251  typedef std::vector<Module*> List;
252 
255  std::string ModuleSourceFile;
256 
260 
264  bool dying;
265 
270  Module();
271 
275  virtual void init() {}
276 
280  CullResult cull() CXX11_OVERRIDE;
281 
285  virtual ~Module();
286 
287  virtual void Prioritize()
288  {
289  }
290 
296  virtual void ReadConfig(ConfigStatus& status);
297 
302  virtual Version GetVersion() = 0;
303 
308  virtual void OnUserConnect(LocalUser* user);
309 
318  virtual ModResult OnUserPreQuit(LocalUser* user, std::string& message, std::string& oper_message);
319 
328  virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message);
329 
336  virtual void OnUserDisconnect(LocalUser* user);
337 
342  virtual ModResult OnChannelPreDelete(Channel *chan);
343 
347  virtual void OnChannelDelete(Channel* chan);
348 
358  virtual void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except_list);
359 
365  virtual void OnPostJoin(Membership* memb);
366 
374  virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& except_list);
375 
386  virtual void OnPreRehash(User* user, const std::string &parameter);
387 
396  virtual void OnModuleRehash(User* user, const std::string &parameter);
397 
405  virtual ModResult OnSendSnotice(char &snomask, std::string &type, const std::string &message);
406 
427  virtual ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven);
428 
438  virtual ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason);
439 
448  virtual void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list);
449 
456  virtual void OnOper(User* user, const std::string &opertype);
457 
466  virtual void OnPostOper(User* user, const std::string &opername, const std::string &opertype);
467 
471  virtual void OnPostDeoper(User* user);
472 
483  virtual ModResult OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout);
484 
495  virtual void OnUserInvite(User* source, User* dest, Channel* channel, time_t timeout, unsigned int notifyrank, CUList& notifyexcepts);
496 
506  virtual ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details);
507 
517  virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions);
518 
526  virtual ModResult OnUserPreNick(LocalUser* user, const std::string& newnick);
527 
535  virtual void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details);
536 
544  virtual void OnUserMessage(User* user, const MessageTarget& target, const MessageDetails& details);
545 
553  virtual void OnUserMessageBlocked(User* user, const MessageTarget& target, const MessageDetails& details);
554 
566  virtual void OnMode(User* user, User* usertarget, Channel* chantarget, const Modes::ChangeList& changelist, ModeParser::ModeProcessFlag processflags);
567 
574  virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
575 
581  virtual void OnChangeHost(User* user, const std::string &newhost);
582 
588  virtual void OnChangeRealName(User* user, const std::string& real);
589 
595  virtual void OnChangeIdent(User* user, const std::string &ident);
596 
602  virtual void OnAddLine(User* source, XLine* line);
603 
609  virtual void OnDelLine(User* source, XLine* line);
610 
615  virtual void OnExpireLine(XLine *line);
616 
625  virtual void OnCleanup(ExtensionItem::ExtensibleType type, Extensible* item);
626 
636  virtual void OnUserPostNick(User* user, const std::string &oldnick);
637 
649  virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes);
650 
655  virtual void On005Numeric(std::map<std::string, std::string>& tokens);
656 
670  virtual ModResult OnKill(User* source, User* dest, const std::string &reason);
671 
683  virtual void OnLoadModule(Module* mod);
684 
696  virtual void OnUnloadModule(Module* mod);
697 
704  virtual void OnBackgroundTimer(time_t curtime);
705 
722  virtual ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated);
723 
735  virtual void OnPostCommand(Command* command, const CommandBase::Params& parameters, LocalUser* user, CmdResult result, bool loop);
736 
743  virtual void OnUserInit(LocalUser* user);
744 
749  virtual void OnUserPostInit(LocalUser* user);
750 
761  virtual ModResult OnCheckReady(LocalUser* user);
762 
772  virtual ModResult OnUserRegister(LocalUser* user);
773 
782  virtual ModResult OnCheckInvite(User* user, Channel* chan);
783 
795  virtual ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding);
796 
807  virtual ModResult OnCheckKey(User* user, Channel* chan, const std::string &keygiven);
808 
817  virtual ModResult OnCheckLimit(User* user, Channel* chan);
818 
826  virtual ModResult OnCheckChannelBan(User* user, Channel* chan);
827 
836  virtual ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask);
837 
842  virtual ModResult OnExtBanCheck(User* user, Channel* chan, char type);
843 
850  virtual ModResult OnPreChangeHost(LocalUser* user, const std::string &newhost);
851 
858  virtual ModResult OnPreChangeRealName(LocalUser* user, const std::string &newhost);
859 
868  virtual ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic);
869 
876  virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
877 
888  virtual ModResult OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype);
889 
896  virtual void OnPostConnect(User* user);
897 
905  virtual ModResult OnAcceptConnection(int fd, ListenSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
906 
912  virtual void OnGarbageCollect();
913 
918  virtual ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass);
919 
920  virtual ModResult OnNumeric(User* user, const Numeric::Numeric& numeric);
921 
926  virtual void OnSetUserIP(LocalUser* user);
927 
931  virtual void OnServiceAdd(ServiceProvider& service);
932 
936  virtual void OnServiceDel(ServiceProvider& service);
937 
944  virtual ModResult OnUserWrite(LocalUser* user, ClientProtocol::Message& msg);
945 
952  virtual ModResult OnConnectionFail(LocalUser* user, BufferedSocketError error);
953 
958  virtual void OnShutdown(const std::string& reason);
959 };
960 
964 class CoreExport ModuleManager : public fakederef<ModuleManager>
965 {
966  public:
967  typedef std::vector<ServiceProvider*> ServiceList;
968 
969  private:
972  std::string LastModuleError;
973 
977  std::map<std::string, Module*> Modules;
978 
979  enum {
980  PRIO_STATE_FIRST,
981  PRIO_STATE_AGAIN,
982  PRIO_STATE_LAST
983  } prioritizationState;
984 
987  void LoadCoreModules(std::map<std::string, ServiceList>& servicemap);
988 
992  bool PrioritizeHooks();
993 
998  void UnregisterModes(Module* mod, ModeType modetype);
999 
1000  public:
1001  typedef std::map<std::string, Module*> ModuleMap;
1002 
1006  Module::List EventHandlers[I_END];
1007 
1009  std::multimap<std::string, ServiceProvider*, irc::insensitive_swo> DataProviders;
1010 
1019  ServiceList* NewServices;
1020 
1026  static std::string ExpandModName(const std::string& modname);
1027 
1030  ModuleManager();
1031 
1034  ~ModuleManager();
1035 
1052  bool SetPriority(Module* mod, Implementation i, Priority s, Module* which = NULL);
1053 
1062  void SetPriority(Module* mod, Priority s);
1063 
1071  bool Attach(Implementation i, Module* mod);
1072 
1080  bool Detach(Implementation i, Module* mod);
1081 
1087  void Attach(Implementation* i, Module* mod, size_t sz);
1088 
1092  void DetachAll(Module* mod);
1093 
1097  void AttachAll(Module* mod);
1098 
1102  std::string& LastError();
1103 
1109  bool Load(const std::string& filename, bool defer = false);
1110 
1116  bool Unload(Module* module);
1117 
1120  void LoadAll();
1121  void UnloadAll();
1122  void DoSafeUnload(Module*);
1123 
1129  bool CanUnload(Module* mod);
1130 
1136  Module* Find(const std::string &name);
1137 
1139  void AddService(ServiceProvider&);
1140 
1142  void DelService(ServiceProvider&);
1143 
1147  void AddServices(const ServiceList& list);
1148 
1149  inline void AddServices(ServiceProvider** list, int count)
1150  {
1151  for(int i=0; i < count; i++)
1152  AddService(*list[i]);
1153  }
1154 
1158  ServiceProvider* FindService(ServiceType Type, const std::string& name);
1159 
1160  template<typename T> inline T* FindDataService(const std::string& name)
1161  {
1162  return static_cast<T*>(FindService(SERVICE_DATA, name));
1163  }
1164 
1168  const ModuleMap& GetModules() const { return Modules; }
1169 
1174  void AddReferent(const std::string& name, ServiceProvider* service);
1175 
1179  void DelReferent(ServiceProvider* service);
1180 };
1181 
1185 #define MODULE_INIT_STR MODULE_INIT_STR_FN_2(MODULE_INIT_SYM)
1186 #define MODULE_INIT_STR_FN_2(x) MODULE_INIT_STR_FN_1(x)
1187 #define MODULE_INIT_STR_FN_1(x) #x
1188 #define MODULE_INIT_SYM MODULE_INIT_SYM_FN_2(INSPIRCD_VERSION_MAJ, INSPIRCD_VERSION_API)
1189 #define MODULE_INIT_SYM_FN_2(x,y) MODULE_INIT_SYM_FN_1(x,y)
1190 #define MODULE_INIT_SYM_FN_1(x,y) inspircd_module_ ## x ## _ ## y
1191 
1196 #define MODULE_INIT(y) \
1197  extern "C" DllExport Module * MODULE_INIT_SYM() \
1198  { \
1199  return new y; \
1200  } \
1201  extern "C" DllExport const char inspircd_src_version[] = INSPIRCD_VERSION;
fakederef
Definition: inspircd.h:65
MessageTarget
Definition: message.h:89
Extensible
Definition: extensible.h:136
Module::ModuleDLLManager
DLLManager * ModuleDLLManager
Definition: modules.h:259
ModuleManager::GetModules
const ModuleMap & GetModules() const
Definition: modules.h:1168
Modes::ChangeList
Definition: modechange.h:51
Version::Flags
const int Flags
Definition: modules.h:190
Module::List
std::vector< Module * > List
Definition: modules.h:251
ServiceProvider
Definition: base.h:244
MessageDetails
Definition: message.h:32
ConnectClass
Definition: users.h:66
classbase::cull
virtual CullResult cull()
Definition: base.cpp:36
DataProvider
Definition: modules.h:202
Module::dying
bool dying
Definition: modules.h:264
ModResult::operator+
ModResult operator+(const ModResult &r) const
Definition: modules.h:88
ModResult
Definition: modules.h:65
irc::sockets::sockaddrs
Definition: socket.h:58
Version::link_data
const std::string link_data
Definition: modules.h:193
ModuleManager
Definition: modules.h:964
ModuleManager::NewServices
ServiceList * NewServices
Definition: modules.h:1019
classbase
Definition: base.h:41
Version
Definition: modules.h:181
XLine
Definition: xline.h:32
Version::description
const std::string description
Definition: modules.h:186
Channel
Definition: channels.h:37
ModuleManager::DataProviders
std::multimap< std::string, ServiceProvider *, irc::insensitive_swo > DataProviders
Definition: modules.h:1009
Module::init
virtual void init()
Definition: modules.h:275
Module
Definition: modules.h:242
User
Definition: users.h:224
Command
Definition: ctables.h:221
CullResult
Definition: base.h:31
ClientProtocol::Message
Definition: clientprotocol.h:180
DLLManager
Definition: dynamic.h:28
ExtensionItem::ExtensibleType
ExtensibleType
Definition: extensible.h:36
ListenSocket
Definition: socket.h:147
Numeric::Numeric
Definition: numeric.h:29
usecountbase
Definition: base.h:108
CommandBase::Params
Definition: ctables.h:114
Membership
Definition: membership.h:32
ConfigStatus
Definition: configreader.h:494
Module::ModuleSourceFile
std::string ModuleSourceFile
Definition: modules.h:255
ModeHandler
Definition: mode.h:95
LocalUser
Definition: users.h:718