#! /usr/bin/env perl
# kcd-inst
# Copyright (c) 2000, 2001, 2002, 2003 Kriang Lerdsuwanakij
# email:	lerdsuwa@users.sourceforge.net
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.

use English;

$prog_name = 'kcd-inst';
$prog_ver = '7.15.0';	# Single quote make it not a list variable

$sysconfdir = '/etc/opt/local';	# Single quote make it not a list variable
$sysconfdir2 = '/opt/local/etc';	# Single quote make it not a list variable

#
# Subroutines
#

sub version_and_exit {
	print "$prog_name $prog_ver\n";
	exit 0;
}

sub help_and_exit {
	print "$prog_name $prog_ver - Install kcd command in user shell startup files\n";
	print "Usage: $prog_name [-h|--help|-v|--version]\n\n";
	exit 0;
}

#
# modify_startup_real - Do the actual startup file modification
# parameters:
#	file		File to modify
#	mode		"sh" or "csh"
#	run_file	File to run during startup
#

sub append_startup {
	my @parm = @_;
	my ($file, $mode, $run_file);

	die "$prog_name: invalid parameter in modify_startup_real\n"
		if scalar(@parm) < 3;

	$file = shift @parm;
	$mode = shift @parm;
	$run_file = shift @parm;

	open OUTFILE, ">>$file"
		or die "$prog_name: cannot open $file for append\n";

	print "$prog_name: updating $file\n";

	print OUTFILE "\n# For kcd\n";
	if ($mode eq "sh") {
		print OUTFILE "KCD_INIT=\"$run_file\"\n";
		print OUTFILE "if [ -e \"\$KCD_INIT\" ]; then\n";
		print OUTFILE "\t. \"\$KCD_INIT\"\n";
		print OUTFILE "fi\n";
	}
	else {
		print OUTFILE "set KCD_INIT=\"$run_file\"\n";
		print OUTFILE "test -e \"\$KCD_INIT\"\n";
		print OUTFILE "if (\$status == 0) then\n";
		print OUTFILE "\tsource \"\$KCD_INIT\"\n";
		print OUTFILE "endif\n";
	}
	close OUTFILE;
}

sub edit_startup {
	my @parm = @_;
	my ($file, $mode, $run_file);

	die "$prog_name: invalid parameter in modify_startup_real\n"
		if scalar(@parm) < 3;

	$file = shift @parm;
	$mode = shift @parm;
	$run_file = shift @parm;

	my $ret = system "mv $file $file~";
	$ret = $ret/256;

	die "$prog_name: cannot backup $file as $file~, file ignored\n" if $ret;

	open INFILE, "$file~"
		or die "$prog_name: cannot open $file~ for reading\n";
	open OUTFILE, ">$file"
		or die "$prog_name: cannot open $file for writing\n";

	print "$prog_name: updating $file\n";

	while (<INFILE>) {
		if (/For [Kk][Cc][Dd]/) {
			print OUTFILE $_;
			$_ = <INFILE>;
			$_ =~ /KCD_INIT=\"(.*)\"\n/;
			print OUTFILE "$`KCD_INIT=\"$run_file\"\n$'";
		}
		else {
			print OUTFILE $_;
		}
	}
	close INFILE;
	close OUTFILE;
}

sub modify_startup_real {
	my @parm = @_;
	my ($file, $mode, $run_file);

	die "$prog_name: invalid parameter in modify_startup_real\n"
		if scalar(@parm) < 3;

	$file = shift @parm;
	$mode = shift @parm;
	$run_file = shift @parm;

	die "$prog_name: invalid mode in modify_startup\n"
		if $mode ne "sh" && $mode ne "csh";

	if (! -e $file) {
		open OUTFILE, ">$file"
			or die "$prog_name: cannot create $file\n";
		print OUTFILE "# Created by kcd\n";
		close OUTFILE;
	}
	elsif (! -f $file) {
		die "$prog_name: $file is not a file, ignored\n";
	}

	open INFILE, "$file"
		or die "$prog_name: cannot open $file for reading\n";

	while (<INFILE>) {
		if (/For [Kk][Cc][Dd]/) {
			$_ = <INFILE>;
			if (/KCD_INIT=\"(.*)\"\n/) {
				if ($1 eq $run_file) {
					die "$prog_name: $file already contains initialization script, ignored\n";
				}
				else {
					close INFILE;
					edit_startup $file, $mode, $run_file;
					return;
				}
			}
			else {
				die "$prog_name: \"For kcd\" marker found, $file ignored\n";
			}
		}
	}
	close INFILE;
	append_startup $file, $mode, $run_file;
}

#
# modify_startup - Do the actual startup file modification
# parameters:
#	file		File to modify
#	mode		"sh" or "csh"
#	run_file	File to run during startup
#

sub modify_startup {
	eval {
		modify_startup_real @_;
	};
	if ($@) {		# Print error message generated by die
				# if any
		print $@;
	}
}

#
# Main
#

				# Check command line
if (@ARGV > 1) {
	help_and_exit();
}
elsif (@ARGV == 1) {
	if ($ARGV[0] eq "-h" || $ARGV[0] eq "--help") {
		help_and_exit();
	}
	elsif ($ARGV[0] eq "-v" || $ARGV[0] eq "--version") {
		version_and_exit();
	}
	else {
		# Invalid option
		help_and_exit();
	}
}

				# Locate the kcd initialization scripts
if (-e "$sysconfdir2") {
	if (-e "$sysconfdir2/profile.d") {
		$run_file_sh = "$sysconfdir2/profile.d/kcd.sh";
		$run_file_csh = "$sysconfdir2/profile.d/kcd.csh";
	}
	else {
		$run_file_sh = "$sysconfdir2/kcd.sh.init";
		$run_file_csh = "$sysconfdir2/kcd.csh.init";
	}
}
else {
	if (-e "$sysconfdir/profile.d") {
		$run_file_sh = "$sysconfdir/profile.d/kcd.sh";
		$run_file_csh = "$sysconfdir/profile.d/kcd.csh";
	}
	else {
		$run_file_sh = "$sysconfdir/kcd.sh.init";
		$run_file_csh = "$sysconfdir/kcd.csh.init";
	}
}

				# Find user information
$found = 0;
while (($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwent) {
#	print $uid, " ", $name, " ", $UID, " ", $ENV{USER}, "\n";
	if ($uid == $UID && $name eq $ENV{USER}) {
		$found = 1;
		last;
	}
}
endpwent;

if (!$found  || !$dir || !$shell) {
	$dir = $ENV{HOME};
	$shell = $ENV{SHELL};
}

				# Modify startup files

# For bash, zsh
modify_startup("$dir/.bashrc", "sh", $run_file_sh)
	if -e "$dir/.bashrc" || $shell =~ /\/bash$/;
modify_startup("$dir/.zshrc", "sh", $run_file_sh)
	if -e "$dir/.zshrc" || $shell =~ /\/zsh$/;

# For ksh
modify_startup("$dir/.kshrc", "sh", $run_file_sh)
	if -e "$dir/.kshrc" || ($shell =~ /\/ksh$/
				|| $shell =~ /\/dtksh$/ || $shell =~ /\/pdksh$/);

# For ash (*rc file not exist for ash)
modify_startup("$dir/.profile", "sh", $run_file_sh)
	if $shell =~ /\/ash$/;

# For tcsh
modify_startup("$dir/.tcshrc", "csh", $run_file_csh)
	if -e "$dir/.tcshrc" || ($shell =~/\/tcsh$/ && ! -e "$dir/.cshrc");
modify_startup("$dir/.cshrc", "csh", $run_file_csh)
	if -e "$dir/.cshrc";

