2 Unix SMB/CIFS implementation.
5 Copyright (C) Jelmer Vernooij 2002-2004
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "system/dir.h"
24 #include "system/filesys.h"
25 #include "dlinklist.h"
29 /* Load module (or directory with modules) recursively.
30 * Includes running the init_module() function */
31 NTSTATUS smb_load_module(const char *module_name)
34 init_module_function init;
39 struct dirent *dirent;
41 if(stat(module_name, &st) < 0) {
42 DEBUG(0, ("Can't stat module '%s'\n", module_name));
43 return NT_STATUS_UNSUCCESSFUL;
46 /* If the argument is a directory, recursively load all files /
47 * directories in it */
49 /* How about symlinks pointing to themselves - wouldn't we rather
50 * want to use wildcards here? */
51 if(S_ISDIR(st.st_mode)) {
52 dir = opendir(module_name);
53 while ((dirent = readdir(dir))) {
54 smb_load_module(dirent->d_name);
58 /* Always try to use LAZY symbol resolving; if the plugin has
59 * backwards compatibility, there might be symbols in the
60 * plugin referencing to old (removed) functions
62 handle = sys_dlopen(module_name, RTLD_LAZY);
65 DEBUG(0, ("Error loading module '%s': %s\n", module_name, sys_dlerror()));
66 return NT_STATUS_UNSUCCESSFUL;
69 init = (init_module_function)sys_dlsym(handle, "init_module");
71 /* we must check sys_dlerror() to determine if it worked, because
72 sys_dlsym() can validly return NULL */
73 error = sys_dlerror();
75 DEBUG(0, ("Error trying to resolve symbol 'init_module' in %s: %s\n", module_name, error));
76 return NT_STATUS_UNSUCCESSFUL;
81 DEBUG(2, ("Module '%s' loaded\n", module_name));
86 /* Load all modules in list and return number of
87 * modules that has been successfully loaded */
88 int smb_load_modules(const char **modules)
93 for(i = 0; modules[i]; i++){
94 if(NT_STATUS_IS_OK(smb_load_module(modules[i]))) {
99 DEBUG(2, ("%d modules successfully loaded\n", success));
104 #else /* HAVE_DLOPEN */
106 NTSTATUS smb_load_module(const char *module_name)
108 DEBUG(0,("This samba executable has not been built with plugin support\n"));
109 return NT_STATUS_NOT_SUPPORTED;
112 int smb_load_modules(const char **modules)
114 DEBUG(0,("This samba executable has not been built with plugin support\n"));
118 #endif /* HAVE_DLOPEN */
120 void init_modules(void)
122 if(lp_preload_modules())
123 smb_load_modules(lp_preload_modules());
128 register_backend_function callback;
129 struct subsystem *prev, *next;
132 static struct subsystem *subsystems = NULL;
134 NTSTATUS register_subsystem(const char *name, register_backend_function callback)
137 struct subsystem *t = subsystems;
140 if(!strcmp(name, t->name)) {
141 /* its already registered! */
142 DEBUG(0,("Subsystem '%s' already registered\n", name));
143 return NT_STATUS_OBJECT_NAME_COLLISION;
148 s = smb_xmalloc(sizeof(struct subsystem));
150 s->name = smb_xstrdup(name);
151 s->callback = callback;
152 s->prev = s->next = NULL;
154 DLIST_ADD(subsystems, s);
159 NTSTATUS register_backend(const char *subsystem, const void *args)
161 /* Find the specified subsystem */
162 struct subsystem *s = subsystems;
165 if(!strcmp(subsystem, s->name)) return s->callback(args);
169 DEBUG(0, ("Unable to register backend for subsystem '%s'\n", subsystem));
171 return NT_STATUS_NOT_IMPLEMENTED;