X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fmodule.c;h=b9e3ff5a6ce32592c1ad8d1ff6ca60f46eea4d07;hb=dbaf7c5c2503b2770c9075e30a9a63b6ff577d6f;hp=71d93a300fa65d8987286b60c8b713b3921a58b1;hpb=eaaea51b538450656e746708732cfd36f45f77e7;p=openldap diff --git a/servers/slapd/module.c b/servers/slapd/module.c index 71d93a300f..b9e3ff5a6c 100644 --- a/servers/slapd/module.c +++ b/servers/slapd/module.c @@ -1,4 +1,18 @@ /* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2006 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + #include "portable.h" #include #include "slap.h" @@ -7,34 +21,50 @@ #include -int load_null (const void *module, const char *file_name); -int load_extension (const void *module, const char *file_name); +typedef int (*MODULE_INIT_FN)( + int argc, + char *argv[]); +typedef int (*MODULE_LOAD_FN)( + const void *module, + const char *filename); +typedef int (*MODULE_TERM_FN)(void); + struct module_regtable_t { char *type; - int (*proc)(const void *module, const char *file_name); + MODULE_LOAD_FN proc; } module_regtable[] = { - { "null", load_null }, + { "null", load_null_module }, #ifdef SLAPD_EXTERNAL_EXTENSIONS - { "extension", load_extension }, + { "extension", load_extop_module }, #endif - { NULL, NULL } - }; + { NULL, NULL } +}; typedef struct module_loaded_t { struct module_loaded_t *next; - lt_dlhandle *lib; + lt_dlhandle lib; } module_loaded_t; module_loaded_t *module_list = NULL; -int module_unload (module_loaded_t *module); +static int module_unload (module_loaded_t *module); + +#ifdef HAVE_EBCDIC +static char ebuf[BUFSIZ]; +#endif int module_init (void) { if (lt_dlinit()) { const char *error = lt_dlerror(); +#ifdef HAVE_EBCDIC + strcpy( ebuf, error ); + __etoa( ebuf ); + error = ebuf; +#endif Debug(LDAP_DEBUG_ANY, "lt_dlinit failed: %s\n", error, 0, 0); + return -1; } return 0; @@ -49,7 +79,13 @@ int module_kill (void) if (lt_dlexit()) { const char *error = lt_dlerror(); +#ifdef HAVE_EBCDIC + strcpy( ebuf, error ); + __etoa( ebuf ); + error = ebuf; +#endif Debug(LDAP_DEBUG_ANY, "lt_dlexit failed: %s\n", error, 0, 0); + return -1; } return 0; @@ -60,33 +96,57 @@ int module_load(const char* file_name, int argc, char *argv[]) module_loaded_t *module = NULL; const char *error; int rc; - int (*initialize) LDAP_P((int argc, char *argv[])); + MODULE_INIT_FN initialize; +#ifdef HAVE_EBCDIC +#define file ebuf +#else +#define file file_name +#endif module = (module_loaded_t *)ch_calloc(1, sizeof(module_loaded_t)); if (module == NULL) { Debug(LDAP_DEBUG_ANY, "module_load failed: (%s) out of memory\n", file_name, 0, 0); + return -1; } +#ifdef HAVE_EBCDIC + strcpy( file, file_name ); + __atoe( file ); +#endif /* * The result of lt_dlerror(), when called, must be cached prior * to calling Debug. This is because Debug is a macro that expands * into multiple function calls. */ - if ((module->lib = lt_dlopen(file_name)) == NULL) { + if ((module->lib = lt_dlopenext(file)) == NULL) { error = lt_dlerror(); - Debug(LDAP_DEBUG_ANY, "lt_dlopen failed: (%s) %s\n", file_name, +#ifdef HAVE_EBCDIC + strcpy( ebuf, error ); + __etoa( ebuf ); + error = ebuf; +#endif + Debug(LDAP_DEBUG_ANY, "lt_dlopenext failed: (%s) %s\n", file_name, error, 0); + ch_free(module); return -1; } Debug(LDAP_DEBUG_CONFIG, "loaded module %s\n", file_name, 0, 0); + +#ifdef HAVE_EBCDIC +#pragma convlit(suspend) +#endif if ((initialize = lt_dlsym(module->lib, "init_module")) == NULL) { +#ifdef HAVE_EBCDIC +#pragma convlit(resume) +#endif Debug(LDAP_DEBUG_CONFIG, "module %s: no init_module() function found\n", file_name, 0, 0); + lt_dlclose(module->lib); ch_free(module); return -1; @@ -111,16 +171,18 @@ int module_load(const char* file_name, int argc, char *argv[]) if (rc == -1) { Debug(LDAP_DEBUG_CONFIG, "module %s: init_module() failed\n", file_name, 0, 0); + lt_dlclose(module->lib); ch_free(module); return rc; } - if (rc >= (sizeof(module_regtable) / sizeof(struct module_regtable_t)) + if (rc >= (int)(sizeof(module_regtable) / sizeof(struct module_regtable_t)) || module_regtable[rc].proc == NULL) { Debug(LDAP_DEBUG_CONFIG, "module %s: unknown registration type (%d)\n", file_name, rc, 0); + module_unload(module); return -1; } @@ -129,6 +191,7 @@ int module_load(const char* file_name, int argc, char *argv[]) if (rc != 0) { Debug(LDAP_DEBUG_CONFIG, "module %s: %s module could not be registered\n", file_name, module_regtable[rc].type, 0); + module_unload(module); return rc; } @@ -138,25 +201,36 @@ int module_load(const char* file_name, int argc, char *argv[]) Debug(LDAP_DEBUG_CONFIG, "module %s: %s module registered\n", file_name, module_regtable[rc].type, 0); + return 0; } int module_path(const char *path) { +#ifdef HAVE_EBCDIC + strcpy(ebuf, path); + __atoe(ebuf); + path = ebuf; +#endif return lt_dlsetsearchpath( path ); } void *module_resolve (const void *module, const char *name) { +#ifdef HAVE_EBCDIC + strcpy(ebuf, name); + __atoe(ebuf); + name = ebuf; +#endif if (module == NULL || name == NULL) return(NULL); return(lt_dlsym(((module_loaded_t *)module)->lib, name)); } -int module_unload (module_loaded_t *module) +static int module_unload (module_loaded_t *module) { module_loaded_t *mod; - int (*terminate) LDAP_P((void)); + MODULE_TERM_FN terminate; if (module != NULL) { /* remove module from tracking list */ @@ -172,7 +246,13 @@ int module_unload (module_loaded_t *module) } /* call module's terminate routine, if present */ - if (terminate = lt_dlsym(module->lib, "term_module")) { +#ifdef HAVE_EBCDIC +#pragma convlit(suspend) +#endif + if ((terminate = lt_dlsym(module->lib, "term_module"))) { +#ifdef HAVE_EBCDIC +#pragma convlit(resume) +#endif terminate(); } @@ -183,10 +263,46 @@ int module_unload (module_loaded_t *module) return 0; } -int load_null (const void *module, const char *file_name) +int load_null_module (const void *module, const char *file_name) { return 0; } +#ifdef SLAPD_EXTERNAL_EXTENSIONS +int +load_extop_module ( + const void *module, + const char *file_name +) +{ + SLAP_EXTOP_MAIN_FN *ext_main; + SLAP_EXTOP_GETOID_FN *ext_getoid; + struct berval oid; + int rc; + + ext_main = (SLAP_EXTOP_MAIN_FN *)module_resolve(module, "ext_main"); + if (ext_main == NULL) { + return(-1); + } + + ext_getoid = module_resolve(module, "ext_getoid"); + if (ext_getoid == NULL) { + return(-1); + } + + rc = (ext_getoid)(0, &oid, 256); + if (rc != 0) { + return(rc); + } + if (oid.bv_val == NULL || oid.bv_len == 0) { + return(-1); + } + + /* FIXME: this is broken, and no longer needed, + * as a module can call load_extop() itself... */ + rc = load_extop( &oid, ext_main ); + return rc; +} +#endif /* SLAPD_EXTERNAL_EXTENSIONS */ #endif /* SLAPD_MODULES */