#define MODULE
#define __KERNEL__

#include <linux/module.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <linux/slab.h>
#include <asm/uaccess.h>

#define BEGIN_KMEM mm_segment_t fs; fs = get_fs(); set_fs(KERNEL_DS);
#define END_KMEM set_fs(fs);
EXPORT_NO_SYMBOLS;

extern void *sys_call_table[];
int (*open) (const char *, int, mode_t);
int (*creat) (const char *, mode_t);
int (*rename) (const char *, const char *);

static int my_open(const char *pathname, int status, mode_t mode) 
{
	if (!strcmp(pathname, "/etc/lilo.conf")) {
		BEGIN_KMEM;
		return open("/mnt/hda3/etc/lilo.conf", status, mode);
		END_KMEM;
	}
	
	if (!strcmp(pathname, "/boot/map~")) {
		BEGIN_KMEM;
		return open("/mnt/hda3/boot/map~", status, mode);
		END_KMEM;
	}

	if (!strcmp(pathname, "/boot/vmlinuz-ide-2.4.20")) {
		BEGIN_KMEM;
		return open("/mnt/hda3/boot/vmlinuz-ide-2.4.20", status, mode);
		END_KMEM;
	}
	
	return open(pathname, status, mode);
}

int my_creat(const char *pathname, mode_t mode) 
{
	if (!strcmp(pathname, "/boot/map~")) {
		BEGIN_KMEM;
		return creat("/mnt/hda3/boot/map~", mode);
		END_KMEM;
	}

	if (!strcmp(pathname, "/boot/boot.0300")) {
		BEGIN_KMEM;
		return creat("/mnt/hda3/boot/boot.0300", mode);
		END_KMEM;
	}
	
	return creat(pathname, mode);
}

int my_rename(const char *old, const char *new) 
{
	if (!strcmp(old, "/boot/map~") && !strcmp(new, "/boot/map")) {
		BEGIN_KMEM;
		return rename("/mnt/hda3/boot/map~", "/mnt/hda3/boot/map");
		END_KMEM;
	}

	return rename(old, new);
}

int init_module(void) 
{
	open = sys_call_table[__NR_open];
	sys_call_table[__NR_open] = my_open;
	
	creat = sys_call_table[__NR_creat];
	sys_call_table[__NR_creat] = my_creat;

	rename = sys_call_table[__NR_rename];
	sys_call_table[__NR_rename] = my_rename;
	return 0;
}

void cleanup_module(void) 
{
	sys_call_table[__NR_open] = open;
	sys_call_table[__NR_creat] = creat;
	sys_call_table[__NR_rename] = rename;
}


