summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/includes.h2
-rw-r--r--source3/include/module.h45
-rw-r--r--source3/include/smb.h3
-rw-r--r--source3/lib/module.c107
-rw-r--r--source3/smbd/process.c7
-rw-r--r--source3/smbd/server.c3
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,"");