]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/dynamic.cpp
76efd4b1f388f900e73eabf719ec40a061678d45
[user/henk/code/inspircd.git] / src / dynamic.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 using namespace std;
18
19 #include "configreader.h"
20 #include "dynamic.h"
21
22 #ifndef STATIC_LINK
23 #include <dlfcn.h>
24 #else
25 #include "modlist.h"
26 #endif
27
28 #include "inspircd.h"
29
30 DLLManager::DLLManager(InspIRCd* ServerInstance, const char *fname)
31 {
32         err = NULL;
33
34         if (!strstr(fname,".so"))
35         {
36                 err = "This doesn't look like a module file to me...";
37                 return;
38         }
39 #ifdef STATIC_LINK
40         this->staticname[0] = '\0';
41         ServerInstance->Log(DEBUG,"Loading core-compiled module '%s'",fname);
42         for (int j = 0; modsyms[j].name; j++)
43         {
44                 ServerInstance->Log(DEBUG,"Check %s",modsyms[j].name);
45                 if (!strcmp(modsyms[j].name,fname))
46                 {
47                         ServerInstance->Log(DEBUG,"Found %s",fname);
48                         strlcpy(this->staticname,fname,1020);
49                         err = 0;
50                         return;
51                 }
52         }
53         err = "Module is not statically compiled into the ircd";
54 #else
55         h = dlopen(fname, RTLD_NOW|RTLD_LOCAL);
56         if (!h)
57         {
58                 err = (char*)dlerror();
59                 ServerInstance->Log(DEBUG,"dlerror '%s' occured!", err);
60                 return;
61         }
62
63         ServerInstance->Log(DEBUG,"Finished loading '%s': %0x", fname, h);
64 #endif
65 }
66
67 DLLManager::~DLLManager()
68 {
69 #ifndef STATIC_LINK
70         // close the library if it isn't null
71         if (h)
72                 dlclose(h);
73 #endif
74 }
75
76
77
78 #ifdef STATIC_LINK
79
80 bool DLLManager::GetSymbol(initfunc* &v, const char *sym_name)
81 {
82         for (int j = 0; modsyms[j].name; j++)
83         {
84                 if (!strcmp(this->staticname,modsyms[j].name))
85                 {
86                         v = modsyms[j].value;
87                         err = 0;
88                         return true;
89                 }
90         }
91         err = "Module symbol missing from the core";
92         return false;
93 }
94
95 #else
96
97 bool DLLManager::GetSymbol(void** v, const char* sym_name)
98 {
99         // try extract a symbol from the library
100         // get any error message is there is any
101         
102         if (h)
103         {
104                 dlerror(); // clear value
105                 *v = dlsym(h, sym_name);
106                 err = (char*)dlerror();
107                 if (!*v || err)
108                         return false;
109         }
110         
111         if (err)
112         {
113                 return false;
114         }
115         else
116         {       
117                 return true;
118         }
119 }
120
121 #endif
122
123 DLLFactoryBase::DLLFactoryBase(InspIRCd* Instance, const char* fname, const char* symbol) : DLLManager(Instance, fname)
124 {
125         // try get the factory function if there is no error yet
126         factory_func = 0;
127         
128         if (!LastError())
129         {
130 #ifdef STATIC_LINK
131                 if (!GetSymbol( factory_func, symbol ? symbol : "init_module"))
132 #else
133                 if (!GetSymbol( (void **)&factory_func, symbol ? symbol : "init_module"))
134 #endif
135                 {
136                         throw ModuleException("Missing init_module() entrypoint!");
137                 }
138         }
139 }
140
141 DLLFactoryBase::~DLLFactoryBase()
142 {
143 }
144