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