Hi,

I found out that dazuko cannot be compiled on freebsd7.x. I created a
quick patch which is attached. It is made against the latest
dazuko-2.3.6 version. I tested it with the example utility shipped
within the dazuko package and it works fine. Basically the code for
freebsd7 is taken from dazukofs_freebsd5.c file. There are just small
changes in syscall table hooking. I created a new file
called dazuko_freebsd7.c to avoid ifdefs.

How to proceed.

1) copy dazuko-2.3.6-freebsd7.patch to the dazuko-2.3.6 source code
2) in dazuko-2.3.6 apply patch
   $ patch -p1 < dazuko-2.3.6-freebsd7.patch
3) configure and make as usual

-FH
diff -Nru dazuko-2.3.6a/configure dazuko-2.3.6b/configure
--- dazuko-2.3.6a/configure	2008-07-17 20:00:33.000000000 +0200
+++ dazuko-2.3.6b/configure	2009-03-07 15:16:10.000000000 +0100
@@ -56,7 +56,8 @@
 	echo "  --redirfsdir=DIR        RedirFS development files"
 	echo "  --system=SYS            configure for system SYS (linux22,linux24,linux26,"
 	echo "                                                    freebsd4,freebsd5"
-	echo "                                                    freebsd6,dummyos)"
+	echo "                                                    freebsd6,freebsd7)"
+	echo "                                                    dummyos)"
 	echo ""
 	echo "optional features"
 	echo "  --disable-FEATURE               do not include FEATURE"
@@ -1155,9 +1156,17 @@
 	if [ ${FREEBSD_VERSION} -eq 4 ]
 	then
 		DAZUKO_EXT_C="dazuko_freebsd.c"
-	else
+	elif [ ${FREEBSD_VERSION} -eq 5 ]
+	then
 		echo "CFLAGS += -DFREEBSD5_SUPPORT" >> Makefile
 		DAZUKO_EXT_C="dazuko_freebsd5.c"
+	elif [ ${FREEBSD_VERSION} -eq 6 ]
+	then
+		echo "CFLAGS += -DFREEBSD5_SUPPORT" >> Makefile
+		DAZUKO_EXT_C="dazuko_freebsd5.c"
+	else
+		echo "CFLAGS += -DFREEBSD7_SUPPORT" >> Makefile
+		DAZUKO_EXT_C="dazuko_freebsd7.c"
 	fi
 
 	if [ ${DEBUG} -eq 1 ]
@@ -1247,6 +1256,12 @@
 	echo ".include <bsd.kmod.mk>" >> Makefile
 }
 
+do_freebsd7()
+{
+	FREEBSD_VERSION=7
+	do_freebsd
+}
+
 do_freebsd6()
 {
 	FREEBSD_VERSION=6
@@ -1799,6 +1814,10 @@
 			UNAME="FreeBSD"
 			UNAME_R="6.x"
 			;;
+		freebsd7)
+			UNAME="FreeBSD"
+			UNAME_R="7.x"
+			;;
 		dummyos)
 			UNAME="DummyOS"
 			UNAME_R="0.x"
@@ -2076,9 +2095,12 @@
 		elif echo $UNAME_R | grep -qi ^6\.
 		then
 			SYSTEM="freebsd6"
+		elif echo $UNAME_R | grep -qi ^7\.
+		then
+			SYSTEM="freebsd7"
 		else
-			# default to FreeBSD 6
-			SYSTEM="freebsd6"
+			# default to FreeBSD 7
+			SYSTEM="freebsd7"
 		fi
 	fi
 fi
diff -Nru dazuko-2.3.6a/dazuko_freebsd7.c dazuko-2.3.6b/dazuko_freebsd7.c
--- dazuko-2.3.6a/dazuko_freebsd7.c	1970-01-01 01:00:00.000000000 +0100
+++ dazuko-2.3.6b/dazuko_freebsd7.c	2009-03-07 14:56:03.000000000 +0100
@@ -0,0 +1,1772 @@
+/* Dazuko FreeBSD. Allow FreeBSD file access control for 3rd-party applications.
+   Written by John Ogness <dazukoc...@ogness.net>
+
+   Copyright (c) 2004, 2005 H+BEDV Datentechnik GmbH
+   Copyright (c) 2006 Avira GmbH
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+   3. Neither the name of Dazuko nor the names of its contributors may be used
+   to endorse or promote products derived from this software without specific
+   prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include <sys/types.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/proc.h>
+#include <sys/ioccom.h>
+#include <sys/malloc.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/syscall.h>
+#include <sys/filio.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/sx.h>
+
+#include <sys/namei.h>
+#include <sys/param.h>
+#include <sys/vnode.h>
+
+#include "dazuko_freebsd5.h"
+#include "dazuko_core.h"
+
+
+d_read_t freebsd_dazuko_device_read;
+d_write_t freebsd_dazuko_device_write;
+d_open_t freebsd_dazuko_device_open;
+d_close_t freebsd_dazuko_device_close;
+
+extern struct xp_atomic active;
+
+static int		syscall_in_use = 0;
+static int		dev_major = 0;
+static struct cdev	*sdev = NULL;
+
+#define AS(name) (sizeof(struct name) / sizeof(register_t))
+
+#if defined(ON_OPEN_SUPPORT)
+static int freebsd_dazuko_sys_open(struct thread *t, struct open_args *uap);
+static struct sysent freebsd_dazuko_sys_open_sysent = { AS(open_args), (sy_call_t *)freebsd_dazuko_sys_open, AUE_OPEN_RWTC, NULL, 0, 0 };
+static sy_call_t *original_sys_open = NULL;
+
+static int freebsd_dazuko_sys_dup(struct thread *t, struct dup_args *uap);
+static struct sysent freebsd_dazuko_sys_dup_sysent = { AS(dup_args), (sy_call_t *)freebsd_dazuko_sys_dup, AUE_DUP, NULL, 0, 0 };
+static sy_call_t *original_sys_dup = NULL;
+#endif
+
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+static int freebsd_dazuko_sys_dup2(struct thread *t, struct dup2_args *uap);
+static struct sysent freebsd_dazuko_sys_dup2_sysent = { AS(dup2_args), (sy_call_t *)freebsd_dazuko_sys_dup2, AUE_DUP2, NULL, 0, 0 };
+static sy_call_t *original_sys_dup2 = NULL;
+#endif
+
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+static int freebsd_dazuko_sys_close(struct thread *t, struct close_args *uap);
+static struct sysent freebsd_dazuko_sys_close_sysent = { AS(close_args), (sy_call_t *)freebsd_dazuko_sys_close, AUE_CLOSE, NULL, 0, 0 };
+static sy_call_t *original_sys_close = NULL;
+#endif
+
+#ifdef ON_EXEC_SUPPORT
+static int freebsd_dazuko_sys_execve(struct thread *t, struct execve_args *uap);
+static struct sysent freebsd_dazuko_sys_execve_sysent = { AS(execve_args), (sy_call_t *)freebsd_dazuko_sys_execve, AUE_EXECVE, NULL, 0, 0 };
+static sy_call_t *original_sys_execve = NULL;
+#endif
+
+#ifdef ON_UNLINK_SUPPORT
+static int freebsd_dazuko_sys_unlink(struct thread *t, struct unlink_args *uap);
+static struct sysent freebsd_dazuko_sys_unlink_sysent = { AS(unlink_args), (sy_call_t *)freebsd_dazuko_sys_unlink, AUE_UNLINK, NULL, 0, 0 };
+static sy_call_t *original_sys_unlink = NULL;
+#endif
+
+#ifdef ON_RMDIR_SUPPORT
+static int freebsd_dazuko_sys_rmdir(struct thread *t, struct rmdir_args *uap);
+static struct sysent freebsd_dazuko_sys_rmdir_sysent = { AS(rmdir_args), (sy_call_t *)freebsd_dazuko_sys_rmdir, AUE_RMDIR, NULL, 0, 0 };
+static sy_call_t *original_sys_rmdir = NULL;
+#endif
+
+static struct vnode	*orig_rootmnt = NULL;
+
+static struct cdevsw	cdepts = {
+			.d_open =	freebsd_dazuko_device_open,
+			.d_close =	freebsd_dazuko_device_close,
+			.d_read =	freebsd_dazuko_device_read,
+			.d_write =	freebsd_dazuko_device_write,
+			.d_name =	DEVICE_NAME,
+#if defined(D_VERSION)
+			.d_version =	D_VERSION,
+#endif
+};
+
+
+MALLOC_DECLARE(M_DAZUKOBUF);
+MALLOC_DEFINE(M_DAZUKOBUF, "dazukobuffer", "buffer for dazuko module");
+
+
+static inline int freebsd_getpid(struct thread *t)
+{
+	if (t == NULL)
+	{
+		xp_print("dazuko: warning: freebsd_getpid(NULL)\n");
+		return -1;
+	}
+
+	if (t->td_proc == NULL)
+	{
+		xp_print("dazuko: warning: freebsd_getpid.t->td_proc=NULL\n");
+		return -1;
+	}
+
+	return t->td_proc->p_pid;
+}
+
+static inline void freebsd5_setupid(struct xp_daemon_id *xp_id, struct thread *t)
+{
+	if (xp_id == NULL || t == NULL)
+	{
+		xp_print("dazuko: warning: freebsd5_setupid() received NULL\n");
+		return;
+	}
+
+	if (t->td_proc == NULL)
+	{
+		xp_print("dazuko: warning: freebsd5_setupid().td_proc == NULL\n");
+		return;
+	}
+
+	if (t->td_proc->p_fd == NULL)
+	{
+		xp_print("dazuko: warning: freebsd5_setupid().td_proc.p_fd == NULL\n");
+		return;
+	}
+
+	xp_id->proc = t->td_proc;
+	xp_id->pid = t->td_proc->p_pid;
+	xp_id->fd = t->td_proc->p_fd;
+}
+
+
+/* mutex */
+
+inline void xp_init_mutex(struct xp_mutex *mutex)
+{
+	mtx_init(&(mutex->lock), DEVICE_NAME, NULL, MTX_DEF);
+}
+
+inline void xp_down(struct xp_mutex *mutex)
+{
+	mtx_lock(&(mutex->lock));
+}
+
+inline void xp_up(struct xp_mutex *mutex)
+{
+	mtx_unlock(&(mutex->lock));
+}
+
+inline void xp_destroy_mutex(struct xp_mutex *mutex)
+{
+	mtx_destroy(&(mutex->lock));
+}
+
+
+/* read-write lock */
+
+inline void xp_init_rwlock(struct xp_rwlock *rwlock)
+{
+	lockinit(&(rwlock->lock), PVM, DEVICE_NAME, 0, 0);
+}
+
+inline void xp_write_lock(struct xp_rwlock *rwlock)
+{
+	lockmgr(&(rwlock->lock), LK_EXCLUSIVE, 0, curthread);
+}
+
+inline void xp_write_unlock(struct xp_rwlock *rwlock)
+{
+	lockmgr(&(rwlock->lock), LK_RELEASE, 0, curthread);
+}
+
+inline void xp_read_lock(struct xp_rwlock *rlock)
+{
+	lockmgr(&(rlock->lock), LK_SHARED, 0, curthread);
+}
+
+inline void xp_read_unlock(struct xp_rwlock *rlock)
+{
+	lockmgr(&(rlock->lock), LK_RELEASE, 0, curthread);
+}
+
+inline void xp_destroy_rwlock(struct xp_rwlock *rwlock)
+{
+	lockdestroy(&(rwlock->lock));
+}
+
+
+/* wait-notify queue */
+
+inline int xp_init_queue(struct xp_queue *queue)
+{
+	xp_init_mutex(&(queue->mutex));
+
+	return 0;
+}
+
+inline int xp_wait_until_condition(struct xp_queue *queue, int (*cfunction)(void *), void *cparam, int allow_interrupt)
+{
+	int	rc = 0;
+	int	prio = PVM;
+
+	if (allow_interrupt)
+		prio |= PCATCH;
+
+/* DOWN */
+	xp_down(&(queue->mutex));
+
+	for (;;)
+	{
+
+		if (cfunction(cparam))
+			break;
+
+		if (msleep(queue, &(queue->mutex.lock), prio, DEVICE_NAME, 0) != 0)  /* UP+DOWN */
+		{
+			rc = -1;
+			break;
+		}
+	}
+
+	xp_up(&(queue->mutex));
+/* UP */
+
+	return rc;
+}
+
+inline int xp_notify(struct xp_queue *queue)
+{
+/* DOWN */
+	xp_down(&(queue->mutex));
+
+	wakeup(queue);
+
+	xp_up(&(queue->mutex));
+/* UP */
+
+	return 0;
+}
+
+inline int xp_destroy_queue(struct xp_queue *queue)
+{
+	xp_destroy_mutex(&(queue->mutex));
+
+	return 0;
+}
+
+
+/* memory */
+
+inline void* xp_malloc(size_t size)
+{
+	return malloc(size, M_DAZUKOBUF, M_WAITOK);
+}
+
+inline int xp_free(void *ptr)
+{
+	free(ptr, M_DAZUKOBUF);
+
+	return 0;
+}
+
+inline int xp_copyin(const void *user_src, void *kernel_dest, size_t size)
+{
+	return copyin(user_src, kernel_dest, size);
+}
+
+inline int xp_copyout(const void *kernel_src, void *user_dest, size_t size)
+{
+	return copyout(kernel_src, user_dest, size);
+}
+
+inline int xp_verify_user_writable(const void *user_ptr, size_t size)
+{
+	return 0;
+}
+
+inline int xp_verify_user_readable(const void *user_ptr, size_t size)
+{
+	return 0;
+}
+
+
+/* path attribute */
+
+inline int xp_is_absolute_path(const char *path)
+{
+	return (path[0] == '/');
+}
+
+
+/* atomic */
+
+inline int xp_atomic_set(struct xp_atomic *atomic, int value)
+{
+	atomic->value = value;
+
+	return 0;
+}
+
+inline int xp_atomic_inc(struct xp_atomic *atomic)
+{
+	(atomic->value)++;
+
+	return 0;
+}
+
+inline int xp_atomic_dec(struct xp_atomic *atomic)
+{
+	(atomic->value)--;
+
+	return 0;
+}
+
+inline int xp_atomic_read(struct xp_atomic *atomic)
+{
+	return atomic->value;
+}
+
+
+/* file structure */
+
+static void freebsd_get_filename_full_fileinfo(struct thread *t, const char *path, char **fullpath, char **freefullpath, struct file_properties *file_p, int follow_symlinks)
+{
+	struct thread		localt;
+	struct proc		localp;
+	struct nameidata	nd;
+	struct filedesc		localfd;
+	struct vattr		vattr;
+	int			error = 0;
+
+	if (t == NULL || path == NULL || fullpath == NULL || freefullpath == NULL || file_p == NULL)
+		return;
+
+	dazuko_bzero(&nd, sizeof(nd));
+	dazuko_bzero(&localt, sizeof(localt));
+	dazuko_bzero(&localp, sizeof(localp));
+	dazuko_bzero(&localfd, sizeof(localfd));
+	dazuko_bzero(file_p, sizeof(struct file_properties));
+
+	NDINIT(&nd, LOOKUP, follow_symlinks ? FOLLOW : NOFOLLOW, UIO_USERSPACE, path, t);
+
+	error = namei(&nd);
+
+	if (error != 0)
+	{
+		if (error == ENOENT)
+		{
+			/* let's try to resolve the parent dir (if possible) */
+			char * kpath = xp_malloc(MAXPATHLEN+1);
+			char * fname = kpath;
+			char * lookuppath = ".";
+			char * pfullpath = NULL;
+			char * pfreefullpath = NULL;
+			size_t len;
+			int i;
+			struct nameidata ndparent;
+
+			if (kpath == NULL)
+				return;
+
+			dazuko_bzero(kpath, MAXPATHLEN+1);
+			copyinstr(path, kpath, MAXPATHLEN+1, &len);
+
+			/* find the last "/" */
+			for (i=strlen(kpath) ; i>=0 ; i--)
+			{
+				if (kpath[i] == '/')
+				{
+					if (i == 0)
+					{
+						/* the only "/" is the root */
+						lookuppath = "/";
+					}
+					else
+					{
+						kpath[i] = 0;
+						lookuppath = kpath;
+					}
+
+					fname = kpath + i + 1;
+
+					break;
+				}
+			}
+
+			/* at this point we have:
+			 * lookuppath = the name of the parent directory to lookup
+			 * fname = the file name that was not found by the previous namei
+			 */
+
+			dazuko_bzero(&ndparent, sizeof(ndparent));
+
+			NDINIT(&ndparent, LOOKUP, NOFOLLOW, UIO_SYSSPACE, lookuppath, t);
+
+			error = namei(&ndparent);
+
+			if (error)
+			{
+				xp_free(kpath);
+				return;
+			}
+
+			if (ndparent.ni_vp != NULL)
+			{
+				localt.td_proc = &localp;
+				localt.td_proc->p_fd = &localfd;
+				localt.td_proc->p_fd->fd_sx = t->td_proc->p_fd->fd_sx;
+
+				if (orig_rootmnt != NULL)
+					localt.td_proc->p_fd->fd_rdir = orig_rootmnt;
+				else
+					localt.td_proc->p_fd->fd_rdir = ndparent.ni_rootdir;
+
+				vn_fullpath(&localt, ndparent.ni_vp, &pfullpath, &pfreefullpath);
+
+				if (pfreefullpath != NULL)
+				{
+					len = strlen(pfullpath) + strlen(fname) + 2;
+					*fullpath = malloc(len, M_TEMP, M_WAITOK);
+					if (*fullpath != NULL)
+					{
+						strcpy(*fullpath, pfullpath);
+
+						/* we don't add "/" if it is root */
+						if ((pfullpath[0] != '/') || (pfullpath[1] != 0))
+							strcat(*fullpath, "/");
+
+						strcat(*fullpath, fname);
+
+						*freefullpath = *fullpath;
+					}
+					free(pfreefullpath, M_TEMP);
+				}
+			}
+
+			NDFREE(&ndparent, 0);
+			xp_free(kpath);
+		}
+		else
+		{
+			/*
+			 * we need to understand why this fails sometimes
+			 */
+		}
+	}
+	else
+	{
+		localt.td_proc = &localp;
+		localt.td_proc->p_fd = &localfd;
+		localt.td_proc->p_fd->fd_sx = t->td_proc->p_fd->fd_sx;
+
+		if (orig_rootmnt != NULL)
+			localt.td_proc->p_fd->fd_rdir = orig_rootmnt;
+		else
+			localt.td_proc->p_fd->fd_rdir = nd.ni_rootdir;
+
+		vn_fullpath(&localt, nd.ni_vp, fullpath, freefullpath);
+
+		if (nd.ni_vp != NULL)
+		{
+			if (VOP_GETATTR(nd.ni_vp, &vattr, t->td_proc->p_ucred, t) == 0)
+			{
+				file_p->size = vattr.va_size;
+				file_p->set_size = 1;
+				file_p->uid = vattr.va_uid;
+				file_p->set_uid = 1;
+				file_p->gid = vattr.va_gid;
+				file_p->set_gid = 1;
+				file_p->mode = vattr.va_mode;
+				file_p->set_mode = 1;
+				file_p->device_type = vattr.va_fsid;
+				file_p->set_device_type = 1;
+
+				switch (nd.ni_vp->v_type)
+				{
+					case VDIR:
+						file_p->type = DAZUKO_DIRECTORY;
+						file_p->set_type = 1;
+						break;
+					case VREG:
+						file_p->type = DAZUKO_REGULAR;
+						file_p->set_type = 1;
+						break;
+					case VLNK:
+						file_p->type = DAZUKO_LINK;
+						file_p->set_type = 1;
+						break;
+					default:
+						break;
+				}
+			}
+		}
+
+		/* deref looked up vnode */
+		NDFREE(&nd, 0);
+	}
+}
+
+static void freebsd_get_fd_full_fileinfo(struct thread *t, int fd, char **fullpath, char **freefullpath, struct file_properties *file_p)
+{
+	struct thread		localt;
+	struct proc		localp;
+	struct filedesc		localfd;
+	struct vattr		vattr;
+	struct file		*fp;
+	struct vnode		*vp;
+
+	if (t == NULL || fullpath == NULL || freefullpath == NULL || file_p == NULL || orig_rootmnt == NULL)
+		return;
+
+	if (t->td_proc == NULL)
+		return;
+
+	if (t->td_proc->p_fd == NULL)
+		return;
+
+	if (getvnode(t->td_proc->p_fd, fd, &fp) != 0)
+		return;
+
+	if (fp == NULL)
+	{
+		fdrop(fp, t);
+		return;
+	}
+
+	vp = fp->f_vnode;
+
+	if (vp == NULL)
+	{
+		fdrop(fp, t);
+		return;
+	}
+
+	dazuko_bzero(&localt, sizeof(localt));
+	dazuko_bzero(&localp, sizeof(localp));
+	dazuko_bzero(&localfd, sizeof(localfd));
+	dazuko_bzero(file_p, sizeof(struct file_properties));
+
+	localt.td_proc = &localp;
+	localt.td_proc->p_fd = &localfd;
+	localt.td_proc->p_fd->fd_sx = t->td_proc->p_fd->fd_sx;
+
+	localt.td_proc->p_fd->fd_rdir = orig_rootmnt;
+
+	vn_fullpath(&localt, vp, fullpath, freefullpath);
+
+	if (VOP_GETATTR(vp, &vattr, t->td_proc->p_ucred, t) == 0)
+	{
+		file_p->size = vattr.va_size;
+		file_p->set_size = 1;
+		file_p->uid = vattr.va_uid;
+		file_p->set_uid = 1;
+		file_p->gid = vattr.va_gid;
+		file_p->set_gid = 1;
+		file_p->mode = vattr.va_mode;
+		file_p->set_mode = 1;
+		file_p->device_type = vattr.va_fsid;
+		file_p->set_device_type = 1;
+
+		switch (vp->v_type)
+		{
+			case VDIR:
+				file_p->type = DAZUKO_DIRECTORY;
+				file_p->set_type = 1;
+				break;
+			case VREG:
+				file_p->type = DAZUKO_REGULAR;
+				file_p->set_type = 1;
+				break;
+			case VLNK:
+				file_p->type = DAZUKO_LINK;
+				file_p->set_type = 1;
+				break;
+			default:
+				break;
+		}
+	}
+
+	fdrop(fp, t);
+}
+
+inline int xp_fill_file_struct(struct dazuko_file_struct *dfs)
+{
+	char				*fullpath = NULL;
+	char				*freefullpath = NULL;
+	int				length;
+	struct dazuko_file_listnode	*listnode;
+	int				follow_symlinks = 0;
+	int				error = 0;
+	int				loopcount = 0;
+
+	if (dfs == NULL)
+		return -1;
+
+	/* check if filenames have already been filled in */
+	if (dfs->aliases != NULL)
+		return 0;
+
+	if (dfs->extra_data == NULL)
+		return -1;
+
+	while (1)
+	{
+		loopcount++;
+
+		listnode = (struct dazuko_file_listnode *)xp_malloc(sizeof(struct dazuko_file_listnode));
+		if (listnode == NULL)
+		{
+			error = -1;
+			break;
+		}
+
+		dazuko_bzero(listnode, sizeof(struct dazuko_file_listnode));
+
+		if (dfs->extra_data->user_filename != NULL)
+		{
+			freebsd_get_filename_full_fileinfo(dfs->extra_data->t, dfs->extra_data->user_filename, &fullpath, &freefullpath, &(dfs->file_p), follow_symlinks);
+		}
+		else
+		{
+			freebsd_get_fd_full_fileinfo(dfs->extra_data->t, dfs->extra_data->fd, &fullpath, &freefullpath, &(dfs->file_p));
+
+			/* make sure we don't loop a 2nd time */
+			loopcount++;
+		}
+
+		if (freefullpath)
+		{
+			length = dazuko_strlen(fullpath);
+
+			listnode->filename = (char *)xp_malloc(length + 1);
+			if (listnode->filename != NULL)
+			{
+				memcpy(listnode->filename, fullpath, length);
+				listnode->filename[length] = 0;
+				listnode->filename_length = length;  /* the string length */
+			}
+
+			/* this memory is freed from a different pool than
+			 * xp_malloc would use */
+
+			free(freefullpath, M_TEMP);
+		}
+
+		if (dfs->aliases == NULL)
+		{
+			listnode->next = dfs->aliases;
+			dfs->aliases = listnode;
+		}
+		else
+		{
+			listnode->next = dfs->aliases->next;
+			dfs->aliases->next = listnode;
+		}
+
+		if (!follow_symlinks && dfs->file_p.set_type && dfs->file_p.type == DAZUKO_LINK && loopcount < 2)
+		{
+			/* this is a link, we will grab the real path now */
+
+			follow_symlinks = 1;
+		}
+		else
+		{
+			/* we've grabbed the real path (or we already have 2 paths), so we are done */
+
+			break;
+		}
+	}
+
+	if (!error && dfs->aliases->filename == NULL && dfs->extra_data->user_filename != NULL)
+	{
+		/* we couldn't get any filename, so we'll just grab the user parameter
+		 * note: dfs->aliases was already allocated previously, we just have to fill it */
+
+		for (length=0 ; fubyte((dfs->extra_data->user_filename)+length) ; length++);
+
+		length++;
+
+		dfs->aliases->filename = (char *)xp_malloc(length);
+		if (dfs->aliases->filename != NULL)
+		{
+			if (xp_copyin(dfs->extra_data->user_filename, dfs->aliases->filename, length) != 0)
+			{
+				xp_print("dazuko: error: xp_fill_file_struct.xp_copyin() failed\n");
+				xp_free(dfs->aliases->filename);
+				dfs->aliases->filename = NULL;
+				dfs->aliases->filename_length = 0;
+			}
+			else
+			{
+				dfs->aliases->filename_length = length - 1;  /* the string length */
+			}
+		}
+	}
+
+	return error;
+}
+
+static int dazuko_file_struct_cleanup(struct dazuko_file_struct **dfs)
+{
+	struct dazuko_file_listnode	*cur;
+
+	if (dfs == NULL)
+		return 0;
+
+	if (*dfs == NULL)
+		return 0;
+
+	while ((*dfs)->aliases != NULL)
+	{
+		cur = (*dfs)->aliases;
+		(*dfs)->aliases = cur->next;
+
+		if (cur->filename != NULL)
+			xp_free(cur->filename);
+
+		xp_free(cur);
+	}
+
+	if ((*dfs)->extra_data != NULL)
+		xp_free((*dfs)->extra_data);
+
+	xp_free(*dfs);
+
+	*dfs = NULL;
+
+	return 0;
+}
+
+
+/* daemon id */
+
+static inline int check_parent(struct proc *parent, struct proc *child)
+{
+	struct proc	*ts = child;
+	int 		rc = -1;
+
+	if (parent == NULL || child == NULL)
+		return -1;
+
+/* LOCK */
+	sx_slock(&proctree_lock);
+
+	while (1)
+	{
+		if (ts == parent)
+		{
+			rc = 0;
+			break;
+		}
+
+		if (ts->p_pptr == NULL)
+			break;
+
+		if (ts == ts->p_pptr)
+			break;
+
+		ts = ts->p_pptr;
+	}
+
+	sx_sunlock(&proctree_lock);
+/* UNLOCK */
+
+	return rc;
+}
+
+inline int xp_id_compare(struct xp_daemon_id *id1, struct xp_daemon_id *id2, int check_related)
+{
+	if (id1 == NULL || id2 == NULL)
+		return DAZUKO_DIFFERENT;
+
+	if (id1->pid == id2->pid && id1->proc == id2->proc && id1->fd == id2->fd)
+		return DAZUKO_SAME;
+
+	if (check_related)
+	{
+		if (check_parent(id1->proc, id2->proc) == 0)
+		{
+			return DAZUKO_CHILD;
+		}
+		else if (id1->pid == id2->pid || id1->proc == id2->proc || id1->fd == id2->fd)
+		{
+			return DAZUKO_SUSPICIOUS;
+		}
+	}
+
+	return DAZUKO_DIFFERENT;
+}
+
+inline int xp_id_free(struct xp_daemon_id *id)
+{
+	xp_free(id);
+
+	return 0;
+}
+
+inline struct xp_daemon_id* xp_id_copy(struct xp_daemon_id *id)
+{
+	struct xp_daemon_id	*ptr;
+
+	if (id == NULL)
+		return NULL;
+
+	ptr = (struct xp_daemon_id *)xp_malloc(sizeof(struct xp_daemon_id));
+
+	if (ptr != NULL)
+	{
+		ptr->pid = id->pid;
+		ptr->proc = id->proc;
+		ptr->fd = id->fd;
+	}
+
+	return ptr;
+}
+
+
+/* event */
+
+int xp_set_event_properties(struct event_properties *event_p, struct xp_daemon_id *xp_id)
+{
+	event_p->pid = xp_id->pid;
+	event_p->set_pid = 1;
+
+	return 0;
+}
+
+
+/* cache settings */
+
+int xp_init_cache(unsigned long ttl)
+{
+	return -1;
+}
+
+
+/* include/exclude paths */
+
+int xp_set_path(const char *path, int type)
+{
+	return 0;
+}
+
+
+/* system calls */
+
+static inline int check_fd(struct proc *p, int fd)
+{
+	if (p == NULL)
+	{
+		return -1;
+	}
+	else if (p->p_fd == NULL)
+	{
+		return -1;
+	}
+	else if (fd < 0)
+	{
+		return -1;
+	}
+	else if (fd >= p->p_fd->fd_nfiles)
+	{
+		return -1;
+	}
+	else if (p->p_fd->fd_ofiles == NULL)
+	{
+		return -1;
+	}
+	else if (p->p_fd->fd_ofiles[fd] == NULL)
+	{
+		return -1;
+	}
+
+	return 0;
+}
+
+#define DAZUKO_SYSCALL_WRAPPER(syscall_func) static int freebsd_dazuko_sys_##syscall_func(struct thread *t, struct syscall_func##_args *uap) \
+{ \
+	int	ret; \
+	syscall_in_use++; \
+	ret = freebsd_dazuko_sys_##syscall_func##_inner(t, uap); \
+	syscall_in_use--; \
+	return ret; \
+}
+
+#if defined(ON_OPEN_SUPPORT)
+static inline int freebsd_dazuko_sys_open_inner(struct thread *t, struct open_args *uap)
+{
+	struct dazuko_file_struct	*dfs = NULL;
+	struct event_properties		event_p;
+	struct xp_daemon_id		xp_id;
+	int				error = 0;
+	int				check_error = 0;
+
+	if (t == NULL)
+	{
+		xp_print("dazuko: warning: freebsd_dazuko_sys_open(NULL, ...)\n");
+		check_error = -1;
+	}
+	else
+	{
+		freebsd5_setupid(&xp_id, t);
+		check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL);
+	}
+
+	if (!check_error)
+	{
+		dazuko_bzero(&event_p, sizeof(event_p));
+
+		if (uap == NULL)
+		{
+			check_error = -1;
+		}
+		else if (t->td_proc == NULL)
+		{
+			check_error = -1;
+		}
+		else if (t->td_proc->p_ucred == NULL)
+		{
+			check_error = -1;
+		}
+		else
+		{
+			event_p.flags = uap->flags;
+			event_p.set_flags = 1;
+			event_p.mode = uap->mode;
+			event_p.set_mode = 1;
+			event_p.pid = freebsd_getpid(t);
+			event_p.set_pid = 1;
+			event_p.uid = t->td_proc->p_ucred->cr_ruid;
+			event_p.set_uid = 1;
+
+			dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+			if (dfs != NULL)
+			{
+				dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+				dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+				if (dfs->extra_data != NULL)
+				{
+					dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+					dfs->extra_data->user_filename = uap->path;
+					dfs->extra_data->t = t;
+
+					error = dazuko_process_access(DAZUKO_ON_OPEN, dfs, &event_p, NULL);
+
+					dazuko_file_struct_cleanup(&dfs);
+				}
+				else
+				{
+					xp_free(dfs);
+					dfs = NULL;
+				}
+			}
+		}
+	}
+
+	if (error)
+	{
+		/* access should be blocked */
+
+		error = EPERM;
+	}
+	else
+	{
+		/* call the standard open function */
+		error = original_sys_open(t, uap);
+	}
+
+	return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(open)
+
+static inline int freebsd_dazuko_sys_dup_inner(struct thread *t, struct dup_args *uap)
+{
+	struct dazuko_file_struct	*dfs = NULL;
+	int				error = 0;
+	int				check_error = 0;
+	struct event_properties		event_p;
+	struct xp_daemon_id		xp_id;
+
+	if (t == NULL)
+	{
+		xp_print("dazuko: warning: freebsd_dazuko_sys_dup(NULL, ...)\n");
+		check_error = -1;
+	}
+	else
+	{
+		freebsd5_setupid(&xp_id, t);
+		check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL);
+	}
+
+	if (!check_error)
+	{
+		if (uap == NULL)
+		{
+			check_error = -1;
+		}
+		else if (check_fd(t->td_proc, uap->fd) != 0)
+		{
+			check_error = -1;
+		}
+		else if (t->td_proc->p_ucred == NULL)
+		{
+			check_error = -1;
+		}
+		else
+		{
+			dazuko_bzero(&event_p, sizeof(event_p));
+
+			event_p.pid = freebsd_getpid(t);
+			event_p.set_pid = 1;
+			event_p.uid = t->td_proc->p_ucred->cr_ruid;
+			event_p.set_uid = 1;
+
+			dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+			if (dfs != NULL)
+			{
+				dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+				dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+				if (dfs->extra_data != NULL)
+				{
+					dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+					dfs->extra_data->fd = uap->fd;
+					dfs->extra_data->t = t;
+
+					error = dazuko_process_access(DAZUKO_ON_OPEN, dfs, &event_p, NULL);
+
+					dazuko_file_struct_cleanup(&dfs);
+				}
+				else
+				{
+					xp_free(dfs);
+					dfs = NULL;
+				}
+			}
+		}
+	}
+
+	if (error)
+	{
+		/* access should be blocked */
+
+		error = EPERM;
+	}
+	else
+	{
+		/* call the standard dup function */
+		error = original_sys_dup(t, uap);
+	}
+
+	return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(dup)
+#endif
+
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+static inline int freebsd_dazuko_sys_dup2_inner(struct thread *t, struct dup2_args *uap)
+{
+	struct dazuko_file_struct	*dfs = NULL;
+	struct event_properties		open_event_p;
+	struct xp_daemon_id		xp_id;
+	int				error = 0;
+	int				open_check_error = 0;
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+	struct event_properties		close_event_p;
+	int				close_check_error = 0;
+	int				will_close_newfd = 0;
+#endif
+
+	if (t == NULL)
+	{
+		xp_print("dazuko: warning: freebsd_dazuko_sys_dup2(NULL, ...)\n");
+		open_check_error = -1;
+	}
+	else
+	{
+		freebsd5_setupid(&xp_id, t);
+		open_check_error = dazuko_check_access(DAZUKO_ON_OPEN, 1, &xp_id, NULL);
+	}
+
+	if (!open_check_error)
+	{
+		dazuko_bzero(&open_event_p, sizeof(open_event_p));
+
+		if (uap == NULL)
+		{
+			open_check_error = -1;
+		}
+		else if (uap->from == uap->to)
+		{
+			/* oldfd and newfd are equal, there is nothing to do */
+			open_check_error = -1;
+		}
+		else if (check_fd(t->td_proc, uap->from) != 0)
+		{
+			open_check_error = -1;
+		}
+		else if (t->td_proc->p_ucred == NULL)
+		{
+			open_check_error = -1;
+		}
+		else
+		{
+			open_event_p.pid = freebsd_getpid(t);
+			open_event_p.set_pid = 1;
+			open_event_p.uid = t->td_proc->p_ucred->cr_ruid;
+			open_event_p.set_uid = 1;
+
+			dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+			if (dfs != NULL)
+			{
+				dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+				dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+				if (dfs->extra_data != NULL)
+				{
+					dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+					dfs->extra_data->fd = uap->from;
+					dfs->extra_data->t = t;
+
+					error = dazuko_process_access(DAZUKO_ON_OPEN, dfs, &open_event_p, NULL);
+
+					dazuko_file_struct_cleanup(&dfs);
+				}
+				else
+				{
+					xp_free(dfs);
+					dfs = NULL;
+				}
+			}
+		}
+	}
+
+	if (error)
+	{
+		/* access should be blocked */
+
+		error = EPERM;
+	}
+	else
+	{
+		#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+		{
+			close_check_error = dazuko_check_access(DAZUKO_ON_CLOSE, 1, &xp_id, NULL);
+
+			if (!close_check_error)
+			{
+
+				if (check_fd(t->td_proc, uap->to) == 0)
+				{
+					will_close_newfd = 1;
+				}
+			}
+		}
+		#endif
+
+		/* call the standard dup2 function */
+		error = original_sys_dup2(t, uap);
+
+		#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+		{
+			if (!close_check_error)
+			{
+				if (!error && will_close_newfd && check_fd(t->td_proc, t->td_retval[0]) == 0)
+				{
+					dazuko_bzero(&close_event_p, sizeof(close_event_p));
+
+					close_event_p.pid = freebsd_getpid(t);
+					close_event_p.set_pid = 1;
+					close_event_p.uid = t->td_proc->p_ucred->cr_ruid;
+					close_event_p.set_uid = 1;
+
+					dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+					if (dfs != NULL)
+					{
+						dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+						dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+						if (dfs->extra_data != NULL)
+						{
+							dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+							dfs->extra_data->fd = t->td_retval[0];
+							dfs->extra_data->t = t;
+
+							dazuko_process_access(DAZUKO_ON_CLOSE, dfs, &close_event_p, NULL);
+
+							dazuko_file_struct_cleanup(&dfs);
+						}
+						else
+						{
+							xp_free(dfs);
+							dfs = NULL;
+						}
+					}
+				}
+			}
+		}
+		#endif
+	}
+
+	return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(dup2)
+
+#endif
+
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+static inline int freebsd_dazuko_sys_close_inner(struct thread *t, struct close_args *uap)
+{
+	/* The kernel wants to close the given file
+	 * descriptor. */
+
+	struct dazuko_file_struct	*dfs = NULL;
+	int				error = 0;
+	int				check_error = 0;
+	struct event_properties		event_p;
+	struct xp_daemon_id		xp_id;
+
+	if (t == NULL)
+	{
+		xp_print("dazuko: warning: freebsd_dazuko_sys_close(NULL, ...)\n");
+		check_error = -1;
+	}
+	else
+	{
+		freebsd5_setupid(&xp_id, t);
+		check_error = dazuko_check_access(DAZUKO_ON_CLOSE, 1, &xp_id, NULL);
+	}
+
+	if (!check_error)
+	{
+		if (uap == NULL)
+		{
+			check_error = -1;
+		}
+		else if (t->td_proc == NULL)
+		{
+			check_error = -1;
+		}
+		else if (t->td_proc->p_ucred == NULL)
+		{
+			check_error = -1;
+		}
+		else
+		{
+			dazuko_bzero(&event_p, sizeof(event_p));
+
+			event_p.pid = freebsd_getpid(t);
+			event_p.set_pid = 1;
+			event_p.uid = t->td_proc->p_ucred->cr_ruid;
+			event_p.set_uid = 1;
+
+			dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+			if (dfs != NULL)
+			{
+				dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+				dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+				if (dfs->extra_data != NULL)
+				{
+					dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+					dfs->extra_data->fd = uap->fd;
+					dfs->extra_data->t = t;
+
+					check_error = xp_fill_file_struct(dfs);
+				}
+				else
+				{
+					xp_free(dfs);
+					dfs = NULL;
+				}
+			}
+		}
+	}
+
+	error = original_sys_close(t, uap);
+
+	if (dfs != NULL)
+	{
+		if (!check_error)
+		{
+			dazuko_process_access(DAZUKO_ON_CLOSE, dfs, &event_p, NULL);
+		}
+
+		dazuko_file_struct_cleanup(&dfs);
+	}
+
+	return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(close)
+#endif
+
+static inline int freebsd_dazuko_sys_generic(int event, struct thread *t, const char *user_filename, int daemon_is_allowed)
+{
+	struct dazuko_file_struct	*dfs = NULL;
+	struct event_properties		event_p;
+	struct xp_daemon_id		xp_id;
+	int				error = 0;
+	int				check_error = 0;
+	struct slot_list		*sl = NULL;
+
+	if (t == NULL)
+		return -1;
+
+	freebsd5_setupid(&xp_id, t);
+	check_error = dazuko_check_access(event, daemon_is_allowed, &xp_id, &sl);
+
+	if (check_error == 0)
+	{
+		if (user_filename == NULL)
+		{
+			xp_print("dazuko: warning: freebsd_dazuko_sys_generic(%d, t, %s)\n", event, user_filename ? "user_filename" : "NULL");
+			check_error = -1;
+		}
+		else if (t->td_proc == NULL)
+		{
+			xp_print("dazuko: warning: freebsd_dazuko_sys_generic.t->td_proc=NULL\n");
+			check_error = -1;
+		}
+		else if (t->td_proc->p_ucred == NULL)
+		{
+			xp_print("dazuko: warning: freebsd_dazuko_sys_generic.t->td_proc->p_ucred=NULL\n");
+			check_error = -1;
+		}
+		else
+		{
+			dazuko_bzero(&event_p, sizeof(event_p));
+			event_p.pid = freebsd_getpid(t);
+			event_p.set_pid = 1;
+			event_p.uid = t->td_proc->p_ucred->cr_ruid;
+			event_p.set_uid = 1;
+
+			dfs = (struct dazuko_file_struct *)xp_malloc(sizeof(struct dazuko_file_struct));
+			if (dfs != NULL)
+			{
+				dazuko_bzero(dfs, sizeof(struct dazuko_file_struct));
+
+				dfs->extra_data = (struct xp_file_struct *)xp_malloc(sizeof(struct xp_file_struct));
+				if (dfs->extra_data)
+				{
+					dazuko_bzero(dfs->extra_data, sizeof(struct xp_file_struct));
+
+					dfs->extra_data->user_filename = user_filename;
+					dfs->extra_data->t = t;
+
+					error = dazuko_process_access(event, dfs, &event_p, sl);
+
+					dazuko_file_struct_cleanup(&dfs);
+				}
+				else
+				{
+					xp_free(dfs);
+					dfs = NULL;
+				}
+			}
+		}
+	}
+
+	return error;
+}
+
+#ifdef ON_EXEC_SUPPORT
+static inline int freebsd_dazuko_sys_execve_inner(struct thread *t, struct execve_args *uap)
+{
+	int	error;
+
+	error = freebsd_dazuko_sys_generic(DAZUKO_ON_EXEC, t, uap->fname, 0);
+
+	if (error)
+		return error;
+
+	return original_sys_execve(t, uap);
+}
+
+DAZUKO_SYSCALL_WRAPPER(execve)
+#endif
+
+#ifdef ON_UNLINK_SUPPORT
+static inline int freebsd_dazuko_sys_unlink_inner(struct thread *t, struct unlink_args *uap)
+{
+	int	error;
+
+	error = freebsd_dazuko_sys_generic(DAZUKO_ON_UNLINK, t, uap->path, 1);
+
+	if (error)
+		return error;
+
+	return original_sys_unlink(t, uap);
+}
+
+DAZUKO_SYSCALL_WRAPPER(unlink)
+#endif
+
+#ifdef ON_RMDIR_SUPPORT
+static inline int freebsd_dazuko_sys_rmdir_inner(struct thread *t, struct rmdir_args *uap)
+{
+	int	error;
+
+	error = freebsd_dazuko_sys_generic(DAZUKO_ON_RMDIR, t, uap->path, 1);
+
+	if (error)
+		return error;
+
+	return original_sys_rmdir(t, uap);
+}
+
+DAZUKO_SYSCALL_WRAPPER(rmdir)
+#endif
+
+
+/* system hook */
+
+#define DAZUKO_HOOK(syscall_func) do \
+{ \
+	if ((sysent[SYS_##syscall_func].sy_narg) != freebsd_dazuko_sys_##syscall_func##_sysent.sy_narg) \
+	{ \
+		DPRINT(("dazuko: incompatible " #syscall_func " syscall narg\n")); \
+	} \
+	else \
+	{ \
+		original_sys_##syscall_func = sysent[SYS_##syscall_func].sy_call; \
+		sysent[SYS_##syscall_func].sy_call = freebsd_dazuko_sys_##syscall_func##_sysent.sy_call; \
+		DPRINT(("dazuko: hooked sys_" #syscall_func "\n")); \
+	} \
+} \
+while (0)
+
+inline int xp_sys_hook()
+{
+	sdev = make_dev(&cdepts, 0, UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME);
+
+#if defined(ON_OPEN_SUPPORT)
+	DAZUKO_HOOK(open);
+	DAZUKO_HOOK(dup);
+#endif
+
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+	DAZUKO_HOOK(dup2);
+#endif
+
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+	DAZUKO_HOOK(close);
+#endif
+
+#ifdef ON_EXEC_SUPPORT
+	DAZUKO_HOOK(execve);
+#endif
+
+#ifdef ON_UNLINK_SUPPORT
+	DAZUKO_HOOK(unlink);
+#endif
+
+#ifdef ON_RMDIR_SUPPORT
+	DAZUKO_HOOK(rmdir);
+#endif
+
+	return 0;
+}
+
+#define DAZUKO_UNHOOK(syscall_func) do \
+{ \
+	if (original_sys_##syscall_func != NULL) \
+	{ \
+		if (sysent[SYS_##syscall_func].sy_call != freebsd_dazuko_sys_##syscall_func##_sysent.sy_call) \
+			xp_print("dazuko: " #syscall_func " system call has been changed (system may be left in an unstable state!)\n"); \
+		sysent[SYS_##syscall_func].sy_call = (sy_call_t*)original_sys_##syscall_func; \
+		DPRINT(("dazuko: unhooked sys_" #syscall_func "\n")); \
+	} \
+} \
+while (0)
+
+inline int xp_sys_unhook()
+{
+#if defined(ON_OPEN_SUPPORT)
+	DAZUKO_UNHOOK(open);
+	DAZUKO_UNHOOK(dup);
+#endif
+
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+	DAZUKO_UNHOOK(dup2);
+#endif
+
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+	DAZUKO_UNHOOK(close);
+#endif
+
+#ifdef ON_EXEC_SUPPORT
+	DAZUKO_UNHOOK(execve);
+#endif
+
+#ifdef ON_UNLINK_SUPPORT
+	DAZUKO_UNHOOK(unlink);
+#endif
+
+#ifdef ON_RMDIR_SUPPORT
+	DAZUKO_UNHOOK(rmdir);
+#endif
+
+	while (syscall_in_use > 0)
+	{
+		DPRINT(("syscall still in use, yielding (%d)\n", syscall_in_use));
+		yield(curthread, NULL);
+	}
+
+	destroy_dev(sdev);
+
+	return 0;
+}
+
+
+/* output */
+
+int xp_print(const char *fmt, ...)
+{
+	va_list	ap;
+
+	va_start(ap, fmt);
+	vprintf(fmt, ap);
+	va_end(ap);
+
+	return 0;
+}
+
+
+/* device file operations */
+
+int freebsd_dazuko_device_open(struct cdev *dev, int oflags, int devtype, struct thread *t)
+{
+	DPRINT(("dazuko: freebsd_dazuko_device_open() [%d]\n", freebsd_getpid(t)));
+
+	return 0;
+}
+
+static int read_dev_major(struct uio *uio)
+{
+	size_t	dev_major_len;
+	char	tmp[32];
+
+	if (dev_major < 0)
+		return ENODEV;
+
+	if (uio->uio_offset != 0)
+		return 0;
+
+	/* print dev_major to a string
+ 	* and get length */
+	dazuko_bzero(tmp, sizeof(tmp));
+
+	dev_major_len = dazuko_snprintf(tmp, sizeof(tmp), "%d", dev_major);
+
+	if (tmp[sizeof(tmp)-1] != 0)
+	{
+		xp_print("dazuko: failing device_read, device number overflow for dameon %d (dev_major=%d)\n", freebsd_getpid(uio->uio_td), dev_major);
+		return EFAULT;
+	}
+
+	if (uio->uio_iov == NULL)
+	{
+		xp_print("dazuko: error: freebsd_dazuko_device_read.uio->uio_iov=NULL\n");
+		return EFAULT;
+	}
+
+	if (uio->uio_iov->iov_len < dev_major_len)
+		return EINVAL;
+
+	/* copy dev_major string to userspace */
+	if (uiomove(tmp, dev_major_len, uio) != 0)
+		return EFAULT;
+
+	return 0;
+}
+
+int freebsd_dazuko_device_read(struct cdev *dev, struct uio *uio, int ioflag)
+{
+	struct xp_daemon_id	xp_id;
+
+	if (uio == NULL)
+	{
+		xp_print("dazuko: error: freebsd_dazuko_device_read(..., NULL, ...)\n");
+		return EFAULT;
+	}
+
+	if (uio->uio_td == NULL)
+	{
+		xp_print("dazuko: error: freebsd_dazuko_device_read.uio->uio_td=NULL\n");
+		return EFAULT;
+	}
+
+	if (uio->uio_td->td_proc->p_ucred == NULL)
+	{
+		xp_print("dazuko: error: freebsd_dazuko_device_read.uio->uio_td->td_proc->p_ucred=NULL\n");
+		return EFAULT;
+	}
+
+	DPRINT(("dazuko: freebsd_dazuko_device_read() [%d]\n", freebsd_getpid(uio->uio_td)));
+
+	freebsd5_setupid(&xp_id, uio->uio_td);
+
+	/* return dev_major if process is not registered */
+	if (!dazuko_is_our_daemon(&xp_id, NULL, NULL))
+		return read_dev_major(uio);
+
+	return 0;
+}
+
+int freebsd_dazuko_device_write(struct cdev *dev, struct uio *uio, int ioflag)
+{
+	struct xp_daemon_id	xp_id;
+	char			buffer[32];
+	int			size;
+
+	if (uio == NULL)
+	{
+		xp_print("dazuko: error: freebsd_dazuko_device_write(..., NULL, ...)\n");
+		return EFAULT;
+	}
+
+	if (uio->uio_td == NULL)
+	{
+		xp_print("dazuko: error: freebsd_dazuko_device_write.uio->uio_td=NULL\n");
+		return EFAULT;
+	}
+
+	if (uio->uio_td->td_proc->p_ucred == NULL)
+	{
+		xp_print("dazuko: error: freebsd_dazuko_device_write.uio->uio_td->td_proc->p_ucred=NULL\n");
+		return EFAULT;
+	}
+
+	size = uio->uio_resid;
+	if (size >= sizeof(buffer))
+		size = sizeof(buffer) - 1;
+
+	/* copy request_pointer string to kernelspace */
+	if (uiomove(buffer, size, uio) != 0)
+	{
+		xp_print("dazuko: error: freebsd_dazuko_device_write.uiomove!=0\n");
+		return EFAULT;
+	}
+
+	buffer[size] = 0;
+
+	freebsd5_setupid(&xp_id, uio->uio_td);
+
+	if (dazuko_handle_user_request(buffer, &xp_id) == 0)
+		return uio->uio_resid;
+	else
+		return EINTR;
+}
+
+int freebsd_dazuko_device_close(struct cdev *dev, int fflag, int devtype, struct thread *t)
+{
+	struct xp_daemon_id	xp_id;
+
+	DPRINT(("dazuko: dazuko_device_close() [%d]\n", freebsd_getpid(t)));
+
+	freebsd5_setupid(&xp_id, t);
+
+	/* note: This only works for compat1 mode.
+	 * For 1.3, the daemon must properly unregister.
+	 */
+
+	return dazuko_unregister_daemon(&xp_id);
+}
+
+
+/* init/exit */
+
+static int dazuko_loader(struct module *m, int what, void *arg)
+{
+	int			err = 0;
+	struct nameidata	nd;
+
+	switch (what)
+	{
+		case MOD_LOAD:
+			err = dazuko_init();
+
+			if (!err)
+			{
+				NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, "/", curthread);
+
+				if (namei(&nd) != 0)
+				{
+					xp_print("dazuko: warning: failed to get root mount\n");
+				}
+				else
+				{
+					orig_rootmnt = nd.ni_rootdir;
+					vref(orig_rootmnt);
+
+					/* deref looked up vnode */
+					NDFREE(&nd, 0);
+				}
+			}
+			break;
+
+		case MOD_UNLOAD:
+			if (dazuko_exit() != 0)
+				err = EPERM;
+
+			if (orig_rootmnt != NULL)
+				vrele(orig_rootmnt);
+
+			break;
+
+		default:
+			err = EINVAL;
+			break;
+	}
+
+	return err;
+}
+
+DEV_MODULE(dazuko, dazuko_loader, NULL);
+
diff -Nru dazuko-2.3.6a/dazuko_platform.h dazuko-2.3.6b/dazuko_platform.h
--- dazuko-2.3.6a/dazuko_platform.h	2005-02-05 12:59:13.000000000 +0100
+++ dazuko-2.3.6b/dazuko_platform.h	2009-03-07 15:19:37.000000000 +0100
@@ -6,6 +6,8 @@
 	#include "dazuko_linux.h"
 #elif defined(FREEBSD5_SUPPORT)
 	#include "dazuko_freebsd5.h"
+#elif defined(FREEBSD7_SUPPORT)
+	#include "dazuko_freebsd5.h"
 #elif defined(__FreeBSD__)
 	#include "dazuko_freebsd.h"
 #else
diff -Nru dazuko-2.3.6a/dazuko_transport.c dazuko-2.3.6b/dazuko_transport.c
--- dazuko-2.3.6a/dazuko_transport.c	2005-05-13 23:28:02.000000000 +0200
+++ dazuko-2.3.6b/dazuko_transport.c	2009-03-07 15:00:23.000000000 +0100
@@ -64,8 +64,12 @@
     #include <linux/stddef.h>
     #include <linux/types.h>
   #elif defined __FreeBSD__
-    #include <stdio.h>
-    #include <sys/types.h>
+	#if defined FREEBSD7_SUPPORT
+		#include <sys/stddef.h>
+	#else
+    		#include <stdio.h>
+	#endif
+    	#include <sys/types.h>
   #elif defined __sun__
     #include <stdio.h>
     #include <sys/types.h>
_______________________________________________
Dazuko-devel mailing list
Dazuko-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/dazuko-devel

Reply via email to