InspIRCd  3.0
modules.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2019 iwalkalone <[email protected]>
5  * Copyright (C) 2013 Adam <[email protected]>
6  * Copyright (C) 2012-2016, 2018 Attila Molnar <[email protected]>
7  * Copyright (C) 2012-2013, 2016-2020 Sadie Powell <[email protected]>
8  * Copyright (C) 2012 Robby <[email protected]>
9  * Copyright (C) 2009-2010 Daniel De Graaf <[email protected]>
10  * Copyright (C) 2009 Uli Schlachter <[email protected]>
11  * Copyright (C) 2008 Thomas Stagner <[email protected]>
12  * Copyright (C) 2007-2009 Robin Burchell <[email protected]>
13  * Copyright (C) 2007-2008, 2010 Craig Edwards <[email protected]>
14  * Copyright (C) 2007 Oliver Lupton <[email protected]>
15  * Copyright (C) 2007 Dennis Friis <[email protected]>
16  *
17  * This file is part of InspIRCd. InspIRCd is free software: you can
18  * redistribute it and/or modify it under the terms of the GNU General Public
19  * License as published by the Free Software Foundation, version 2.
20  *
21  * This program is distributed in the hope that it will be useful, but WITHOUT
22  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
23  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
24  * details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program. If not, see <http://www.gnu.org/licenses/>.
28  */
29 
30 
31 #pragma once
32 
33 #include "dynamic.h"
34 #include "base.h"
35 #include "ctables.h"
36 #include "inspsocket.h"
37 #include <string>
38 #include <deque>
39 #include <sstream>
40 #include "timer.h"
41 #include "mode.h"
42 
44 enum ModuleFlags
45 {
47  VF_NONE = 0,
48 
50  VF_CORE = 1,
51 
52  /* The module is included with InspIRCd. */
53  VF_VENDOR = 2,
54 
56  VF_COMMON = 4,
57 
59  VF_OPTCOMMON = 8
60 };
61 
62 #define MOD_RES_ALLOW (ModResult(1))
63 #define MOD_RES_PASSTHRU (ModResult(0))
64 #define MOD_RES_DENY (ModResult(-1))
65 
70 struct ModResult {
71  int res;
72  ModResult() : res(0) {}
73  explicit ModResult(int r) : res(r) {}
74  inline bool operator==(const ModResult& r) const
75  {
76  return res == r.res;
77  }
78  inline bool operator!=(const ModResult& r) const
79  {
80  return res != r.res;
81  }
82  inline bool operator!() const
83  {
84  return !res;
85  }
86  inline bool check(bool def) const
87  {
88  return (res == 1 || (res == 0 && def));
89  }
93  inline ModResult operator+(const ModResult& r) const
94  {
95  if (res == r.res || r.res == 0)
96  return *this;
97  if (res == 0)
98  return r;
99  // they are different, and neither is passthru
100  return MOD_RES_ALLOW;
101  }
102 };
103 
107 #define INSPIRCD_VERSION_MAJ 300
108 
115 #define INSPIRCD_VERSION_API 9
116 
122 #define FOREACH_MOD(y,x) do { \
123  const Module::List& _handlers = ServerInstance->Modules->EventHandlers[I_ ## y]; \
124  for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
125  { \
126  _next = _i+1; \
127  try \
128  { \
129  if (!(*_i)->dying) \
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 Module::List& _handlers = ServerInstance->Modules->EventHandlers[I_ ## n]; \
148  for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
149  { \
150  _next = _i+1; \
151  try \
152  { \
153  if (!(*_i)->dying) \
154  v = (*_i)->n args;
155 
156 #define WHILE_EACH_HOOK(n) \
157  } \
158  catch (CoreException& except_ ## n) \
159  { \
160  ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + (except_ ## n).GetReason()); \
161  } \
162  } \
163 } while(0)
164 
172 #define FIRST_MOD_RESULT(n,v,args) do { \
173  v = MOD_RES_PASSTHRU; \
174  DO_EACH_HOOK(n,v,args) \
175  { \
176  if (v != MOD_RES_PASSTHRU) \
177  break; \
178  } \
179  WHILE_EACH_HOOK(n); \
180 } while (0)
181 
186 class CoreExport Version
187 {
188  public:
191  const std::string description;
192 
195  const int Flags;
196 
198  const std::string link_data;
199 
201  Version(const std::string &desc, int flags = VF_NONE);
202 
204  Version(const std::string &desc, int flags, const std::string& linkdata);
205 };
206 
207 class CoreExport DataProvider : public ServiceProvider
208 {
209  public:
210  DataProvider(Module* Creator, const std::string& Name)
211  : ServiceProvider(Creator, Name, SERVICE_DATA) {}
212 };
213 
216 enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
217 
220 enum Implementation
221 {
222  I_OnUserConnect, I_OnUserPreQuit, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart,
223  I_OnSendSnotice, I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper,
224  I_OnUserPreInvite, I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNick,
225  I_OnUserPostMessage, I_OnUserMessageBlocked, I_OnMode, I_OnShutdown,
226  I_OnDecodeMetaData, I_OnAcceptConnection, I_OnUserInit, I_OnUserPostInit,
227  I_OnChangeHost, I_OnChangeRealName, I_OnAddLine, I_OnDelLine, I_OnExpireLine,
228  I_OnUserPostNick, I_OnPreMode, I_On005Numeric, I_OnKill, I_OnLoadModule,
229  I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite,
230  I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan, I_OnExtBanCheck,
231  I_OnPreChangeHost, I_OnPreTopicChange, I_OnConnectionFail,
232  I_OnPostTopicChange, I_OnPostConnect, I_OnPostDeoper,
233  I_OnPreChangeRealName, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
234  I_OnPostOper, I_OnPostCommand, I_OnCommandBlocked, I_OnPostJoin,
235  I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
236  I_OnUserMessage, I_OnPassCompare, I_OnNumeric,
237  I_OnPreRehash, I_OnModuleRehash, I_OnChangeIdent, I_OnSetUserIP,
238  I_OnServiceAdd, I_OnServiceDel, I_OnUserWrite,
239  I_END
240 };
241 
247 class CoreExport Module : public classbase, public usecountbase
248 {
252  void DetachEvent(Implementation i);
253 
254  public:
256  typedef std::vector<Module*> List;
257 
260  std::string ModuleSourceFile;
261 
265 
269  bool dying;
270 
275  Module();
276 
280  virtual void init() {}
281 
285  CullResult cull() CXX11_OVERRIDE;
286 
290  virtual ~Module();
291 
292  virtual void Prioritize()
293  {
294  }
295 
301  virtual void ReadConfig(ConfigStatus& status);
302 
307  virtual Version GetVersion() = 0;
308 
313  virtual void OnUserConnect(LocalUser* user);
314 
323  virtual ModResult OnUserPreQuit(LocalUser* user, std::string& message, std::string& oper_message);
324 
333  virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message);
334 
341  virtual void OnUserDisconnect(LocalUser* user);
342 
347  virtual ModResult OnChannelPreDelete(Channel *chan);
348 
352  virtual void OnChannelDelete(Channel* chan);
353 
363  virtual void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except_list);
364 
370  virtual void OnPostJoin(Membership* memb);
371 
379  virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& except_list);
380 
391  virtual void OnPreRehash(User* user, const std::string &parameter);
392 
401  virtual void OnModuleRehash(User* user, const std::string &parameter);
402 
410  virtual ModResult OnSendSnotice(char &snomask, std::string &type, const std::string &message);
411 
432  virtual ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven);
433 
443  virtual ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason);
444 
453  virtual void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list);
454 
461  virtual void OnOper(User* user, const std::string &opertype);
462 
471  virtual void OnPostOper(User* user, const std::string &opername, const std::string &opertype);
472 
476  virtual void OnPostDeoper(User* user);
477 
488  virtual ModResult OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout);
489 
500  virtual void OnUserInvite(User* source, User* dest, Channel* channel, time_t timeout, unsigned int notifyrank, CUList& notifyexcepts);
501 
511  virtual ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details);
512 
522  virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions);
523 
531  virtual ModResult OnUserPreNick(LocalUser* user, const std::string& newnick);
532 
540  virtual void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details);
541 
549  virtual void OnUserMessage(User* user, const MessageTarget& target, const MessageDetails& details);
550 
558  virtual void OnUserMessageBlocked(User* user, const MessageTarget& target, const MessageDetails& details);
559 
571  virtual void OnMode(User* user, User* usertarget, Channel* chantarget, const Modes::ChangeList& changelist, ModeParser::ModeProcessFlag processflags);
572 
579  virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
580 
586  virtual void OnChangeHost(User* user, const std::string &newhost);
587 
593  virtual void OnChangeRealName(User* user, const std::string& real);
594 
600  virtual void OnChangeIdent(User* user, const std::string &ident);
601 
607  virtual void OnAddLine(User* source, XLine* line);
608 
614  virtual void OnDelLine(User* source, XLine* line);
615 
620  virtual void OnExpireLine(XLine *line);
621 
630  virtual void OnCleanup(ExtensionItem::ExtensibleType type, Extensible* item);
631 
641  virtual void OnUserPostNick(User* user, const std::string &oldnick);
642 
654  virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes);
655 
660  virtual void On005Numeric(std::map<std::string, std::string>& tokens);
661 
675  virtual ModResult OnKill(User* source, User* dest, const std::string &reason);
676 
688  virtual void OnLoadModule(Module* mod);
689 
701  virtual void OnUnloadModule(Module* mod);
702 
709  virtual void OnBackgroundTimer(time_t curtime);
710 
727  virtual ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated);
728 
740  virtual void OnPostCommand(Command* command, const CommandBase::Params& parameters, LocalUser* user, CmdResult result, bool loop);
741 
747  virtual void OnCommandBlocked(const std::string& command, const CommandBase::Params& parameters, LocalUser* user);
748 
755  virtual void OnUserInit(LocalUser* user);
756 
761  virtual void OnUserPostInit(LocalUser* user);
762 
773  virtual ModResult OnCheckReady(LocalUser* user);
774 
784  virtual ModResult OnUserRegister(LocalUser* user);
785 
794  virtual ModResult OnCheckInvite(User* user, Channel* chan);
795 
807  virtual ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding);
808 
819  virtual ModResult OnCheckKey(User* user, Channel* chan, const std::string &keygiven);
820 
829  virtual ModResult OnCheckLimit(User* user, Channel* chan);
830 
838  virtual ModResult OnCheckChannelBan(User* user, Channel* chan);
839 
848  virtual ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask);
849 
854  virtual ModResult OnExtBanCheck(User* user, Channel* chan, char type);
855 
862  virtual ModResult OnPreChangeHost(LocalUser* user, const std::string &newhost);
863 
870  virtual ModResult OnPreChangeRealName(LocalUser* user, const std::string &newhost);
871 
880  virtual ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic);
881 
888  virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
889 
900  virtual ModResult OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype);
901 
908  virtual void OnPostConnect(User* user);
909 
917  virtual ModResult OnAcceptConnection(int fd, ListenSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
918 
924  virtual void OnGarbageCollect();
925 
930  virtual ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass);
931 
932  virtual ModResult OnNumeric(User* user, const Numeric::Numeric& numeric);
933 
938  virtual void OnSetUserIP(LocalUser* user);
939 
943  virtual void OnServiceAdd(ServiceProvider& service);
944 
948  virtual void OnServiceDel(ServiceProvider& service);
949 
956  virtual ModResult OnUserWrite(LocalUser* user, ClientProtocol::Message& msg);
957 
964  virtual ModResult OnConnectionFail(LocalUser* user, BufferedSocketError error);
965 
970  virtual void OnShutdown(const std::string& reason);
971 };
972 
976 class CoreExport ModuleManager : public fakederef<ModuleManager>
977 {
978  public:
979  typedef std::vector<ServiceProvider*> ServiceList;
980 
981  private:
984  std::string LastModuleError;
985 
989  std::map<std::string, Module*> Modules;
990 
991  enum {
992  PRIO_STATE_FIRST,
993  PRIO_STATE_AGAIN,
994  PRIO_STATE_LAST
995  } prioritizationState;
996 
999  void LoadCoreModules(std::map<std::string, ServiceList>& servicemap);
1000 
1004  bool PrioritizeHooks();
1005 
1010  void UnregisterModes(Module* mod, ModeType modetype);
1011 
1012  public:
1013  typedef std::map<std::string, Module*> ModuleMap;
1014 
1018  Module::List EventHandlers[I_END];
1019 
1021  std::multimap<std::string, ServiceProvider*, irc::insensitive_swo> DataProviders;
1022 
1031  ServiceList* NewServices;
1032 
1038  static std::string ExpandModName(const std::string& modname);
1039 
1042  ModuleManager();
1043 
1046  ~ModuleManager();
1047 
1064  bool SetPriority(Module* mod, Implementation i, Priority s, Module* which = NULL);
1065 
1074  void SetPriority(Module* mod, Priority s);
1075 
1083  bool Attach(Implementation i, Module* mod);
1084 
1092  bool Detach(Implementation i, Module* mod);
1093 
1099  void Attach(Implementation* i, Module* mod, size_t sz);
1100 
1104  void DetachAll(Module* mod);
1105 
1109  void AttachAll(Module* mod);
1110 
1114  std::string& LastError();
1115 
1121  bool Load(const std::string& filename, bool defer = false);
1122 
1128  bool Unload(Module* module);
1129 
1132  void LoadAll();
1133  void UnloadAll();
1134  void DoSafeUnload(Module*);
1135 
1141  bool CanUnload(Module* mod);
1142 
1148  Module* Find(const std::string &name);
1149 
1151  void AddService(ServiceProvider&);
1152 
1154  void DelService(ServiceProvider&);
1155 
1159  void AddServices(const ServiceList& list);
1160 
1161  inline void AddServices(ServiceProvider** list, int count)
1162  {
1163  for(int i=0; i < count; i++)
1164  AddService(*list[i]);
1165  }
1166 
1170  ServiceProvider* FindService(ServiceType Type, const std::string& name);
1171 
1172  template<typename T> inline T* FindDataService(const std::string& name)
1173  {
1174  return static_cast<T*>(FindService(SERVICE_DATA, name));
1175  }
1176 
1180  const ModuleMap& GetModules() const { return Modules; }
1181 
1186  void AddReferent(const std::string& name, ServiceProvider* service);
1187 
1191  void DelReferent(ServiceProvider* service);
1192 };
1193 
1197 #define MODULE_INIT_STR MODULE_INIT_STR_FN_2(MODULE_INIT_SYM)
1198 #define MODULE_INIT_STR_FN_2(x) MODULE_INIT_STR_FN_1(x)
1199 #define MODULE_INIT_STR_FN_1(x) #x
1200 #define MODULE_INIT_SYM MODULE_INIT_SYM_FN_2(INSPIRCD_VERSION_MAJ, INSPIRCD_VERSION_API)
1201 #define MODULE_INIT_SYM_FN_2(x,y) MODULE_INIT_SYM_FN_1(x,y)
1202 #define MODULE_INIT_SYM_FN_1(x,y) inspircd_module_ ## x ## _ ## y
1203 
1208 #define MODULE_INIT(y) \
1209  extern "C" DllExport Module * MODULE_INIT_SYM() \
1210  { \
1211  return new y; \
1212  } \
1213  extern "C" DllExport const char inspircd_src_version[] = INSPIRCD_VERSION;
fakederef
Definition: inspircd.h:71
MessageTarget
Definition: message.h:90
Extensible
Definition: extensible.h:139
Module::ModuleDLLManager
DLLManager * ModuleDLLManager
Definition: modules.h:264
ModuleManager::GetModules
const ModuleMap & GetModules() const
Definition: modules.h:1180
Modes::ChangeList
Definition: modechange.h:52
Version::Flags
const int Flags
Definition: modules.h:195
Module::List
std::vector< Module * > List
Definition: modules.h:256
ServiceProvider
Definition: base.h:249
MessageDetails
Definition: message.h:33
ConnectClass
Definition: users.h:75
classbase::cull
virtual CullResult cull()
Definition: base.cpp:41
DataProvider
Definition: modules.h:207
Module::dying
bool dying
Definition: modules.h:269
ModResult::operator+
ModResult operator+(const ModResult &r) const
Definition: modules.h:93
ModResult
Definition: modules.h:70
irc::sockets::sockaddrs
Definition: socket.h:62
Version::link_data
const std::string link_data
Definition: modules.h:198
ModuleManager
Definition: modules.h:976
ModuleManager::NewServices
ServiceList * NewServices
Definition: modules.h:1031
classbase
Definition: base.h:46
Version
Definition: modules.h:186
XLine
Definition: xline.h:36
Version::description
const std::string description
Definition: modules.h:191
Channel
Definition: channels.h:40
ModuleManager::DataProviders
std::multimap< std::string, ServiceProvider *, irc::insensitive_swo > DataProviders
Definition: modules.h:1021
Module::init
virtual void init()
Definition: modules.h:280
Module
Definition: modules.h:247
User
Definition: users.h:233
Command
Definition: ctables.h:224
CullResult
Definition: base.h:36
ClientProtocol::Message
Definition: clientprotocol.h:181
DLLManager
Definition: dynamic.h:31
ExtensionItem::ExtensibleType
ExtensibleType
Definition: extensible.h:39
ListenSocket
Definition: socket.h:173
Numeric::Numeric
Definition: numeric.h:30
usecountbase
Definition: base.h:113
CommandBase::Params
Definition: ctables.h:117
Membership
Definition: membership.h:35
ConfigStatus
Definition: configreader.h:501
Module::ModuleSourceFile
std::string ModuleSourceFile
Definition: modules.h:260
ModeHandler
Definition: mode.h:99
LocalUser
Definition: users.h:727