00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025 #ifdef HAVE_DLOPEN
00026
00027
00028
00029
00030 static NTSTATUS do_smb_load_module(const char *module_name, BOOL is_probe)
00031 {
00032 void *handle;
00033 init_module_function *init;
00034 NTSTATUS status;
00035 const char *error;
00036
00037
00038
00039
00040
00041 handle = sys_dlopen(module_name, RTLD_LAZY);
00042
00043
00044
00045 error = sys_dlerror();
00046
00047 if(!handle) {
00048 int level = is_probe ? 3 : 0;
00049 DEBUG(level, ("Error loading module '%s': %s\n", module_name, error ? error : ""));
00050 return NT_STATUS_UNSUCCESSFUL;
00051 }
00052
00053 init = (init_module_function *)sys_dlsym(handle, "init_module");
00054
00055
00056
00057 error = sys_dlerror();
00058 if (error) {
00059 DEBUG(0, ("Error trying to resolve symbol 'init_module' in %s: %s\n",
00060 module_name, error));
00061 return NT_STATUS_UNSUCCESSFUL;
00062 }
00063
00064 DEBUG(2, ("Module '%s' loaded\n", module_name));
00065
00066 status = init();
00067 if (!NT_STATUS_IS_OK(status)) {
00068 DEBUG(0, ("Module '%s' initialization failed: %s\n",
00069 module_name, get_friendly_nt_error_msg(status)));
00070 }
00071
00072 return status;
00073 }
00074
00075 NTSTATUS smb_load_module(const char *module_name)
00076 {
00077 return do_smb_load_module(module_name, False);
00078 }
00079
00080
00081
00082 int smb_load_modules(const char **modules)
00083 {
00084 int i;
00085 int success = 0;
00086
00087 for(i = 0; modules[i]; i++){
00088 if(NT_STATUS_IS_OK(smb_load_module(modules[i]))) {
00089 success++;
00090 }
00091 }
00092
00093 DEBUG(2, ("%d modules successfully loaded\n", success));
00094
00095 return success;
00096 }
00097
00098 NTSTATUS smb_probe_module(const char *subsystem, const char *module)
00099 {
00100 pstring full_path;
00101
00102
00103
00104
00105
00106
00107
00108 DEBUG(5, ("Probing module '%s'\n", module));
00109
00110 if (module[0] == '/')
00111 return do_smb_load_module(module, True);
00112
00113 pstrcpy(full_path, lib_path(subsystem));
00114 pstrcat(full_path, "/");
00115 pstrcat(full_path, module);
00116 pstrcat(full_path, ".");
00117 pstrcat(full_path, shlib_ext());
00118
00119 DEBUG(5, ("Probing module '%s': Trying to load from %s\n", module, full_path));
00120
00121 return do_smb_load_module(full_path, True);
00122 }
00123
00124 #else
00125
00126 NTSTATUS smb_load_module(const char *module_name)
00127 {
00128 DEBUG(0,("This samba executable has not been built with plugin support\n"));
00129 return NT_STATUS_NOT_SUPPORTED;
00130 }
00131
00132 int smb_load_modules(const char **modules)
00133 {
00134 DEBUG(0,("This samba executable has not been built with plugin support\n"));
00135 return -1;
00136 }
00137
00138 NTSTATUS smb_probe_module(const char *subsystem, const char *module)
00139 {
00140 DEBUG(0,("This samba executable has not been built with plugin support, not probing\n"));
00141 return NT_STATUS_NOT_SUPPORTED;
00142 }
00143
00144 #endif
00145
00146 void init_modules(void)
00147 {
00148
00149
00150 if(lp_preload_modules())
00151 smb_load_modules(lp_preload_modules());
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161 static smb_event_id_t smb_idle_event_id = 1;
00162
00163 struct smb_idle_list_ent {
00164 struct smb_idle_list_ent *prev,*next;
00165 smb_event_id_t id;
00166 smb_idle_event_fn *fn;
00167 void *data;
00168 time_t interval;
00169 time_t lastrun;
00170 };
00171
00172 static struct smb_idle_list_ent *smb_idle_event_list = NULL;
00173
00174 smb_event_id_t smb_register_idle_event(smb_idle_event_fn *fn, void *data, time_t interval)
00175 {
00176 struct smb_idle_list_ent *event;
00177
00178 if (!fn) {
00179 return SMB_EVENT_ID_INVALID;
00180 }
00181
00182 event = SMB_MALLOC_P(struct smb_idle_list_ent);
00183 if (!event) {
00184 DEBUG(0,("malloc() failed!\n"));
00185 return SMB_EVENT_ID_INVALID;
00186 }
00187 event->fn = fn;
00188 event->data = data;
00189 event->interval = interval;
00190 event->lastrun = 0;
00191 event->id = smb_idle_event_id++;
00192
00193 DLIST_ADD(smb_idle_event_list,event);
00194
00195 return event->id;
00196 }
00197
00198 BOOL smb_unregister_idle_event(smb_event_id_t id)
00199 {
00200 struct smb_idle_list_ent *event = smb_idle_event_list;
00201
00202 while(event) {
00203 if (event->id == id) {
00204 DLIST_REMOVE(smb_idle_event_list,event);
00205 SAFE_FREE(event);
00206 return True;
00207 }
00208 event = event->next;
00209 }
00210
00211 return False;
00212 }
00213
00214 void smb_run_idle_events(time_t now)
00215 {
00216 struct smb_idle_list_ent *event = smb_idle_event_list;
00217
00218 while (event) {
00219 struct smb_idle_list_ent *next = event->next;
00220 time_t interval;
00221
00222 if (event->interval <= 0) {
00223 interval = SMB_IDLE_EVENT_DEFAULT_INTERVAL;
00224 } else if (event->interval >= SMB_IDLE_EVENT_MIN_INTERVAL) {
00225 interval = event->interval;
00226 } else {
00227 interval = SMB_IDLE_EVENT_MIN_INTERVAL;
00228 }
00229 if (now >(event->lastrun+interval)) {
00230 event->lastrun = now;
00231 event->fn(&event->data,&event->interval,now);
00232 }
00233 event = next;
00234 }
00235
00236 return;
00237 }