diff options
-rw-r--r-- | source3/include/includes.h | 2 | ||||
-rw-r--r-- | source3/include/module.h | 45 | ||||
-rw-r--r-- | source3/include/smb.h | 3 | ||||
-rw-r--r-- | source3/lib/module.c | 107 | ||||
-rw-r--r-- | source3/smbd/process.c | 7 | ||||
-rw-r--r-- | source3/smbd/server.c | 3 |
6 files changed, 163 insertions, 4 deletions
diff --git a/source3/include/includes.h b/source3/include/includes.h index 8fc09c2cae..c0e59a39b3 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -824,6 +824,8 @@ extern int errno; #include "mangle.h" +#include "module.h" + #include "nsswitch/winbind_client.h" #include "genparser.h" diff --git a/source3/include/module.h b/source3/include/module.h new file mode 100644 index 0000000000..659833c91a --- /dev/null +++ b/source3/include/module.h @@ -0,0 +1,45 @@ +/* + Unix SMB/CIFS implementation. + Handling of idle/exit events + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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. +*/ + +#ifndef _MODULE_H +#define _MODULE_H + +/* Module support */ +typedef NTSTATUS (init_module_function) (void); + + +#define SMB_IDLE_EVENT_DEFAULT_INTERVAL 180 +#define SMB_IDLE_EVENT_MIN_INTERVAL 30 + +typedef struct smb_idle_event_struct { + struct smb_idle_event_struct *prev,*next; + time_t interval; + time_t last_run; + void *data; + void (*fn)(struct smb_idle_event_struct **event, time_t now); +} smb_idle_event_struct; + +typedef struct smb_exit_event_struct { + struct smb_exit_event_struct *prev,*next; + void *data; + void (*fn)(struct smb_exit_event_struct **event); +} smb_exit_event_struct; + +#endif /* _MODULE_H */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 2ca65ec275..04b7d72395 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1616,7 +1616,4 @@ typedef struct { #include "popt_common.h" -/* Module support */ -typedef NTSTATUS (init_module_function) (void); - #endif /* _SMB_H */ diff --git a/source3/lib/module.c b/source3/lib/module.c index 087c964d3c..221538fbec 100644 --- a/source3/lib/module.c +++ b/source3/lib/module.c @@ -2,7 +2,8 @@ Unix SMB/CIFS implementation. module loading system - Copyright (C) Jelmer Vernooij 2002 + Copyright (C) Jelmer Vernooij 2002-2003 + Copyright (C) Stefan (metze) Metzmacher 2003 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 @@ -145,3 +146,107 @@ void module_path_get_name(const char *path, pstring name) } } } + + +/*************************************************************************** + * 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_idle_event_struct *smb_idle_event_list = NULL; +NTSTATUS smb_register_idle_event(smb_idle_event_struct *idle_event) +{ + if (!idle_event) { + return NT_STATUS_INVALID_PARAMETER; + } + + idle_event->last_run = 0; + + DLIST_ADD(smb_idle_event_list,idle_event); + + return NT_STATUS_OK; +} + +NTSTATUS smb_unregister_idle_event(smb_idle_event_struct *idle_event) +{ + if (!idle_event) { + return NT_STATUS_INVALID_PARAMETER; + } + + DLIST_REMOVE(smb_idle_event_list,idle_event); + + return NT_STATUS_OK; +} + +void smb_run_idle_events(time_t now) +{ + smb_idle_event_struct *tmp_event = smb_idle_event_list; + + while (tmp_event) { + time_t interval; + + if (tmp_event->fn) { + if (tmp_event->interval >= SMB_IDLE_EVENT_MIN_INTERVAL) { + interval = tmp_event->interval; + } else { + interval = SMB_IDLE_EVENT_DEFAULT_INTERVAL; + } + if (now >(tmp_event->last_run+interval)) { + tmp_event->fn(&tmp_event,now); + tmp_event->last_run = now; + } + } + + tmp_event = tmp_event->next; + } + + return; +} + +/*************************************************************************** + * This Function registers a exit event + * + * the registered funtions are run on exit() + * and maybe shutdown idle connections (e.g. to an LDAP server) + ***************************************************************************/ +static smb_exit_event_struct *smb_exit_event_list = NULL; +NTSTATUS smb_register_exit_event(smb_exit_event_struct *exit_event) +{ + if (!exit_event) { + return NT_STATUS_INVALID_PARAMETER; + } + + DLIST_ADD(smb_exit_event_list,exit_event); + + return NT_STATUS_OK; +} + +NTSTATUS smb_unregister_exit_event(smb_exit_event_struct *exit_event) +{ + if (!exit_event) { + return NT_STATUS_INVALID_PARAMETER; + } + + DLIST_REMOVE(smb_exit_event_list,exit_event); + + return NT_STATUS_OK; +} + +void smb_run_exit_events(void) +{ + smb_exit_event_struct *tmp_event = smb_exit_event_list; + + while (tmp_event) { + if (tmp_event->fn) { + tmp_event->fn(&tmp_event); + } + tmp_event = tmp_event->next; + } + + /* run exit_events only once */ + smb_exit_event_list = NULL; + + return; +} + diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 54fd4a90d9..18acb35f7a 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1114,6 +1114,9 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t /* become root again if waiting */ change_to_root_user(); + /* run all registered idle events */ + smb_run_idle_events(t); + /* check if we need to reload services */ check_reload(t); @@ -1277,6 +1280,10 @@ void smbd_process(void) lp_talloc_free(); main_loop_talloc_free(); + /* run all registered idle events */ + smb_run_idle_events(time(NULL)); + + /* Did someone ask for immediate checks on things like blocking locks ? */ if (select_timeout == 0) { if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time)) diff --git a/source3/smbd/server.c b/source3/smbd/server.c index ef27f0b7a4..c24fc5134d 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -567,6 +567,9 @@ void exit_server(const char *reason) print_notify_send_messages(3); /* 3 second timeout. */ + /* run all registered exit events */ + smb_run_exit_events(); + /* delete our entry in the connections database. */ yield_connection(NULL,""); |