]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/dynamic.cpp
Merge pull request #1157 from SaberUK/insp20+fix-cron-restart
[user/henk/code/inspircd.git] / src / dynamic.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007 Oliver Lupton <oliverlupton@gmail.com>
6  *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
7  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
8  *   Copyright (C) 2003, 2006 Craig Edwards <craigedwards@brainbox.cc>
9  *
10  * This file is part of InspIRCd.  InspIRCd is free software: you can
11  * redistribute it and/or modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation, version 2.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23
24 #include "inspircd.h"
25 #include "dynamic.h"
26 #ifndef _WIN32
27 #include <dlfcn.h>
28 #else
29 #define dlopen(path, state) (void*)LoadLibraryA(path)
30 #define dlsym(handle, export) (void*)GetProcAddress((HMODULE)handle, export)
31 #define dlclose(handle) FreeLibrary((HMODULE)handle)
32 #endif
33
34 DLLManager::DLLManager(const char *fname)
35 {
36         if (!strstr(fname,".so"))
37         {
38                 err = "This doesn't look like a module file to me...";
39                 h = NULL;
40                 return;
41         }
42
43         h = dlopen(fname, RTLD_NOW|RTLD_LOCAL);
44         if (!h)
45         {
46 #ifdef _WIN32
47                 RetrieveLastError();
48 #else
49                 err = dlerror();
50 #endif
51         }
52 }
53
54 DLLManager::~DLLManager()
55 {
56         /* close the library */
57         if (h)
58                 dlclose(h);
59 }
60
61 union init_t {
62         void* vptr;
63         Module* (*fptr)();
64 };
65
66 Module* DLLManager::CallInit()
67 {
68         if (!h)
69                 return NULL;
70
71         init_t initfn;
72         initfn.vptr = dlsym(h, MODULE_INIT_STR);
73         if (!initfn.vptr)
74         {
75 #ifdef _WIN32
76                 RetrieveLastError();
77 #else
78                 err = dlerror();
79 #endif
80                 return NULL;
81         }
82
83         return (*initfn.fptr)();
84 }
85
86 std::string DLLManager::GetVersion()
87 {
88         if (!h)
89                 return "";
90
91         const char* srcver = (char*)dlsym(h, "inspircd_src_version");
92         if (srcver)
93                 return srcver;
94         return "Unversioned module";
95 }
96
97 #ifdef _WIN32
98 void DLLManager::RetrieveLastError()
99 {
100         char errmsg[500];
101         DWORD dwErrorCode = GetLastError();
102         if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)errmsg, _countof(errmsg), NULL) == 0)
103                 sprintf_s(errmsg, _countof(errmsg), "Error code: %u", dwErrorCode);
104         SetLastError(ERROR_SUCCESS);
105         err = errmsg;
106
107         std::string::size_type p;
108         while ((p = err.find_last_of("\r\n")) != std::string::npos)
109                 err.erase(p, 1);
110 }
111 #endif