]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/dynamic.cpp
e1471a40adf4ce610b8780febfd84b5dbcb72e8f
[user/henk/code/inspircd.git] / src / dynamic.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2004 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 "inspircd_config.h"
20 #include "globals.h"
21 #include "dynamic.h"
22
23 #ifndef STATIC_LINK
24 #include <dlfcn.h>
25 #else
26 #include "modlist.h"
27 #endif
28
29 #include "inspstring.h"
30 #include "helperfuncs.h"
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <stdio.h>
34
35 DLLManager::DLLManager(char *fname)
36 {
37 #ifdef STATIC_LINK
38         this->staticname[0] = '\0';
39         log(DEBUG,"Loading core-compiled module '%s'",fname);
40         for (int j = 0; modsyms[j].name; j++)
41         {
42                 log(DEBUG,"Check %s",modsyms[j].name);
43                 if (!strcmp(modsyms[j].name,fname))
44                 {
45                         log(DEBUG,"Found %s",fname);
46                         strlcpy(this->staticname,fname,1020);
47                         err = 0;
48                         return;
49                 }
50         }
51         err = "Module is not statically compiled into the ircd";
52 #else
53         // Copy the library to a temp location, this makes recompiles
54         // a little safer if the ircd is running at the time as the
55         // shared libraries are mmap()ed and not doing this causes
56         // segfaults.
57         FILE* x = fopen(fname,"rb");
58         char tmpfile_template[255];
59         char buffer[65536];
60         snprintf(tmpfile_template, 255, "/tmp/inspircd_file.so.%d.XXXXXXXXXX",getpid());
61         int fd = mkstemp(tmpfile_template);
62         while (!feof(x))
63         {
64                 int n = fread(buffer, 1, 65535, x);
65                 if (n)
66                         write(fd,buffer,n);
67         }
68         
69         // Try to open the library now and get any error message.
70         
71         h = dlopen(tmpfile_template, RTLD_NOW );
72         err = (char*)dlerror();
73         close(fd);
74 #endif
75 }
76
77 DLLManager::~DLLManager()
78 {
79 #ifndef STATIC_LINK
80         // close the library if it isn't null
81         if (h != 0)
82         dlclose(h);
83 #endif
84 }
85
86
87
88 #ifdef STATIC_LINK
89
90 bool DLLManager::GetSymbol(initfunc* &v, char *sym_name)
91 {
92         log(DEBUG,"Symbol search...");
93         for (int j = 0; modsyms[j].name; j++)
94         {
95                 if (!strcmp(this->staticname,modsyms[j].name))
96                 {
97                         log(DEBUG,"Loading symbol...");
98                         v = modsyms[j].value;
99                         err = 0;
100                         return true;
101                 }
102         }
103         err = "Module symbol missing from the core";
104         return false;
105 }
106
107 #else
108
109 bool DLLManager::GetSymbol(void **v, char *sym_name)
110 {
111         // try extract a symbol from the library
112         // get any error message is there is any
113         
114         if(h != 0)
115         {
116                 *v = dlsym( h, sym_name );
117                 err = (char*)dlerror();
118                 if( err == 0 )
119                         return true;
120                 else
121                         return false;
122         }
123         else
124         {       
125                 return false;
126         }
127 }
128
129 #endif
130
131 DLLFactoryBase::DLLFactoryBase(char *fname, char *factory) : DLLManager(fname)
132 {
133         // try get the factory function if there is no error yet
134         
135         factory_func = 0;
136         
137         if(LastError() == 0)
138         {
139 #ifdef STATIC_LINK
140                 GetSymbol( factory_func, factory ? factory : (char*)"init_module" );
141 #else
142                 GetSymbol( (void **)&factory_func, factory ? factory : (char*)"init_module" );
143 #endif
144         }
145 }
146
147
148 DLLFactoryBase::~DLLFactoryBase()
149 {
150 }