#!/bin/bash
###########################################################################
#
# Linux NetBEUI installation script
#
# Copyright (c) 1999 by Procom Technology,Inc.
#
# This program can be redistributed or modified under the terms of the
# GNU General Public License as published by the Free Software Foundation.
# This program is distributed without any warranty or implied warranty
# of merchantability or fitness for a particular purpose.
#
# See the GNU General Public License for more details.
#
###########################################################################

TMP_FILE=/tmp/netb_inst$$
KERNEL_TREE=$1
KERNEL_VER=$2
PKG_DIR=$3
NETBEUI_DIR=$PKG_DIR/source/netbeui
LLC_DIR=$PKG_DIR/source/8022llc
CORE_DIR=$PKG_DIR/source/core
SCRIPT_DIR=$PKG_DIR/scripts
INCLUDE_DIR=$PKG_DIR/source/include

FILES_UPDATED=""
UPDATED=""
LAST_ERROR=""


inform_errors()
{
	echo ""
	echo "NetBEUI installation finished with errors: $1"
	echo ""
}

inform_update()
{
	echo "$1 updated"
}

inform_not_found()
{
	echo "Error: $1 is not found below the kernel tree!"
}

inform_already_updated()
{
	echo "$1 is already updated by NetBEUI"
}

check_if_updated()
{
	NOT_FOUND=""
	UPDATED=""
	if [ "$2" != "0" ]
	then
		identity="# Updated by NetBEUI on "
	else
		identity="Updated by NetBEUI on "
	fi
	identity=`sed -n -e "/$identity/=" $1 2>/dev/null`
	if [ $? != 0 ]
	then 
		inform_not_found $1
		LAST_ERROR="SOME FILES ARE MISSING!"
		NOT_FOUND="YES"
		return
	fi
	if [ "$identity" != "" ] 	
	then
		inform_already_updated $1
		UPDATED="YES"
	else
		FILES_UPDATED="YES"
	fi
}

copy_files()
{
	if [ ! -r $KERNEL_TREE/net/netbeui ]; 
	then
		mkdir $KERNEL_TREE/net/netbeui
	fi
	if [ ! -r $KERNEL_TREE/net/8022llc ]; 
	then
		mkdir $KERNEL_TREE/net/8022llc
	fi
	echo Copying NetBEUI files ...
	cp $NETBEUI_DIR/* $KERNEL_TREE/net/netbeui
	echo Copying LLC files ...
	cp $LLC_DIR/* $KERNEL_TREE/net/8022llc
	cp $CORE_DIR/* $KERNEL_TREE/net/core
	echo Copying include files ...
	cp $INCLUDE_DIR/linux/* $KERNEL_TREE/include/linux
	cp $INCLUDE_DIR/net/* $KERNEL_TREE/include/net
	cp $SCRIPT_DIR/netb /usr/bin 
	cp $SCRIPT_DIR/nbview /usr/bin 
}

install_net_makefile()
{
	ORG_FILE=$KERNEL_TREE/net/Makefile
	check_if_updated $ORG_FILE 1
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi

awk '
BEGIN 	{
	printf "# Updated by NetBEUI on "
	system("date")
	dirs_added= 0
	}
	{
	if (match($0, "^ALL_SUB_DIRS :=")) 
		sub(":=", ":= 8022llc netbeui", $0);
	else if (match($0, "^ifeq") && (dirs_added==0))
		{
		dirs_added= 1
		print "ifeq ($(CONFIG_NETBEUI), m)"
		print "MOD_SUB_DIRS+= 8022llc netbeui"
		print "endif\n"
		}
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE
	
	inform_update $ORG_FILE

}

install_net_configin()
{
	ORG_FILE=$KERNEL_TREE/net/Config.in
	check_if_updated $ORG_FILE 1
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi
	
awk '
BEGIN 	{
	printf "# Updated by NetBEUI on "
	system("date")
	tirstate_added= 0
	}
	{
	if (match($0, "tristate") && (tristate_added==0)) 
		{
	       	print "tristate \"NetBEUI Protocol\" CONFIG_NETBEUI"
		print "if [ \"$CONFIG_NETBEUI\" = \"y\" ]; then"
		print "  CONFIG_NETBEUI=\"m\""
		print "  dialog --msgbox \"NetBEUI MUST be configured just as a module\" 6 50"
		print "fi"
		tristate_added= 1
		}
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE

	inform_update $ORG_FILE
}

install_include_procfs()
{
	ORG_FILE=$KERNEL_TREE/include/linux/proc_fs.h
	check_if_updated $ORG_FILE 0
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi
	
awk '
BEGIN 	{
	printf "/* Updated by NetBEUI on "
	system("date")
	print " */"
	}
	{
	if (match($0, "^enum root_directory_inos"))
		{
		do
			{
			print $0
			getline
			}
		while (match($0, "^};") == 0)
		print "	,PROC_NETBEUI"
		print "	,PROC_NBLINKS"
		print "	,PROC_NBNAMES"
		print "	,PROC_NBSESSIONS"
		}
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE

	inform_update $ORG_FILE
}

install_include_socket()
{
	ORG_FILE=$KERNEL_TREE/include/linux/socket.h
	check_if_updated $ORG_FILE 0
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi
	
awk '
BEGIN 	{
	printf "/* Updated by NetBEUI on "
	system("date")
	print " */"
	}
	{
	if (match($0, "#define AF_MAX"))
		{
		printf "#define AF_NETBEUI	%u\n", $3
		printf "#define AF_MAX 		%u\n", $3+1
		getline
		}
	else if (match($0, "#define PF_MAX"))
		printf "#define PF_NETBEUI	AF_NETBEUI\n"
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE

	inform_update $ORG_FILE
}

install_core_makefile()
{
	ORG_FILE=$KERNEL_TREE/net/core/Makefile
	check_if_updated $ORG_FILE 1
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi
	
awk '
BEGIN 	{
	printf "# Updated by NetBEUI on "
	system("date")
	dirs_added= 0
	}
	{
	if (match($0, "dev.o")) 
		sub("+=", "+= ext8022.o", $0);
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE

	inform_update $ORG_FILE
}

install_net_netsyms()
{
	ORG_FILE=$KERNEL_TREE/net/netsyms.c
	check_if_updated $ORG_FILE 0 
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi


awk '
BEGIN 	{
	printf "/* Updated by NetBEUI on "
	system("date")
	print " */"
	}
	{
	if (match($0, "struct symbol_table net_syms"))
		{
		print "extern void P8022_register_sap(unsigned char sap,"
		print "   int (* rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));"
		print "extern void P8022_unregister_sap(unsigned char sap);"
		print ""
		}
	else if (match($0, "sock_register"))
		{
		print "	X(P8022_register_sap),"
		print "	X(P8022_unregister_sap),"
		print "	X(skb_copy),"
		}
	else if (match($0, "tr_setup"))
		{
		print "	X(tr_source_route),"
		}
	else if (match($0, "dev_mc_add"))
		{
		print "	X(dev_mc_delete),"
		}
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE

	inform_update $ORG_FILE
}

install_net_p8022()
{
	ORG_FILE=$KERNEL_TREE/net/802/p8022.c
	check_if_updated $ORG_FILE 0 
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi
	
awk '
BEGIN 	{
	printf "/* Updated by NetBEUI on "
	system("date")
	print " */"
	}
	{
	if (match($0, "dev_add_pack"))
		{
		print "	/* dev_add_pack(&p8022_packet_type); */" 
		getline
		}
	else if (match($0, "p8022_list = proto;"))
		{
		print $0
		print "		P8022_register_sap(type, p8022_rcv);"
		getline
		}
	else if (match($0, "kfree_s") && match($0, "struct datalink_proto"))
		{
		print $0
		print "			P8022_unregister_sap(type);"
		getline
		}
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE

	inform_update $ORG_FILE
}

install_net_p8022tr()
{
	ORG_FILE=$KERNEL_TREE/net/802/p8022tr.c
	check_if_updated $ORG_FILE 0
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi
	
awk '
BEGIN 	{
	printf "/* Updated by NetBEUI on "
	system("date")
	print " */"
	}
	{
	if (match($0, "dev_add_pack"))
		{
		print "	/* dev_add_pack(&p8022tr_packet_type); */" 
		getline
		}
	else if (match($0, "p8022tr_list = proto;"))
		{
		print $0
		print "		P8022_register_sap(type, p8022tr_rcv);"
		getline
		}
	else if (match($0, "kfree_s") && match($0, "struct datalink_proto"))
		{
		print $0
		print "			P8022_unregister_sap(type);"
		getline
		}
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE

	inform_update $ORG_FILE
}

install_net_802_tr()
{
	ORG_FILE=$KERNEL_TREE/net/802/tr.c
	check_if_updated $ORG_FILE 0 
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi
	
awk '
BEGIN 	{
	printf "/* Updated by NetBEUI on "
	system("date")
	print " */"
	}
	{
	if (match($0, "static void tr_source_route\\(struct trh_hdr \\*trh,struct device \\*dev\\);"))
		{
		print "void tr_source_route(struct trh_hdr *trh,struct device *dev);" 
		getline
		}
	else if (match($0, "static void tr_source_route\\(struct trh_hdr \\*trh,struct device \\*dev\\) {"))
		{
		print "void tr_source_route(struct trh_hdr *trh,struct device *dev) {" 
		getline
		}
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE 

	inform_update $ORG_FILE
}

install_net_trdevice()
{
	ORG_FILE=$KERNEL_TREE/include/linux/trdevice.h
	check_if_updated $ORG_FILE 0 
	if [ "$UPDATED" != "" -o "$NOT_FOUND" != "" ]
	then
		return
	fi
	
awk '
BEGIN 	{
	printf "/* Updated by NetBEUI on "
	system("date")
	print " */"
	}
	{
	if (match($0, "tr_header"))
		{
		print "extern void tr_source_route(struct trh_hdr *trh,struct device *dev);"
		}
	print $0
	}' $ORG_FILE > $TMP_FILE 

	mv $TMP_FILE $ORG_FILE

	inform_update $ORG_FILE
}


orgdir=`pwd`
cd $KERNEL_TREE

if [ "$KERNEL_VER" = "" ]
then
	KERNEL_VER=UNKNOWN
fi

echo Modifying the files in the kernel tree
echo The kernel version is $KERNEL_VER

install_net_makefile
install_net_configin
install_include_procfs
install_include_socket
install_core_makefile
install_net_netsyms
install_net_p8022
install_net_p8022tr
install_net_802_tr
install_net_trdevice

if [ "$LAST_ERROR" != "" ]
then
	inform_errors "$LAST_ERROR"
fi

copy_files
echo ""
cd $orgdir
