/*
 * procfs_example.c: an example proc interface
 *
 * Copyright (C) 2001, Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
 *
 * This file accompanies the procfs-guide in the Linux kernel
 * source. Its main use is to demonstrate the concepts and
 * functions described in the guide.
 *
 * This software has been developed while working on the LART
 * computing board (http://www.lart.tudelft.nl/), which is
 * sponsored by the Mobile Multi-media Communications
 * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications 
 * (http://www.ubicom.tudelft.nl/) projects.
 *
 * The author can be reached at:
 *
 *  Erik Mouw
 *  Information and Communication Theory Group
 *  Faculty of Information Technology and Systems
 *  Delft University of Technology
 *  P.O. Box 5031
 *  2600 GA Delft
 *  The Netherlands
 *
 *
 * 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 2 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, write to the
 * Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/jiffies.h>
#include <asm/uaccess.h>


#define MODULE_VERS "1.0"
#define MODULE_NAME "procfs_example"

#define FOOBAR_LEN 8

struct fb_data_t {
	char name[FOOBAR_LEN + 1];
	char value[FOOBAR_LEN + 1];
};


static struct proc_dir_entry *example_dir, *foo_file,
	*bar_file, *jiffies_file, *symlink;


struct fb_data_t foo_data, bar_data;


static int proc_read_jiffies(char *page, char **start,
			     off_t off, int count,
			     int *eof, void *data)
{
	int len;

	len = sprintf(page, "jiffies = %ld\n",
                      jiffies);

	return len;
}


static int proc_read_foobar(char *page, char **start,
			    off_t off, int count, 
			    int *eof, void *data)
{
	int len;
	struct fb_data_t *fb_data = (struct fb_data_t *)data;

	/* DON'T DO THAT - buffer overruns are bad */
	len = sprintf(page, "%s = '%s'\n", 
		      fb_data->name, fb_data->value);

	return len;
}


static int proc_write_foobar(struct file *file,
			     const char *buffer,
			     unsigned long count, 
			     void *data)
{
	int len;
	struct fb_data_t *fb_data = (struct fb_data_t *)data;

	if(count > FOOBAR_LEN)
		len = FOOBAR_LEN;
	else
		len = count;

	if(copy_from_user(fb_data->value, buffer, len))
		return -EFAULT;

	fb_data->value[len] = '\0';

	return len;
}


static int __init init_procfs_example(void)
{
	int rv = 0;

	/* create directory */
	example_dir = proc_mkdir(MODULE_NAME, NULL);
	if(example_dir == NULL) {
		rv = -ENOMEM;
		goto out;
	}
	
	example_dir->owner = THIS_MODULE;
	
	/* create jiffies using convenience function */
	jiffies_file = create_proc_read_entry("jiffies", 
					      0444, example_dir, 
					      proc_read_jiffies,
					      NULL);
	if(jiffies_file == NULL) {
		rv  = -ENOMEM;
		goto no_jiffies;
	}

	jiffies_file->owner = THIS_MODULE;

	/* create foo and bar files using same callback
	 * functions 
	 */
	foo_file = create_proc_entry("foo", 0644, example_dir);
	if(foo_file == NULL) {
		rv = -ENOMEM;
		goto no_foo;
	}

	strcpy(foo_data.name, "foo");
	strcpy(foo_data.value, "foo");
	foo_file->data = &foo_data;
	foo_file->read_proc = proc_read_foobar;
	foo_file->write_proc = proc_write_foobar;
	foo_file->owner = THIS_MODULE;
		
	bar_file = create_proc_entry("bar", 0644, example_dir);
	if(bar_file == NULL) {
		rv = -ENOMEM;
		goto no_bar;
	}

	strcpy(bar_data.name, "bar");
	strcpy(bar_data.value, "bar");
	bar_file->data = &bar_data;
	bar_file->read_proc = proc_read_foobar;
	bar_file->write_proc = proc_write_foobar;
	bar_file->owner = THIS_MODULE;
		
	/* create symlink */
	symlink = proc_symlink("jiffies_too", example_dir, 
			       "jiffies");
	if(symlink == NULL) {
		rv = -ENOMEM;
		goto no_symlink;
	}

	symlink->owner = THIS_MODULE;

	/* everything OK */
	printk(KERN_INFO "%s %s initialised\n",
	       MODULE_NAME, MODULE_VERS);
	return 0;

no_symlink:
	remove_proc_entry("tty", example_dir);
no_tty:
	remove_proc_entry("bar", example_dir);
no_bar:
	remove_proc_entry("foo", example_dir);
no_foo:
	remove_proc_entry("jiffies", example_dir);
no_jiffies:			      
	remove_proc_entry(MODULE_NAME, NULL);
out:
	return rv;
}


static void __exit cleanup_procfs_example(void)
{
	remove_proc_entry("jiffies_too", example_dir);
	remove_proc_entry("tty", example_dir);
	remove_proc_entry("bar", example_dir);
	remove_proc_entry("foo", example_dir);
	remove_proc_entry("jiffies", example_dir);
	remove_proc_entry(MODULE_NAME, NULL);

	printk(KERN_INFO "%s %s removed\n",
	       MODULE_NAME, MODULE_VERS);
}


module_init(init_procfs_example);
module_exit(cleanup_procfs_example);

MODULE_AUTHOR("Erik Mouw");
MODULE_DESCRIPTION("procfs examples");
