aboutsummaryrefslogtreecommitdiffstats
path: root/daemon/purger.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/purger.c')
-rw-r--r--daemon/purger.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/daemon/purger.c b/daemon/purger.c
new file mode 100644
index 0000000..43be168
--- /dev/null
+++ b/daemon/purger.c
@@ -0,0 +1,155 @@
+/*
+ * purger.c - syslogd implementation for windows, log dir purger
+ *
+ * Created by Alexander Yaworsky
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <stdio.h>
+#include <windows.h>
+
+#include <glib.h>
+
+#include <syslog.h>
+#include <syslogd.h>
+
+static HANDLE purger_semaphore = NULL;
+
+/******************************************************************************
+ * recursive_purge
+ *
+ * auxiliary function for purge_log_dirs
+ */
+static void recursive_purge( gchar* pathname, LPFILETIME min_time )
+{
+ gchar *new_pathname;
+ HANDLE find_handle;
+ WIN32_FIND_DATA find_data;
+
+ TRACE_ENTER( "%s\n", pathname );
+
+ new_pathname = g_build_filename( pathname, "*", NULL );
+ find_handle = FindFirstFile( new_pathname, &find_data );
+ if( INVALID_HANDLE_VALUE == find_handle )
+ {
+ TRACE_2( "FindFirstFile(%s) error %lu\n", new_pathname, GetLastError() );
+ g_free( new_pathname );
+ TRACE_LEAVE( "it seems the path does not exist\n" );
+ return;
+ }
+ g_free( new_pathname );
+ do {
+ if( (find_data.cFileName[0] == '.' && find_data.cFileName[1] == '\0')
+ ||
+ (find_data.cFileName[0] == '.'
+ && find_data.cFileName[1] == '.' && find_data.cFileName[2] == '\0') )
+ continue;
+
+ new_pathname = g_build_filename( pathname, find_data.cFileName, NULL );
+ if( find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ {
+ recursive_purge( new_pathname, min_time );
+ if( RemoveDirectory( new_pathname ) )
+ {
+ TRACE( "removed %s\n", new_pathname );
+ }
+ else
+ {
+ TRACE( "failed to remove %s\n", new_pathname );
+ }
+ }
+ else
+ {
+ if( CompareFileTime( min_time, &find_data.ftLastWriteTime ) > 0 )
+ {
+ if( DeleteFile( new_pathname ) )
+ {
+ TRACE( "deleted %s\n", new_pathname );
+ }
+ else
+ {
+ TRACE( "failed to delete %s\n", new_pathname );
+ }
+ }
+ }
+ g_free( new_pathname );
+ } while( FindNextFile( find_handle, &find_data ) );
+ FindClose( find_handle );
+
+ TRACE_LEAVE( "done\n" );
+}
+
+/******************************************************************************
+ * purge_log_dirs
+ */
+void purge_log_dirs()
+{
+ GList *item;
+
+ TRACE_ENTER( "\n" );
+ if( WaitForSingleObject( purger_semaphore, 0 ) != WAIT_OBJECT_0 )
+ {
+ TRACE_LEAVE( "done; another thread is active\n" );
+ return;
+ }
+ for( item = purger_dirs; item; item = item->next )
+ {
+ struct purger_dir *p = item->data;
+ gchar *pathname = make_absolute_log_pathname( p->directory );
+ FILETIME min_time;
+ long long min_time_64;
+
+ GetSystemTimeAsFileTime( &min_time );
+ min_time_64 = (((long long) min_time.dwHighDateTime) << 32) + (long long) min_time.dwLowDateTime;
+ min_time_64 -= ((long long) p->keep_days) * ((long long) (24 * 3600)) * (long long) 10000000;
+ min_time.dwHighDateTime = min_time_64 >> 32;
+ min_time.dwLowDateTime = min_time_64;
+
+ recursive_purge( pathname, &min_time );
+ g_free( pathname );
+ }
+ ReleaseSemaphore( purger_semaphore, 1, NULL );
+ TRACE_LEAVE( "done\n" );
+}
+
+/******************************************************************************
+ * init_purger
+ */
+gboolean init_purger()
+{
+ gboolean ret = FALSE;
+
+ TRACE_ENTER( "\n" );
+
+ purger_semaphore = CreateSemaphore( NULL, 1, 1, NULL );
+ if( !purger_semaphore )
+ {
+ ERR( "Cannot create semaphore; error %lu\n", GetLastError() );
+ goto done;
+ }
+ ret = TRUE;
+
+done:
+ TRACE_LEAVE( "done; ret=%d\n", ret );
+ return ret;
+}
+
+/******************************************************************************
+ * fini_purger
+ */
+void fini_purger()
+{
+ TRACE_ENTER( "\n" );
+ if( purger_semaphore ) CloseHandle( purger_semaphore );
+ TRACE_LEAVE( "done\n" );
+}