Added support for threaded authentication modules. See
[yazproxy-moved-to-github.git] / src / yaz-proxy-config.cpp
index 11ad189..6a5b313 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: yaz-proxy-config.cpp,v 1.18 2005-05-04 08:31:44 adam Exp $
+/* $Id: yaz-proxy-config.cpp,v 1.20 2005-05-30 20:09:21 adam Exp $
    Copyright (c) 1998-2005, Index Data.
 
 This file is part of the yaz-proxy.
@@ -21,97 +21,18 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include <ctype.h>
 
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
 #include <yaz/log.h>
 #include "proxyp.h"
 
-
-class Yaz_ProxyModule {
-private:
-    void *m_dl_handle;                /* dlopen/close handle */
-    Yaz_ProxyModule_entry *m_entry;
-    Yaz_ProxyModule *m_next; 
-    void *m_user_handle;              /* user handle */
-public:
-    Yaz_ProxyModule(void *dl_handle, Yaz_ProxyModule_entry *ent,
-                   Yaz_ProxyModule *next);
-    ~Yaz_ProxyModule();
-    
-    Yaz_ProxyModule *get_next() { return m_next; };
-    int is_module(const char *name);
-    int authenticate(const char *target_name, void *element_ptr,
-                    const char *user, const char *group, const char *password);
-};
-
-int Yaz_ProxyModule::is_module(const char *type)
-{
-    if (!type || !strcmp(m_entry->module_name, type))
-       return 1;
-    return 0;
-}
-
-Yaz_ProxyModule::Yaz_ProxyModule(void *dl_handle, Yaz_ProxyModule_entry *ent,
-                                Yaz_ProxyModule *next)
-{
-    m_dl_handle = dl_handle;
-    m_entry = ent;
-    m_next = next;
-    m_user_handle = 0;
-    if (m_entry->int_version == 0)
-    {
-       struct Yaz_ProxyModule_int0 *int0 =
-           reinterpret_cast<Yaz_ProxyModule_int0 *>(m_entry->fl);
-       if (int0->init)
-           m_user_handle = (*int0->init)();
-    }
-}
-
-Yaz_ProxyModule::~Yaz_ProxyModule()
-{
-    if (m_entry->int_version == 0)
-    {
-       struct Yaz_ProxyModule_int0 *int0 =
-           reinterpret_cast<Yaz_ProxyModule_int0 *>(m_entry->fl);
-       if (int0->destroy)
-           (*int0->destroy)(m_user_handle);
-    }
-#if HAVE_DLFCN_H
-    dlclose(m_dl_handle);
-#endif
-}
-
-int Yaz_ProxyModule::authenticate(const char *name,
-                                 void *element_ptr,
-                                 const char *user, const char *group,
-                                 const char *password)
-{
-    if (m_entry->int_version == 0)
-    {
-       struct Yaz_ProxyModule_int0 *int0 =
-           reinterpret_cast<Yaz_ProxyModule_int0 *>(m_entry->fl);
-       
-       if (!int0->authenticate)
-           return YAZPROXY_RET_NOT_ME;
-       return (*int0->authenticate)(m_user_handle, name, element_ptr,
-                                    user, group, password);
-    }
-    return YAZPROXY_RET_NOT_ME;
-}
-
 class Yaz_ProxyConfigP {
     friend class Yaz_ProxyConfig;
 
-    Yaz_ProxyModule *m_modules;
-
+    Yaz_ProxyModules m_modules;
     int mycmp(const char *hay, const char *item, size_t len);
     int match_list(int v, const char *m);
     int atoi_l(const char **cp);
 #if HAVE_XSLT
     void load_modules(void);
-    void unload_modules(void);
     int check_schema(xmlNodePtr ptr, Z_RecordComposition *comp,
                     const char *schema_identifier);
     xmlDocPtr m_docPtr;
@@ -123,7 +44,7 @@ class Yaz_ProxyConfigP {
                            int *pre_init, const char **cql2rpn,
                            const char **negotiation_charset,
                            const char **negotiation_lang,
-                           const char **query_charset);
+                           const char **target_charset);
     void return_limit(xmlNodePtr ptr,
                      int *limit_bw, int *limit_pdu, int *limit_req);
     int check_type_1(ODR odr, xmlNodePtr ptr, Z_RPNQuery *query,
@@ -143,13 +64,12 @@ class Yaz_ProxyConfigP {
     ~Yaz_ProxyConfigP();
 };
 
-Yaz_ProxyConfigP::Yaz_ProxyConfigP()
+Yaz_ProxyConfigP::Yaz_ProxyConfigP()  : m_modules()
 {
 #if HAVE_XSLT
     m_docPtr = 0;
     m_proxyPtr = 0;
 #endif
-    m_modules = 0;
 }
 
 Yaz_ProxyConfigP::~Yaz_ProxyConfigP()
@@ -162,7 +82,7 @@ Yaz_ProxyConfigP::~Yaz_ProxyConfigP()
 
 Yaz_ProxyConfig::Yaz_ProxyConfig()
 {
-    m_cp = new Yaz_ProxyConfigP;
+    m_cp = new Yaz_ProxyConfigP();
 }
 
 Yaz_ProxyConfig::~Yaz_ProxyConfig()
@@ -171,20 +91,6 @@ Yaz_ProxyConfig::~Yaz_ProxyConfig()
 }
 
 #if HAVE_XSLT
-void Yaz_ProxyConfigP::unload_modules()
-{
-    Yaz_ProxyModule *m = m_modules;
-    while (m)
-    {
-       Yaz_ProxyModule *m_next = m->get_next();
-       delete m;
-       m = m_next;
-    }
-    m_modules = 0;
-}
-#endif
-
-#if HAVE_XSLT
 void Yaz_ProxyConfigP::load_modules()
 {
     if (!m_proxyPtr)
@@ -197,32 +103,7 @@ void Yaz_ProxyConfigP::load_modules()
            && !strcmp((const char *) ptr->name, "module")
            && (fname = get_text(ptr)))
        {
-#if HAVE_DLFCN_H
-           void *dl_handle = dlopen(fname, RTLD_NOW|RTLD_GLOBAL);
-           if (dl_handle)
-           {
-               Yaz_ProxyModule_entry *fl_ptr = 0;
-               fl_ptr = reinterpret_cast<Yaz_ProxyModule_entry *> 
-                   (dlsym(dl_handle, "yazproxy_module"));
-               if (fl_ptr)
-               {
-                   Yaz_ProxyModule *m = new Yaz_ProxyModule(dl_handle,
-                                                            fl_ptr,
-                                                            m_modules);
-                   m_modules = m;
-                   yaz_log(YLOG_LOG, "Loading %s OK", fname);
-               }
-               else
-               {
-                   yaz_log(YLOG_WARN, "Loading %s FAIL: missing yazproxy_module symbol", fname);
-                   dlclose(dl_handle);
-               }
-           }
-           else
-               yaz_log(YLOG_WARN, "Loading %s FAIL: dlopen failed", fname);
-#else
-           yaz_log(YLOG_WARN, "Loading &s FAIL: dl unsupported", fname);
-#endif
+           m_modules.add_module(fname);
        }
     }
 }
@@ -257,7 +138,7 @@ int Yaz_ProxyConfig::read_xml(const char *fname)
        xmlFreeDoc(m_cp->m_docPtr);
     m_cp->m_docPtr = ndoc;
 
-    m_cp->unload_modules();
+    m_cp->m_modules.unload_modules();
     m_cp->load_modules();
     return 0;
 #else
@@ -330,7 +211,7 @@ void Yaz_ProxyConfigP::return_target_info(xmlNodePtr ptr,
                                          const char **cql2rpn,
                                          const char **negotiation_charset,
                                          const char **negotiation_lang,
-                                         const char **query_charset)
+                                         const char **target_charset)
 {
     *pre_init = 0;
     int no_url = 0;
@@ -395,11 +276,11 @@ void Yaz_ProxyConfigP::return_target_info(xmlNodePtr ptr,
                *cql2rpn = t;
        }
        if (ptr->type == XML_ELEMENT_NODE 
-           && !strcmp((const char *) ptr->name, "query-charset"))
+           && !strcmp((const char *) ptr->name, "target-charset"))
        {
            const char *t = get_text(ptr);
-           if (t && query_charset)
-               *query_charset = t;
+           if (t && target_charset)
+               *target_charset = t;
        }
        if (ptr->type == XML_ELEMENT_NODE 
            && !strcmp((const char *) ptr->name, "negotiation-charset"))
@@ -742,16 +623,11 @@ int Yaz_ProxyConfig::client_authentication(const char *name,
                    attr->children && attr->children->type == XML_TEXT_NODE)
                    module_name = (const char *) attr->children->content;
            }
-           Yaz_ProxyModule *m = m_cp->m_modules;
-           for (; m; m = m->get_next())
-           {
-               if (m->is_module(module_name))
-               {
-                   ret = m->authenticate(name, ptr, user, group, password);
-                   if (ret != YAZPROXY_RET_NOT_ME)
-                       break;
-               }
-           }
+           ret = m_cp->m_modules.authenticate(module_name,
+                                              name, ptr,
+                                              user, group, password);
+           if (ret != YAZPROXY_RET_NOT_ME)
+               break;
        }
 #endif
     if (ret == YAZPROXY_RET_PERM)
@@ -1031,7 +907,7 @@ int Yaz_ProxyConfig::get_target_no(int no,
                                   const char **authentication,
                                   const char **negotiation_charset,
                                   const char **negotiation_lang,
-                                  const char **query_charset)
+                                  const char **target_charset)
 {
 #if HAVE_XSLT
     xmlNodePtr ptr;
@@ -1059,7 +935,7 @@ int Yaz_ProxyConfig::get_target_no(int no,
                    target_idletime, client_idletime,
                    keepalive_limit_bw, keepalive_limit_pdu,
                    pre_init, cql2rpn,
-                   negotiation_charset, negotiation_lang, query_charset);
+                   negotiation_charset, negotiation_lang, target_charset);
                return 1;
            }
            i++;
@@ -1259,7 +1135,7 @@ void Yaz_ProxyConfig::get_target_info(const char *name,
                                      const char **cql2rpn,
                                      const char **negotiation_charset,
                                      const char **negotiation_lang,
-                                     const char **query_charset)
+                                     const char **target_charset)
 {
 #if HAVE_XSLT
     xmlNodePtr ptr;
@@ -1297,7 +1173,7 @@ void Yaz_ProxyConfig::get_target_info(const char *name,
                                 keepalive_limit_bw, keepalive_limit_pdu,
                                 pre_init, cql2rpn,
                                 negotiation_charset, negotiation_lang,
-                                query_charset);
+                                target_charset);
     }
 #else
     *url = name;