]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/dynamic.cpp
Test-fix for crazy's bug (/who 0 * as oper while on no channels)
[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 "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         // We can delete the tempfile once it's loaded, leaving just the inode.
75         unlink(tmpfile_template);
76 #endif
77 }
78
79 DLLManager::~DLLManager()
80 {
81 #ifndef STATIC_LINK
82         // close the library if it isn't null
83         if (h != 0)
84         dlclose(h);
85 #endif
86 }
87
88
89
90 #ifdef STATIC_LINK
91
92 bool DLLManager::GetSymbol(initfunc* &v, char *sym_name)
93 {
94         log(DEBUG,"Symbol search...");
95         for (int j = 0; modsyms[j].name; j++)
96         {
97                 if (!strcmp(this->staticname,modsyms[j].name))
98                 {
99                         log(DEBUG,"Loading symbol...");
100                         v = modsyms[j].value;
101                         err = 0;
102                         return true;
103                 }
104         }
105         err = "Module symbol missing from the core";
106         return false;
107 }
108
109 #else
110
111 bool DLLManager::GetSymbol(void **v, char *sym_name)
112 {
113         // try extract a symbol from the library
114         // get any error message is there is any
115         
116         if(h != 0)
117         {
118                 *v = dlsym( h, sym_name );
119                 err = (char*)dlerror();
120                 if( err == 0 )
121                         return true;
122                 else
123                         return false;
124         }
125         else
126         {       
127                 return false;
128         }
129 }
130
131 #endif
132
133 DLLFactoryBase::DLLFactoryBase(char *fname, char *factory) : DLLManager(fname)
134 {
135         // try get the factory function if there is no error yet
136         
137         factory_func = 0;
138         
139         if(LastError() == 0)
140         {
141 #ifdef STATIC_LINK
142                 GetSymbol( factory_func, factory ? factory : (char*)"init_module" );
143 #else
144                 GetSymbol( (void **)&factory_func, factory ? factory : (char*)"init_module" );
145 #endif
146         }
147 }
148
149
150 DLLFactoryBase::~DLLFactoryBase()
151 {
152 }