/*    dblinkfs: stores some file's attributes of whole file system (like inodes, file names, file sizes, etc.) in small database.
*     Copyright (C) 2012 by alexus (alexus.o.1982@gmail.com)
* 
*     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 3 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, see <http://www.gnu.org/licenses/>.
*/


/* Necessary includes for device drivers */
#include <linux/init.h>
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
//#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
//#include <linux/errno.h> /* error codes */
//#include <linux/types.h> /* size_t */
//#include <linux/proc_fs.h>
//#include <linux/fcntl.h> /* O_ACCMODE */
//#include <asm/system.h> /* cli(), *_flags */
//#include <asm/uaccess.h> /* copy_from/to_user */
#include <linux/security.h>


int mod_register = 0;

/* lsm hooks */
static int inode_create( struct inode *dir, struct dentry *dentry, 
                                 int mode);
static int inode_mkdir( struct inode * dir, struct dentry * dentry, 
                                int mode );
static int inode_link ( struct dentry * old_dentry, struct inode * dir, 
                                struct dentry * dentry);
static int inode_symlink ( struct inode * dir, struct dentry * dentry, 
                                   const char *old_name);
static int inode_mknod ( struct inode * dir, struct dentry * dentry,
                                 int mode, dev_t dev);
static int inode_rename( struct inode * old_dir,
                                 struct dentry * old_dentry,
                                 struct inode * new_dir,
                                 struct dentry * new_dentry);

// static int sb_mount( char *dev_name, 
// 			     struct nameidata *nd, 
// 			     char *type, 
// 			     unsigned long flags, 
// 			     void *data);

//static int sb_umount( struct vfsmount *mnt, int flags );

//static int inode_permission (struct inode *inode, int mask, 
//                                     struct nameidata *nd);


/* Structure that declares the usual file */
/* access functions */
static struct security_operations security_ops = {
        .inode_create =                 inode_create,
        .inode_mkdir  =                 inode_mkdir,
        .inode_link   =                 inode_link,
        .inode_symlink=                 inode_symlink,
        .inode_mknod  =                 inode_mknod,
        .inode_rename =                 inode_rename,
//	.sb_mount     =			sb_mount,
//	.sb_umount    =			sb_umount,
//        .inode_permission =            inode_permission,
};

static int __init hello_start(void)
{
  printk(KERN_INFO "DBLINKFS: Loading module...\n");  
  
  
        security_module_enable(&security_ops);
        // register as security module
        register_security( &security_ops );
     
        
                //mod_unreg_security(DEVICE_NAME, &rlocate_security_ops);
 
                //unregister_security(&rlocate_security_ops);
        return 0;

}
static void __exit hello_end(void)
{
  printk(KERN_INFO "DBLINKFS: goodbye Mr.\n");
  
  //unregister_security(&security_ops);
//   if ( mod_register ) {
// 	if (mod_unreg_security("dblinkf_module", &security_ops)) 
//                         printk(KERN_INFO "DBLINKFS: failed to unregister "
// 					 "dblinkf_module security module with primary "
// 					 "module.\n");
// 	} 
//   }
  	printk(KERN_INFO "DBLINKFS: unloaded\n");
}
module_init(hello_start);
module_exit(hello_end);

static int inode_create( struct inode *dir, struct dentry *dentry, 
                                 int mode)
{
  printk(KERN_ALERT "DBLINKFS: inode_create executed. mode=%d\n", mode);
  printk(KERN_INFO "DBLINKFS: inode_create executed. mode=%d\n", mode);
  printk(KERN_INFO "DBLINKFS: inode_create executed.\n");
  return 0;
}

static int inode_mkdir( struct inode * dir, struct dentry * dentry, 
                                int mode )
{
  printk(KERN_ALERT "DBLINKFS: mkdir executed. mode=%d\n", mode);
  printk(KERN_INFO "DBLINKFS: mkdir executed. mode=%d\n", mode);
  printk(KERN_INFO "DBLINKFS: mkdir executed.\n");
  return 0;
}

static int inode_link ( struct dentry * old_dentry, struct inode * dir, 
                                struct dentry * dentry)
{
  return 0;
}
static int inode_symlink ( struct inode * dir, struct dentry * dentry, 
                                   const char *old_name)
{
  return 0;
}

static int inode_mknod ( struct inode * dir, struct dentry * dentry,
                                 int mode, dev_t dev)
{
  return 0;
}
static int inode_rename( struct inode * old_dir,
                                 struct dentry * old_dentry,
                                 struct inode * new_dir,
                                 struct dentry * new_dentry)
{
  return 0;
}

// static int sb_mount( char *dev_name, 
// 			     struct nameidata *nd, 
// 			     char *type, 
// 			     unsigned long flags, 
// 			     void *data)
// {
//   return 0;
// }




MODULE_AUTHOR("alexus <www.ru>");
MODULE_DESCRIPTION("dblinkfs desc...");
MODULE_LICENSE("GPL");