4e7f4739fa8c6a46ee8cc1d83dd97f983e2b5836
[yazproxy-moved-to-github.git] / src / modules.cpp
1 /* $Id: modules.cpp,v 1.1 2005-05-30 20:09:21 adam Exp $
2    Copyright (c) 1998-2005, Index Data.
3
4 This file is part of the yaz-proxy.
5
6 YAZ proxy is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 YAZ proxy is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with YAZ proxy; see the file LICENSE.  If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.
20  */
21
22 #include <string.h>
23 #if HAVE_DLFCN_H
24 #include <dlfcn.h>
25 #endif
26
27 #include <yaz/nmem.h>
28 #include <yazproxy/module.h>
29
30 class Yaz_ProxyModule {
31     friend class Proxy_Msg;
32 private:
33     void *m_dl_handle;                /* dlopen/close handle */
34     Yaz_ProxyModule_entry *m_entry;
35     Yaz_ProxyModule *m_next; 
36     void *m_user_handle;              /* user handle */
37 public:
38     Yaz_ProxyModule(void *dl_handle, Yaz_ProxyModule_entry *ent,
39                     Yaz_ProxyModule *next);
40     ~Yaz_ProxyModule();
41     
42     Yaz_ProxyModule *get_next() { return m_next; };
43     int is_module(const char *name);
44     int authenticate(const char *target_name, void *element_ptr,
45                      const char *user, const char *group, const char *password);
46 };
47
48 int Yaz_ProxyModule::is_module(const char *name)
49 {
50     if (!name || !strcmp(m_entry->module_name, name))
51         return 1;
52     return 0;
53 }
54
55 Yaz_ProxyModule::Yaz_ProxyModule(void *dl_handle, Yaz_ProxyModule_entry *ent,
56                                  Yaz_ProxyModule *next)
57 {
58     m_dl_handle = dl_handle;
59     m_entry = ent;
60     m_next = next;
61     m_user_handle = 0;
62     if (m_entry->int_version == 0)
63     {
64         struct Yaz_ProxyModule_int0 *int0 =
65             reinterpret_cast<Yaz_ProxyModule_int0 *>(m_entry->fl);
66         if (int0->init)
67             m_user_handle = (*int0->init)();
68     }
69 }
70
71 Yaz_ProxyModule::~Yaz_ProxyModule()
72 {
73     if (m_entry->int_version == 0)
74     {
75         struct Yaz_ProxyModule_int0 *int0 =
76             reinterpret_cast<Yaz_ProxyModule_int0 *>(m_entry->fl);
77         if (int0->destroy)
78             (*int0->destroy)(m_user_handle);
79     }
80 #if HAVE_DLFCN_H
81     dlclose(m_dl_handle);
82 #endif
83 }
84
85 int Yaz_ProxyModule::authenticate(const char *name,
86                                   void *element_ptr,
87                                   const char *user, const char *group,
88                                   const char *password)
89 {
90     if (m_entry->int_version == 0)
91     {
92         struct Yaz_ProxyModule_int0 *int0 =
93             reinterpret_cast<Yaz_ProxyModule_int0 *>(m_entry->fl);
94         
95         if (!int0->authenticate)
96             return YAZPROXY_RET_NOT_ME;
97         return (*int0->authenticate)(m_user_handle, name, element_ptr,
98                                      user, group, password);
99     }
100     return YAZPROXY_RET_NOT_ME;
101 }
102
103 Yaz_ProxyModules::Yaz_ProxyModules()
104 {
105     m_list = 0;
106 }
107
108
109 Yaz_ProxyModules::~Yaz_ProxyModules()
110 {
111     unload_modules();
112 }
113
114 void Yaz_ProxyModules::unload_modules()
115 {
116     Yaz_ProxyModule *m = m_list;
117     while (m)
118     {
119         Yaz_ProxyModule *m_next = m->get_next();
120         delete m;
121         m = m_next;
122     }
123     m_list = 0;
124 }
125
126
127 int Yaz_ProxyModules::authenticate(const char *module_name,
128                                    const char *target_name, void *element_ptr,
129                                    const char *user,
130                                    const char *group,
131                                    const char *password)
132 {
133     int ret = YAZPROXY_RET_NOT_ME;
134     Yaz_ProxyModule *m = m_list;
135     for (; m; m = m->get_next())
136     {
137         if (m->is_module(module_name))
138         {
139             ret = m->authenticate(target_name, element_ptr,
140                                        user, group, password);
141             if (ret != YAZPROXY_RET_NOT_ME)
142                 break;
143         }
144     }
145     return ret;
146 }
147
148 int Yaz_ProxyModules::add_module(const char *fname)
149 {
150 #if HAVE_DLFCN_H
151     void *dl_handle = dlopen(fname, RTLD_NOW|RTLD_GLOBAL);
152     if (dl_handle)
153     {
154         Yaz_ProxyModule_entry *fl_ptr = 0;
155         fl_ptr = reinterpret_cast<Yaz_ProxyModule_entry *> 
156             (dlsym(dl_handle, "yazproxy_module"));
157         if (fl_ptr)
158         {
159             Yaz_ProxyModule *m = new Yaz_ProxyModule(dl_handle,
160                                                      fl_ptr,
161                                                      m_list);
162             m_list = m;
163
164             return 0;
165         }
166         else
167         {
168             return -1;
169             dlclose(dl_handle);
170         }
171     }
172     else
173         return -1;
174 #else
175     return -1;
176 #endif
177 }
178