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 202
103 
109 #define INSPIRCD_VERSION_API 1
110 
116 #define FOREACH_MOD(y,x) do { \
117  const IntModuleList& _handlers = ServerInstance->Modules->EventHandlers[I_ ## y]; \
118  for (IntModuleList::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
119  { \
120  _next = _i+1; \
121  try \
122  { \
123  (*_i)->y x ; \
124  } \
125  catch (CoreException& modexcept) \
126  { \
127  ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + modexcept.GetReason()); \
128  } \
129  } \
130 } while (0);
131 
138 #define DO_EACH_HOOK(n,v,args) \
139 do { \
140  const IntModuleList& _handlers = ServerInstance->Modules->EventHandlers[I_ ## n]; \
141  for (IntModuleList::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
142  { \
143  _next = _i+1; \
144  try \
145  { \
146  v = (*_i)->n args;
147 
148 #define WHILE_EACH_HOOK(n) \
149  } \
150  catch (CoreException& except_ ## n) \
151  { \
152  ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + (except_ ## n).GetReason()); \
153  } \
154  } \
155 } while(0)
156 
164 #define FIRST_MOD_RESULT(n,v,args) do { \
165  v = MOD_RES_PASSTHRU; \
166  DO_EACH_HOOK(n,v,args) \
167  { \
168  if (v != MOD_RES_PASSTHRU) \
169  break; \
170  } \
171  WHILE_EACH_HOOK(n); \
172 } while (0)
173 
178 class CoreExport Version
179 {
180  public:
183  const std::string description;
184 
187  const int Flags;
188 
190  const std::string link_data;
191 
193  Version(const std::string &desc, int flags = VF_NONE);
194 
196  Version(const std::string &desc, int flags, const std::string& linkdata);
197 };
198 
199 class CoreExport DataProvider : public ServiceProvider
200 {
201  public:
202  DataProvider(Module* Creator, const std::string& Name)
203  : ServiceProvider(Creator, Name, SERVICE_DATA) {}
204 };
205 
208 enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
209 
212 enum Implementation
213 {
214  I_OnUserConnect, I_OnUserQuit, I_OnUserDisconnect, I_OnUserJoin, I_OnUserPart,
215  I_OnSendSnotice, I_OnUserPreJoin, I_OnUserPreKick, I_OnUserKick, I_OnOper, I_OnInfo,
216  I_OnUserPreInvite, I_OnUserInvite, I_OnUserPreMessage, I_OnUserPreNick,
217  I_OnUserPostMessage, I_OnUserMessageBlocked, I_OnMode,
218  I_OnDecodeMetaData, I_OnAcceptConnection, I_OnUserInit,
219  I_OnChangeHost, I_OnChangeName, I_OnAddLine, I_OnDelLine, I_OnExpireLine,
220  I_OnUserPostNick, I_OnPreMode, I_On005Numeric, I_OnKill, I_OnLoadModule,
221  I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite,
222  I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan, I_OnExtBanCheck,
223  I_OnChangeLocalUserHost, I_OnPreTopicChange,
224  I_OnPostTopicChange, I_OnPostConnect, I_OnPostDeoper,
225  I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
226  I_OnPostOper, I_OnSetAway, I_OnPostCommand, I_OnPostJoin,
227  I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
228  I_OnUserMessage, I_OnPassCompare, I_OnNamesListItem, I_OnNumeric,
229  I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent, I_OnSetUserIP,
230  I_OnServiceAdd, I_OnServiceDel,
231  I_END
232 };
233 
239 class CoreExport Module : public classbase, public usecountbase
240 {
244  void DetachEvent(Implementation i);
245 
246  public:
249  std::string ModuleSourceFile;
253 
257  bool dying;
258 
263  Module();
264 
268  virtual void init() {}
269 
273  CullResult cull() CXX11_OVERRIDE;
274 
278  virtual ~Module();
279 
280  virtual void Prioritize()
281  {
282  }
283 
289  virtual void ReadConfig(ConfigStatus& status);
290 
295  virtual Version GetVersion() = 0;
296 
301  virtual void OnUserConnect(LocalUser* user);
302 
311  virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message);
312 
319  virtual void OnUserDisconnect(LocalUser* user);
320 
325  virtual ModResult OnChannelPreDelete(Channel *chan);
326 
330  virtual void OnChannelDelete(Channel* chan);
331 
341  virtual void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except_list);
342 
348  virtual void OnPostJoin(Membership* memb);
349 
357  virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& except_list);
358 
369  virtual void OnPreRehash(User* user, const std::string &parameter);
370 
379  virtual void OnModuleRehash(User* user, const std::string &parameter);
380 
388  virtual ModResult OnSendSnotice(char &snomask, std::string &type, const std::string &message);
389 
410  virtual ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven);
411 
421  virtual ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason);
422 
431  virtual void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list);
432 
439  virtual void OnOper(User* user, const std::string &opertype);
440 
449  virtual void OnPostOper(User* user, const std::string &opername, const std::string &opertype);
450 
454  virtual void OnPostDeoper(User* user);
455 
466  virtual void OnInfo(User* user);
467 
478  virtual ModResult OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout);
479 
490  virtual void OnUserInvite(User* source, User* dest, Channel* channel, time_t timeout, unsigned int notifyrank, CUList& notifyexcepts);
491 
501  virtual ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details);
502 
512  virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions);
513 
521  virtual ModResult OnUserPreNick(LocalUser* user, const std::string& newnick);
522 
530  virtual void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details);
531 
539  virtual void OnUserMessage(User* user, const MessageTarget& target, const MessageDetails& details);
540 
548  virtual void OnUserMessageBlocked(User* user, const MessageTarget& target, const MessageDetails& details);
549 
562  virtual void OnMode(User* user, User* usertarget, Channel* chantarget, const Modes::ChangeList& changelist, ModeParser::ModeProcessFlag processflags, const std::string& output_mode);
563 
570  virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
571 
577  virtual void OnChangeHost(User* user, const std::string &newhost);
578 
584  virtual void OnChangeName(User* user, const std::string &gecos);
585 
591  virtual void OnChangeIdent(User* user, const std::string &ident);
592 
598  virtual void OnAddLine(User* source, XLine* line);
599 
605  virtual void OnDelLine(User* source, XLine* line);
606 
611  virtual void OnExpireLine(XLine *line);
612 
621  virtual void OnCleanup(ExtensionItem::ExtensibleType type, Extensible* item);
622 
632  virtual void OnUserPostNick(User* user, const std::string &oldnick);
633 
645  virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes);
646 
651  virtual void On005Numeric(std::map<std::string, std::string>& tokens);
652 
666  virtual ModResult OnKill(User* source, User* dest, const std::string &reason);
667 
679  virtual void OnLoadModule(Module* mod);
680 
692  virtual void OnUnloadModule(Module* mod);
693 
700  virtual void OnBackgroundTimer(time_t curtime);
701 
719  virtual ModResult OnPreCommand(std::string &command, std::vector<std::string>& parameters, LocalUser *user, bool validated, const std::string &original_line);
720 
732  virtual void OnPostCommand(Command* command, const std::vector<std::string>& parameters, LocalUser* user, CmdResult result, const std::string& original_line);
733 
737  virtual void OnUserInit(LocalUser* user);
738 
749  virtual ModResult OnCheckReady(LocalUser* user);
750 
760  virtual ModResult OnUserRegister(LocalUser* user);
761 
770  virtual ModResult OnCheckInvite(User* user, Channel* chan);
771 
783  virtual ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding);
784 
795  virtual ModResult OnCheckKey(User* user, Channel* chan, const std::string &keygiven);
796 
805  virtual ModResult OnCheckLimit(User* user, Channel* chan);
806 
814  virtual ModResult OnCheckChannelBan(User* user, Channel* chan);
815 
824  virtual ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask);
825 
830  virtual ModResult OnExtBanCheck(User* user, Channel* chan, char type);
831 
838  virtual ModResult OnChangeLocalUserHost(LocalUser* user, const std::string &newhost);
839 
846  virtual ModResult OnChangeLocalUserGECOS(LocalUser* user, const std::string &newhost);
847 
856  virtual ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic);
857 
864  virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
865 
876  virtual ModResult OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype);
877 
884  virtual void OnPostConnect(User* user);
885 
893  virtual ModResult OnAcceptConnection(int fd, ListenSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
894 
903  virtual ModResult OnSetAway(User* user, const std::string &awaymsg);
904 
910  virtual void OnGarbageCollect();
911 
916  virtual ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass);
917 
918 #ifdef INSPIRCD_ENABLE_TESTSUITE
919 
922  virtual void OnRunTestSuite();
923 #endif
924 
935  virtual ModResult OnNamesListItem(User* issuer, Membership* item, std::string& prefixes, std::string& nick);
936 
937  virtual ModResult OnNumeric(User* user, const Numeric::Numeric& numeric);
938 
947  virtual ModResult OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, Membership* memb, Numeric::Numeric& numeric);
948 
953  virtual void OnSetUserIP(LocalUser* user);
954 
958  virtual void OnServiceAdd(ServiceProvider& service);
959 
963  virtual void OnServiceDel(ServiceProvider& service);
964 };
965 
968 typedef std::vector<Module*> IntModuleList;
969 
973 class CoreExport ModuleManager : public fakederef<ModuleManager>
974 {
975  public:
976  typedef std::vector<ServiceProvider*> ServiceList;
977 
978  private:
981  std::string LastModuleError;
982 
986  std::map<std::string, Module*> Modules;
987 
988  enum {
989  PRIO_STATE_FIRST,
990  PRIO_STATE_AGAIN,
991  PRIO_STATE_LAST
992  } prioritizationState;
993 
996  void LoadCoreModules(std::map<std::string, ServiceList>& servicemap);
997 
1001  bool PrioritizeHooks();
1002 
1007  void UnregisterModes(Module* mod, ModeType modetype);
1008 
1009  public:
1010  typedef std::map<std::string, Module*> ModuleMap;
1011 
1015  IntModuleList EventHandlers[I_END];
1016 
1018  std::multimap<std::string, ServiceProvider*> DataProviders;
1019 
1028  ServiceList* NewServices;
1029 
1035  static std::string ExpandModName(const std::string& modname);
1036 
1039  ModuleManager();
1040 
1043  ~ModuleManager();
1044 
1061  bool SetPriority(Module* mod, Implementation i, Priority s, Module* which = NULL);
1062 
1071  void SetPriority(Module* mod, Priority s);
1072 
1080  bool Attach(Implementation i, Module* mod);
1081 
1089  bool Detach(Implementation i, Module* mod);
1090 
1096  void Attach(Implementation* i, Module* mod, size_t sz);
1097 
1101  void DetachAll(Module* mod);
1102 
1106  void AttachAll(Module* mod);
1107 
1111  std::string& LastError();
1112 
1118  bool Load(const std::string& filename, bool defer = false);
1119 
1125  bool Unload(Module* module);
1126 
1129  void LoadAll();
1130  void UnloadAll();
1131  void DoSafeUnload(Module*);
1132 
1138  bool CanUnload(Module* mod);
1139 
1145  Module* Find(const std::string &name);
1146 
1148  void AddService(ServiceProvider&);
1149 
1151  void DelService(ServiceProvider&);
1152 
1156  void AddServices(const ServiceList& list);
1157 
1158  inline void AddServices(ServiceProvider** list, int count)
1159  {
1160  for(int i=0; i < count; i++)
1161  AddService(*list[i]);
1162  }
1163 
1167  ServiceProvider* FindService(ServiceType Type, const std::string& name);
1168 
1169  template<typename T> inline T* FindDataService(const std::string& name)
1170  {
1171  return static_cast<T*>(FindService(SERVICE_DATA, name));
1172  }
1173 
1177  const ModuleMap& GetModules() const { return Modules; }
1178 
1183  void AddReferent(const std::string& name, ServiceProvider* service);
1184 
1188  void DelReferent(ServiceProvider* service);
1189 };
1190 
1194 #define MODULE_INIT_STR MODULE_INIT_STR_FN_2(MODULE_INIT_SYM)
1195 #define MODULE_INIT_STR_FN_2(x) MODULE_INIT_STR_FN_1(x)
1196 #define MODULE_INIT_STR_FN_1(x) #x
1197 #define MODULE_INIT_SYM MODULE_INIT_SYM_FN_2(INSPIRCD_VERSION_MAJ, INSPIRCD_VERSION_API)
1198 #define MODULE_INIT_SYM_FN_2(x,y) MODULE_INIT_SYM_FN_1(x,y)
1199 #define MODULE_INIT_SYM_FN_1(x,y) inspircd_module_ ## x ## _ ## y
1200 
1201 #ifdef INSPIRCD_STATIC
1202 
1203 struct AllCommandList {
1204  typedef Command* (*fn)(Module*);
1205  AllCommandList(fn cmd);
1206 };
1207 #define COMMAND_INIT(x) static Command* MK_ ## x(Module* m) { return new x(m); } \
1208  static const AllCommandList PREP_ ## x(&MK_ ## x);
1209 
1210 struct AllModuleList {
1211  typedef Module* (*fn)();
1212  fn init;
1213  std::string name;
1214  AllModuleList(fn mod, const std::string& Name);
1215 };
1216 
1217 #define MODULE_INIT(x) static Module* MK_ ## x() { return new x; } \
1218  static const AllModuleList PREP_ ## x(&MK_ ## x, MODNAME ".so");
1219 
1220 #else
1221 
1226 #define MODULE_INIT(y) \
1227  extern "C" DllExport Module * MODULE_INIT_SYM() \
1228  { \
1229  return new y; \
1230  } \
1231  extern "C" DllExport const char inspircd_src_version[] = INSPIRCD_VERSION;
1232 
1233 #define COMMAND_INIT(c) MODULE_INIT(CommandModule<c>)
1234 
1235 #endif
Definition: modules.h:178
Definition: mode.h:95
virtual CullResult cull()
Definition: base.cpp:36
Definition: base.h:108
Definition: message.h:60
ExtensibleType
Definition: extensible.h:41
const ModuleMap & GetModules() const
Definition: modules.h:1177
std::multimap< std::string, ServiceProvider * > DataProviders
Definition: modules.h:1018
Definition: numeric.h:29
Definition: extensible.h:90
Definition: users.h:224
bool dying
Definition: modules.h:257
ServiceList * NewServices
Definition: modules.h:1028
Definition: users.h:66
Definition: ctables.h:207
Definition: users.h:751
Definition: socket.h:57
Definition: message.h:32
Definition: base.h:41
virtual void init()
Definition: modules.h:268
Definition: membership.h:32
const std::string description
Definition: modules.h:183
Definition: modules.h:973
const int Flags
Definition: modules.h:187
const std::string link_data
Definition: modules.h:190
Definition: modules.h:239
Definition: modules.h:65
DLLManager * ModuleDLLManager
Definition: modules.h:252
std::string ModuleSourceFile
Definition: modules.h:249
Definition: inspircd.h:60
Definition: dynamic.h:28
Definition: modules.h:199
ModResult operator+(const ModResult &r) const
Definition: modules.h:88
Definition: xline.h:32
Definition: base.h:244
Definition: configreader.h:503
Definition: modechange.h:51
Definition: base.h:31
Definition: socket.h:130
Definition: channels.h:37