lib/util: consolidate module loading into common code
[samba.git] / source3 / lib / module.c
index 38fcf0f3297599d55117d48bd011a6cb35880aa2..a85d7d05280dd6e64c85cf368d94496c011655cd 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-
-#ifdef HAVE_DLOPEN
-
-/* Load a dynamic module.  Only log a level 0 error if we are not checking 
-   for the existence of a module (probling). */
-
-static NTSTATUS do_smb_load_module(const char *module_name, BOOL is_probe)
-{
-       void *handle;
-       init_module_function *init;
-       NTSTATUS status;
-       const char *error;
-
-       /* Always try to use LAZY symbol resolving; if the plugin has 
-        * backwards compatibility, there might be symbols in the 
-        * plugin referencing to old (removed) functions
-        */
-       handle = sys_dlopen(module_name, RTLD_LAZY);
-
-       if(!handle) {
-               int level = is_probe ? 3 : 0;
-               DEBUG(level, ("Error loading module '%s': %s\n", module_name, 
-                             sys_dlerror()));
-
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       init = (init_module_function *)sys_dlsym(handle, "init_module");
-
-       /* we must check sys_dlerror() to determine if it worked, because
-           sys_dlsym() can validly return NULL */
-       error = sys_dlerror();
-       if (error) {
-               DEBUG(0, ("Error trying to resolve symbol 'init_module' in %s: %s\n", 
-                         module_name, error));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       status = init();
-
-       DEBUG(2, ("Module '%s' loaded\n", module_name));
-
-       return status;
-}
-
-NTSTATUS smb_load_module(const char *module_name)
-{
-       return do_smb_load_module(module_name, False);
-}
-
-/* Load all modules in list and return number of 
- * modules that has been successfully loaded */
-int smb_load_modules(const char **modules)
-{
-       int i;
-       int success = 0;
-
-       for(i = 0; modules[i]; i++){
-               if(NT_STATUS_IS_OK(smb_load_module(modules[i]))) {
-                       success++;
-               }
-       }
-
-       DEBUG(2, ("%d modules successfully loaded\n", success));
-
-       return success;
-}
-
-NTSTATUS smb_probe_module(const char *subsystem, const char *module)
-{
-       pstring full_path;
-       
-       /* Check for absolute path */
-
-       /* if we make any 'samba multibyte string' 
-          calls here, we break 
-          for loading string modules */
-
-       DEBUG(5, ("Probing module '%s'\n", module));
-
-       if (module[0] == '/')
-               return do_smb_load_module(module, True);
-       
-       pstrcpy(full_path, lib_path(subsystem));
-       pstrcat(full_path, "/");
-       pstrcat(full_path, module);
-       pstrcat(full_path, ".");
-       pstrcat(full_path, shlib_ext());
-
-       DEBUG(5, ("Probing module '%s': Trying to load from %s\n", module, full_path));
-       
-       return do_smb_load_module(full_path, True);
-}
-
-#else /* HAVE_DLOPEN */
-
-NTSTATUS smb_load_module(const char *module_name)
-{
-       DEBUG(0,("This samba executable has not been built with plugin support\n"));
-       return NT_STATUS_NOT_SUPPORTED;
-}
-
-int smb_load_modules(const char **modules)
-{
-       DEBUG(0,("This samba executable has not been built with plugin support\n"));
-       return -1;
-}
-
-NTSTATUS smb_probe_module(const char *subsystem, const char *module)
-{
-       DEBUG(0,("This samba executable has not been built with plugin support, not probing\n")); 
-       return NT_STATUS_NOT_SUPPORTED;
-}
-
-#endif /* HAVE_DLOPEN */
-
-void init_modules(void)
-{
-       /* FIXME: This can cause undefined symbol errors :
-        *  smb_register_vfs() isn't available in nmbd, for example */
-       if(lp_preload_modules()) 
-               smb_load_modules(lp_preload_modules());
-}
-
-
-/***************************************************************************
- * This Function registers a idle event
- *
- * the registered funtions are run periodically
- * and maybe shutdown idle connections (e.g. to an LDAP server)
- ***************************************************************************/
-static smb_event_id_t smb_idle_event_id = 1;
-
-struct smb_idle_list_ent {
-       struct smb_idle_list_ent *prev,*next;
-       smb_event_id_t id;
-       smb_idle_event_fn *fn;
-       void *data;
-       time_t interval;
-       time_t lastrun;
-};
-
-static struct smb_idle_list_ent *smb_idle_event_list = NULL;
-
-smb_event_id_t smb_register_idle_event(smb_idle_event_fn *fn, void *data, time_t interval)
-{
-       struct smb_idle_list_ent *event;
-
-       if (!fn) {      
-               return SMB_EVENT_ID_INVALID;
-       }
-
-       event = (struct smb_idle_list_ent *)malloc(sizeof(struct smb_idle_list_ent));
-       if (!event) {
-               DEBUG(0,("malloc() failed!\n"));
-               return SMB_EVENT_ID_INVALID;
-       }
-       event->fn = fn;
-       event->data = data;
-       event->interval = interval;
-       event->lastrun = 0;
-       event->id = smb_idle_event_id++;
-
-       DLIST_ADD(smb_idle_event_list,event);
-
-       return event->id;
-}
-
-BOOL smb_unregister_idle_event(smb_event_id_t id)
-{
-       struct smb_idle_list_ent *event = smb_idle_event_list;
-       
-       while(event) {
-               if (event->id == id) {
-                       DLIST_REMOVE(smb_idle_event_list,event);
-                       SAFE_FREE(event);
-                       return True;
-               }
-               event = event->next;
-       }
-       
-       return False;
-}
-
-void smb_run_idle_events(time_t now)
-{
-       struct smb_idle_list_ent *event = smb_idle_event_list;
-
-       while (event) {
-               struct smb_idle_list_ent *next = event->next;
-               time_t interval;
-
-               if (event->interval <= 0) {
-                       interval = SMB_IDLE_EVENT_DEFAULT_INTERVAL;
-               } else if (event->interval >= SMB_IDLE_EVENT_MIN_INTERVAL) {
-                       interval = event->interval;
-               } else {
-                       interval = SMB_IDLE_EVENT_MIN_INTERVAL;
-               }
-               if (now >(event->lastrun+interval)) {
-                       event->lastrun = now;
-                       event->fn(&event->data,&event->interval,now);
-               }
-               event = next;
-       }
-
-       return;
-}
-
-/***************************************************************************
- * This Function registers a exit event
- *
- * the registered functions are run on exit()
- * and maybe shutdown idle connections (e.g. to an LDAP server)
- ***************************************************************************/
-
-struct smb_exit_list_ent {
-       struct smb_exit_list_ent *prev,*next;
-       smb_event_id_t id;
-       smb_exit_event_fn *fn;
-       void *data;
-};
-
-static struct smb_exit_list_ent *smb_exit_event_list = NULL;
-
-smb_event_id_t smb_register_exit_event(smb_exit_event_fn *fn, void *data)
-{
-       struct smb_exit_list_ent *event;
-       static smb_event_id_t smb_exit_event_id = 1;
-
-       if (!fn) {      
-               return SMB_EVENT_ID_INVALID;
-       }
-
-       event = (struct smb_exit_list_ent *)malloc(sizeof(struct smb_exit_list_ent));
-       if (!event) {
-               DEBUG(0,("malloc() failed!\n"));
-               return SMB_EVENT_ID_INVALID;
-       }
-       event->fn = fn;
-       event->data = data;
-       event->id = smb_exit_event_id++;
-
-       DLIST_ADD(smb_exit_event_list,event);
-
-       return event->id;
-}
-
-BOOL smb_unregister_exit_event(smb_event_id_t id)
-{
-       struct smb_exit_list_ent *event = smb_exit_event_list;
-       
-       while(event) {
-               if (event->id == id) {
-                       DLIST_REMOVE(smb_exit_event_list,event);
-                       SAFE_FREE(event);
-                       return True;
-               }
-               event = event->next;
-       }
-       
-       return False;
-}
-
-void smb_run_exit_events(void)
-{
-       struct smb_exit_list_ent *event = smb_exit_event_list;
-       struct smb_exit_list_ent *tmp = NULL;
-
-       while (event) {
-               event->fn(&event->data);
-               tmp = event;
-               event = event->next;
-               /* exit event should only run one time :-)*/
-               SAFE_FREE(tmp);
-       }
-
-       /* the list is empty now...*/
-       smb_exit_event_list = NULL;
-
-       return;
-}