[Box Backup-commit] COMMIT r2183 - box/trunk/lib/intercept

boxbackup-dev at fluffy.co.uk boxbackup-dev at fluffy.co.uk
Wed May 28 16:28:36 BST 2008


Author: chris
Date: 2008-05-28 16:28:36 +0100 (Wed, 28 May 2008)
New Revision: 2183

Modified:
   box/trunk/lib/intercept/intercept.cpp
   box/trunk/lib/intercept/intercept.h
Log:
Add stat() intercept and stat() and lstat() post call hooks.


Modified: box/trunk/lib/intercept/intercept.cpp
===================================================================
--- box/trunk/lib/intercept/intercept.cpp	2008-05-28 15:25:59 UTC (rev 2182)
+++ box/trunk/lib/intercept/intercept.cpp	2008-05-28 15:28:36 UTC (rev 2183)
@@ -84,7 +84,13 @@
 static lstat_t*    lstat_real    = NULL;
 static lstat_t*    lstat_hook    = NULL;
 static const char* lstat_file    = NULL;
+static lstat_t*    stat_real     = NULL;
+static lstat_t*    stat_hook     = NULL;
+static const char* stat_file     = NULL;
 
+static lstat_post_hook_t* lstat_post_hook = NULL;
+static lstat_post_hook_t* stat_post_hook  = NULL;
+
 #define SIZE_ALWAYS_ERROR	-773
 
 void intercept_clear_setup()
@@ -97,7 +103,10 @@
 	intercept_filepos = 0;
 	intercept_delay_ms = 0;
 	readdir_hook = NULL;
+	stat_hook = NULL;
 	lstat_hook = NULL;
+	stat_post_hook = NULL;
+	lstat_post_hook = NULL;
 }
 
 bool intercept_triggered()
@@ -405,6 +414,40 @@
 	lstat_hook = hookfn;
 }
 
+void intercept_setup_lstat_post_hook(lstat_post_hook_t hookfn)
+{
+	/*
+	if (hookfn != NULL)
+	{
+		BOX_TRACE("lstat hooked to " << hookfn << " for " << filename);
+	}
+	else
+	{
+		BOX_TRACE("lstat unhooked from " << lstat_hook << " for " <<
+			lstat_file);
+	}
+	*/
+
+	lstat_post_hook = hookfn;
+}
+
+void intercept_setup_stat_post_hook(lstat_post_hook_t hookfn)
+{
+	/*
+	if (hookfn != NULL)
+	{
+		BOX_TRACE("lstat hooked to " << hookfn << " for " << filename);
+	}
+	else
+	{
+		BOX_TRACE("lstat unhooked from " << lstat_hook << " for " <<
+			lstat_file);
+	}
+	*/
+
+	stat_post_hook = hookfn;
+}
+
 static void * find_function(const char *pName)
 {
 	dlerror();
@@ -534,10 +577,15 @@
 	if (lstat_hook == NULL || strcmp(file_name, lstat_file) != 0)
 	{
 	#ifdef LINUX_WEIRD_LSTAT
-		return lstat_real(ver, file_name, buf);
+		int ret = lstat_real(ver, file_name, buf);
 	#else
-		return lstat_real(file_name, buf);
+		int ret = lstat_real(file_name, buf);
 	#endif
+		if (lstat_post_hook != NULL)
+		{
+			ret = lstat_post_hook(ret, file_name, buf);
+		}
+		return ret;
 	}
 
 	#ifdef LINUX_WEIRD_LSTAT
@@ -547,4 +595,48 @@
 	#endif
 }
 
+extern "C" int 
+#ifdef LINUX_WEIRD_LSTAT
+__xstat(int ver, const char *file_name, STAT_STRUCT *buf)
+#else
+stat(const char *file_name, STAT_STRUCT *buf)
+#endif
+{
+	if (stat_real == NULL)
+	{
+	#ifdef LINUX_WEIRD_LSTAT
+		stat_real = (lstat_t*)find_function("__xstat");
+	#else
+		stat_real = (lstat_t*)find_function("stat");
+	#endif
+	}
+
+	if (stat_real == NULL)
+	{
+		perror("cannot find real stat");
+		errno = ENOSYS;
+		return -1;
+	}
+
+	if (stat_hook == NULL || strcmp(file_name, stat_file) != 0)
+	{
+	#ifdef LINUX_WEIRD_LSTAT
+		int ret = stat_real(ver, file_name, buf);
+	#else
+		int ret = stat_real(file_name, buf);
+	#endif
+		if (stat_post_hook != NULL)
+		{
+			ret = stat_post_hook(ret, file_name, buf);
+		}
+		return ret;
+	}
+
+	#ifdef LINUX_WEIRD_LSTAT
+	return stat_hook(ver, file_name, buf);
+	#else
+	return stat_hook(file_name, buf);
+	#endif
+}
+
 #endif // n PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE

Modified: box/trunk/lib/intercept/intercept.h
===================================================================
--- box/trunk/lib/intercept/intercept.h	2008-05-28 15:25:59 UTC (rev 2182)
+++ box/trunk/lib/intercept/intercept.h	2008-05-28 15:28:36 UTC (rev 2183)
@@ -34,6 +34,9 @@
 #endif
 }
 
+typedef int (lstat_post_hook_t) (int old_ret, const char *file_name,
+	struct stat *buf);
+
 void intercept_setup_error(const char *filename, unsigned int errorafter, 
 	int errortoreturn, int syscalltoerror);
 void intercept_setup_delay(const char *filename, unsigned int delay_after,
@@ -42,6 +45,10 @@
 
 void intercept_setup_readdir_hook(const char *dirname,  readdir_t hookfn);
 void intercept_setup_lstat_hook  (const char *filename, lstat_t   hookfn);
+void intercept_setup_lstat_post_hook(lstat_post_hook_t hookfn);
+void intercept_setup_stat_post_hook (lstat_post_hook_t hookfn);
 
+void intercept_clear_setup();
+
 #endif // !PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE
 #endif // !INTERCEPT_H




More information about the Boxbackup-commit mailing list