6f1778b6bd855ae58fb094ad7d12c1d6f6fb04d7
[yazproxy-moved-to-github.git] / src / p2_modules.cpp
1
2 #include <dlfcn.h>
3
4 #include "p2_modules.h"
5
6 class P2_ModuleDLEntry {
7 public:
8     void *m_dl_handle;
9     P2_ModuleEntry *m_entry;
10     P2_ModuleDLEntry();
11     ~P2_ModuleDLEntry();
12 };
13
14 P2_ModuleDLEntry::P2_ModuleDLEntry()
15 {
16     m_dl_handle = 0;
17     m_entry = 0;
18 }
19     
20 P2_ModuleDLEntry::~P2_ModuleDLEntry()
21 {
22     if (m_dl_handle)
23         dlclose(m_dl_handle);
24 }
25     
26 P2_ModuleFactory::P2_ModuleFactory()
27 {
28 }
29
30 P2_ModuleFactory::~P2_ModuleFactory()
31 {
32 }
33
34 bool P2_ModuleFactory::add(P2_ModuleEntry *entry)
35 {
36     P2_ModuleDLEntry *m = new P2_ModuleDLEntry();
37     m->m_entry = entry;
38     m_modules.push_back(m);
39     return true;
40 }
41
42 bool P2_ModuleFactory::add(const char *fname)
43 {
44     void *dl_handle = dlopen(fname, RTLD_NOW|RTLD_GLOBAL);
45     if (!dl_handle)
46         return false;
47
48     P2_ModuleEntry *entry =
49         reinterpret_cast<P2_ModuleEntry *> 
50         (dlsym(dl_handle, "p2_module_entry"));
51     if (!entry)
52     {
53         dlclose(dl_handle);
54         return false;
55     }
56     P2_ModuleDLEntry *m = new P2_ModuleDLEntry();
57     m->m_dl_handle = dl_handle;
58     m->m_entry = entry;
59     m_modules.push_back(m);
60     return true;
61 }
62
63 void *P2_ModuleFactory::get_interface(const char *name, int version)
64 {
65     std::list<P2_ModuleDLEntry *>::const_iterator it;
66     for (it = m_modules.begin();  it != m_modules.end(); it++)
67     {
68         P2_ModuleDLEntry *ent = *it;
69         if (!strcmp(ent->m_entry->name, name) &&
70             ent->m_entry->version == version)
71         {
72             return ent->m_entry->interface_ptr;
73         }
74     }
75     return 0;
76 }
77