#!/bin/bash
# genlkm
# **********************************************************************
# This program is part of the source code released for the book
#  "Linux Kernel Programming"
#  (c) Author: Kaiwan N Billimoria
#  Publisher:  Packt
#  GitHub repository:
#  https://github.com/PacktPublishing/Linux-Kernel-Programming
# **********************************************************************
# Brief Description:
# Generate a simple Linux LKM (Loadable Kernel Module) 'template'.
# For details, please refer the book, Ch 4.
name=$(basename "$0")

usage()
{
	echo "${name} is a simple Linux kernel module 'generator' script.
(It internally invokes the xcc_lkm.sh script as well).

Usage: ${name} mykmod
 ; where \"mykmod\" is a filename (without any extension)
 This helper script will create a directory under the current one named \"mykmod\"
 and will then generate two files within it:
 (i)  the \"mykmod\".c kernel module 'template' file, and
 (ii) the Makefile for it.
Enjoy!"
}

[ $# -lt 1 ] && {
	usage
	exit 1
}

# Check all params for a "."
for param in "$@"
do
	if [[ "${param}" = *"."* ]]; then
		echo "*** Error: do Not use any extension or \".\", thank you! ***"
		usage
		exit 1
	fi
done

#------------- File Sections ------------------------
HDR_1="/*
 * $1.c
 ***************************************************************
 * This program is <insert your comments here ... >
 ****************************************************************
 * Brief Description:
 *
 */
"

INC_1="
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
"

MAC_1="
#define OURMODNAME   \"$1\"
"

MOD_STUFF="
MODULE_AUTHOR(\"<insert your name here>\");
MODULE_DESCRIPTION(\"<insert your module desc here>\");
MODULE_LICENSE(\"Dual MIT/GPL\");
MODULE_VERSION(\"0.1\");
"

CODE_1="
static int __init $1_init(void)
{
	pr_debug(\"%s: inserted\n\", OURMODNAME);
	return 0;		/* success */
}

static void __exit $1_exit(void)
{
	pr_debug(\"%s: removed\n\", OURMODNAME);
}

module_init($1_init);
module_exit($1_exit);"

#---

if [ ! -d "$1" ] ; then
 mkdir -p "$1"
else
 echo "${name}: the directory $1/ already exists, aborting..."
 exit 1
fi

# Within a sub-shell ...
(
cd "$1" || exit 1
[ -f "$1".c ] && cp -f "$1".c "$1".c.bkp

cat > "$1".c << EOF
${HDR_1}
${INC_1}
${MAC_1}
${MOD_STUFF}
${CODE_1}
EOF

echo "[+] LKM $1/$1.c generated"
ls -l "$1".c

# If our build /cross-compile script is available, lets use it
which xcc_lkm.sh >/dev/null 2>&1 || {
 echo "[!] xcc_lkm.sh script not found (not in PATH?), unable to generate Makefile"
 exit 1
}
echo "[+] Generating the $1/Makefile for $1.c (via xcc_lkm.sh)..."
xcc_lkm.sh "$1"
)
exit 0
