#!/usr/bin/perl -w
##
## Copyright (c) 2001, 2002, Amnon BARAK (amnon@MOSIX.org).
## All rights reserved.
## This software is subject to the MOSIX SOFTWARE LICENSE AGREEMENT.
##
## THIS SOFTWARE IS PROVIDED IN ITS "AS IS" CONDITION, WITH NO WARRANTY
## WHATSOEVER. NO LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
## FROM THE USE OF THIS SOFTWARE WILL BE ACCEPTED.
##
##
## Author(s): A.Spanier, Shlomo Matichin 
##

# This script compiles and installs the user level applications.

# Default arguments currently compatible with all Linux distributions.

use Getopt::Long;
use FindBin;
use lib "$FindBin::Bin";
use common;

$temp_dir	= "/tmp";
$CC		= '';

GetOptions( 	"temp_dir=s" ,	 	\$temp_dir ,
		"cc=s" ,		\$CC ,
		"help" ,		\$usage ,
		"silent",               \$silent ,
		"uninstall" ,		\$uninstall );

$temp_dir =~ s/\/$// ;
$CC and $CC="CC=$CC";

usage() if defined $usage ;

-e "$source_dir/user.tar" or dead "MOSIX Distribution is not intact: Unable to find $source_dir/user.tar";

-e "$source_dir/patches.$kernel_version" or
	dead "MOSIX Distribution is not intact: Unable to find $source_dir/patches.$kernel_version";

-w "/bin" and -w "/lib" and -w "/sbin" and -w "/usr/bin" or 
	dead "You do not have write permissions on: /bin, /lib, /sbin and /usr/bin";

-w $temp_dir or dead "You do not have write permission on $temp_dir. Use the --temp_dir parameter";

-w "/etc" or dead "You do not have write permission on /etc";

uninstall() and exit 1 if defined $uninstall ;
if( defined $silent) {$SILENCE="-s";} else {$SILENCE="";}
install();
exit 1;
    
sub install
{
	-e "/etc/.mosix_user_level_programs" and
		dead "Please uninstall MOSIX before reinstalling";
	-d "$temp_dir/mosix_user" and system( "rm -fr $temp_dir/mosix_user" ) and
		dead "Unable to delete old $temp_dir/mosix_user directory. Remove it manually and try again" ;
	mkdir( "$temp_dir/mosix_user" , 0777 ) or 
		dead "Unable to create directory $temp_dir/mosix_user. Aborting";
	chdir( "$temp_dir/mosix_user" ) or
		dead "Unable to change directory into $temp_dir/mosix_user" ;
	system( "tar -x -f $source_dir/user.tar --directory $temp_dir/mosix_user" ) and
		dead "tar reproted problems while untarring $source_dir/user.tar into $temp_dir/mosix_user";
	mkdir( "headers" , 0777 ) or
		dead "Unable to create directory 'headers'\n" ;

	patch_distribution("$source_dir/user.tar","$temp_dir/mosix_user") and dead "\nFailed to patch $distribution files\n";	
	mosix_new_files() and dead "Unable to copy new file\n";

	chdir( "$temp_dir/mosix_user" ) or
                dead "Unable to change directory into $temp_dir/mosix_user" ;

	system( "echo 'CFLAGS += -I$temp_dir/mosix_user/headers/include' >> Rules.make" ) and
		dead "Unable to apply to Rules.make";
	print "\nMaking the user-level MOSIX programs...\n";
	system( "make $CC $SILENCE") and
		dead "Make failed.  The most common reason is failing to link the kernel sources to /usr/include."; 
	system( "make $CC $SILENCE install") and
		dead "Make install failed.  Please run it manually from $temp_dir/mosix_user. ";

	#create uninstall information:
	mkdir( "$temp_dir/mosix_user/tmp" , 0777 ) or 
		dead "Unable to mkdir $temp_dir/mosix_user/tmp";
	mkdir( "$temp_dir/mosix_user/tmp/usr" , 0777 ) or
		dead "Unable to mkdir $temp_dir/mosix_user/tmp/usr";
	mkdir( "$temp_dir/mosix_user/tmp/usr/include" , 0777 ) or
		dead "Unable to mkdir $temp_dir/mosix_user/tmp/usr/include";

	mkdir( "$temp_dir/mosix_user/tmp/usr/include/mos" , 0777 ) or
		dead "Unable to mkdir $temp_dir/mosix_user/tmp/usr/include/mos";
	chdir( "$temp_dir/mosix_user/tmp/usr" ) or
		dead "Unable to chdir into $temp_dir/mosix_user/tmp/usr";
	system( "cp -f $temp_dir/mosix_user/headers/include/mos/* ./include/mos/" ) and
		dead "Unable to copy mosix include files into $temp_dir/mosix_user/tmp/usr";

	chdir( "$temp_dir/mosix_user" ) or
		dead "Unable to chdir into $temp_dir/mosix_user";
	system( "make $CC -s install PREFIX=$temp_dir/mosix_user/tmp/usr ".
		"ROOT=$temp_dir/mosix_user/tmp > /dev/null" ) and
		dead "Unable to install user level program in ".
			"$temp_dir/mosix_user/tmp";
	chdir( "$temp_dir/mosix_user/tmp" ) or
		dead "Unable to chdir into $temp_dir/mosix_user";
	system( "rm -fr usr/include/mos" ) and
		dead "Unable to delete temporary header files from $temp_dir/mosix_user/tmp/usr/include/mos";
	system( "find . -type f > /etc/.mosix_user_level_programs" ) and
		dead "Unable to build uninstall file list in /etc/.mosix_user_level_programs";
	system( "find . -type l >> /etc/.mosix_user_level_programs" ) and
		dead "Unable to build uninstall symbolic links list in /etc/.mosix_user_level_programs";
	chdir("$temp_dir");
	system("rm -rf mosix_user");
	exit;
}

sub usage {
	print "Usage : install_user [OPTION]\n";
	print "--temp_dir=     a temporary files directory (default: /tmp)\n";
	print "--uninstall     uninstall\n";
	print "--help          this message\n";		
	exit ;
}

sub uninstall {
	unless( -e "/sbin/setpe" or -e "/bin/mosrun" ) {
		print "\nThe MOSIX user-level programs do not seem to have been previously installed!\n";
		system( "rm -f /etc/.mosix_user_level_programs" );
		exit;
	}
	-r "/etc/.mosix_user_level_programs" or
		dead "Unable to read uninstall list from /etc/.mosix_user_level_programs";
	chomp( @files = `cat /etc/.mosix_user_level_programs` );
	foreach $file(@files) {
		system( "rm -f /$file" ) and
			print "\nUnable to delete /$file\n";
	}
	system( "rm -f /etc/.mosix_user_level_programs" ) and
		dead "Unable to erase /etc/.mosix_user_level_programs";
	exit;
}

sub mosix_new_files {
	$openfile = 1;
	
	chdir( "$temp_dir/mosix_user/headers" ) or
                dead "Unable to chdir into $temp_dir/mosix_user";

 	system( "cp -f $source_dir/patches.$kernel_version mosix_patches" ) and
                dead "Unable to copy patches to local directory";

	open(SOURCE, mosix_patches) or dead "Could not open mosix_patch !\n";

	mkdir( "$temp_dir/mosix_user/headers/include" , 0777 ) or
                dead "Unable to create directory $temp_dir/mosix_user/headers/include. Aborting";
	
	mkdir( "$temp_dir/mosix_user/headers/include/mos" , 0777 ) or
                dead "Unable to create directory $temp_dir/mosix_user/headers/include/mos. Aborting";

	mkdir( "$temp_dir/mosix_user/headers/include/linux" , 0777 ) or
                dead "Unable to create directory $temp_dir/mosix_user/headers/include/linux. Aborting";
	
	while (<SOURCE>) {
        	if(($_ =~ /^\*\*\*.*\.h.*Jan\ \ 1\ 00\:00\:00\ 1970/))  { 
	                m/\*\*\*\ (\S+)\s/;
        	        
			@spl = split(/\./,$1);
                       	$file =join('.' ,$spl[3],$spl[4]);
 
        		$openfile = 0;
	        	open(PATCHFILE, ">./$file") or dead "Could not open ./$file: $!\n";
			next;	
		} 

		if (($openfile == 0) && ($_ =~ /^\+/)) {
			/^\+\ (.*)/; 
			 print PATCHFILE "$1\n"; 
			if ($_ =~ /^\*\*\*/) {
				close(PATCHFILE); 
				$openfile = 1;
			 }
		}
	}
	
	close (SOURCE);
	return(0);
}
