
eval 'exec perl -S $0 "$@"'
	if 0;

# fixpath - add/remove paths from startup files.
# $Id: fixpath,v 1.2 1999/01/14 20:11:16 drk Exp $
#
&main;
exit 0;

sub main
{
	@files = ();
	$shell = $ENV{'SHELL'};
	$home = $ENV{'HOME'};
	@info = getpwuid($>);
	if ($#info == -1) {
		die "$0: can't find passwd entry for UID $>\n";
	}
	$home = $info[7] unless ($home ne "");
	$shell = $info[8] unless ($shell ne "");

	# Make sure we are doing the right thing.
	open(TTY, "/dev/tty") || die "$0: No tty";
	select(STDOUT);
	$| = 1;
	$ok = 0;
	while (!$ok) {
		do {
			print "Your shell seems to be $shell, is that correct? ";
			$ans = <TTY>;
			print "Please use yes/no for your answer.\n"
			    unless $ans =~ /^[yYnN]/;
		} while ($ans !~ /^[yYnN]/);
		if ($ans =~ /^[yY]/) {
			$ok = 1;
		} else {
			print "What is your shell? ";
			$shell = <TTY>;
			chop($shell);
		}
	}

	# XXX - don't handle zsh - couldn't find a man page.
	$shell =~ s|.*/||;
	$ok = 0;
	foreach $s ('sh', 'ksh', 'bash', 'csh', 'tcsh') {
		$ok = 1 if $s eq $shell;
	}
	if (!$ok) {
		die "$0: I don't know what to do for your '$shell' shell.\n";
	}

	# Depending on which shell it is, figure out the file.
	if ($shell eq "sh") {
		push(files, "$home/.profile");
		$default = "$home/.profile";
	}

	if ($shell eq "csh") {
		foreach $f ('.login', '.cshrc') {
			if (-e "$home/$f" && &haspath("$home/$f")) {
				push(files, "$home/$f");
			}
		}
		if ($#files == -1) {
			push(files, "$home/.login");
		}
		$default = "$home/.login";
	}

	if ($shell eq "tcsh") {
		foreach $f ('.login', '.tcshrc', '.cshrc') {
			if (-e "$home/$f" && &haspath("$home/$f")) {
				push(files, "$home/$f");
			}
		}
		if ($#files == -1) {
			push(files, "$home/.login");
		}
		$default = "$home/.login";
	}

	if ($shell eq "ksh") {
		foreach $f ('.kshrc', '.profile') {
			if (-e "$home/$f" && &haspath("$home/$f")) {
				push(files, "$home/$f");
			}
		}
		if ($#files == -1) {
			push(files, "$home/.profile");
		}
		$default = "$home/.profile";
	}

	if ($shell eq "bash") {
		foreach $f ('.bashrc', '.bash_profile', '.bash_login', '.profile') {
			if (-e "$home/$f" && &haspath("$home/$f")) {
				push(files, "$home/$f");
			}
		}
		if ($#files == -1) {
			push(files, "$home/.profile");
		}
		$default = "$home/.profile";
	}

	# OK, now we have set up the following:
	# $shell is the users shell.
	# @files is the list of files that had one or more of the PATH things.
	#warn "shell = $shell\nfiles = @files\n";

	foreach $f (@files) {
		&fixpath($f);
	}
	if (!$path) {
		&addpath("PATH", '${PATH}:/usr/nekoware/bin', $default);
	}
	if (!$manpath) {
		&addpath("MANPATH", '/usr/share/catman:/usr/share/man:/usr/catman:/usr/man:/usr/nekoware/man', $default);
	}
	if (!$X) {
		&addpath("XFILESEARCHPATH", '/usr/lib/X11/%T/%N:/usr/nekoware/lib/X11/%T/%N', $default);
	}
}

sub addpath
{
	local($which, $p, $file) = @_;

	print "Adding new variable $which to $file\n";
	if ($shell =~ /csh/) {
		system("echo setenv $which '$p' >> $file");
	} else {
		system("echo $which='$p' >> $file");
		system("echo export $which >> $file");
	}
}

sub fixpath
{
	open(F, $f) || die "$0: can't open $f\n";
	open(N, ">/tmp/new$$");
	while (<F>) {
		if (/^\s*PATH=/ || /XFILESEARCHPATH=/ ||
		    /MANPATH=/ || /set\s+path\s*=\s*\(/ ||
		    /setenv\s+PATH\s+/ || /setenv\s+MANPATH\s+/ ||
		    /setenv\s+XFILESEARCHPATH/) {
			$manpath = 1 if /MANPATH/;
			$X = 1 if /XFILESEARCHPATH/;
			$path = 1 if /^\s*PATH=/ ||
			    /set\s+path\s*=\s*\(/ || /setenv\s+PATH\s+/;
			chop;
			do {
				$new = &fixit($f, $_);
			} while ($new eq "");
			$_ = "$new\n";
		}
		print N;
	}
	close(N);
	print "\nDiff of $f vs. new:\n";
	system("diff $f /tmp/new$$");
	do {
		print "Use new file? ";
		$ans = <TTY>;
		print "Please answer y/n" unless $ans =~ /^[yYnN]/;
	} while ($ans !~ /^[yYnN]/);
	if ($ans =~ /^[yY]/) {
		system("cp $f $f.bak");
		system("cp /tmp/new$$ $f");
		print "Relogin or source $f to have changes take effect.\n";
		print "$f.bak is the previous version of your file.\n";
	}
	unlink("/tmp/new$$");
}

sub fixit
{
	local($file, $line) = @_;

	if ($line =~ /^\s*PATH=/) {
		$var = "PATH";
		$add = "/usr/nekoware/bin";
	} elsif ($line =~ /XFILESEARCHPATH=/) {
		$var = "XFILESEARCHPATH";
		$add = "/usr/nekoware/lib/X11/%T/%N"; # XXX? check this.
	} elsif ($line =~ /MANPATH=/) {
		$var = "MANPATH";
		$add = "/usr/nekoware/man";
	} elsif ($line =~ /set\s+path\s*=\s*\(/) {
		$var = "path";
		$add = "/usr/nekoware/bin";
	} elsif ($line =~ /setenv\s+PATH\s+/) {
		$var = "PATH";
		$add = "/usr/nekoware/bin";
	} elsif ($line =~ /setenv\s+MANPATH\s+/) {
		$var = "MANPATH";
		$add = "/usr/nekoware/man";
	} elsif ($line =~ /setenv\s+XFILESEARCHPATH\s+/) {
		$var = "XFILESEARCHPATH";
		$add = "/usr/nekoware/lib/X11/%T/%N"; # XXX? check this.
	}

	# This is really tacky, but I want to catch multi line paths.
	while ($line =~ m|.*\s*\\\s*$|) {
		$_ = <F>;
		$line .= $_;
	}
	$save = $line;

	do {
		#print "\nIn $file, your $var variable is:\n";
		#print "\n$line\n";
		if ($line =~ "$add") {
			$q = "\nRemove $add from \$$var in $file? ";
		} else {
			$q = "\nAdd $add to \$$var in $file? ";
		}
		print $q;
		$ans = <TTY>;
		print "Please use yes/no for your answer.\n"
		    unless $ans =~ /^[yYnN]/;
	} while ($ans !~ /^[yYnN]/);
	if ($ans !~ /^[yY]/) {
		print "OK, skipping this one.\n";
		return $save;
	}

	# Remove case.
	if ($line =~ m|$add|) {
		if ($line =~ m|:$add|) {
			$line =~ s|:$add||;
		} elsif ($line =~ m|$add:|) {
			$line =~ s|$add:||;
		} else {
			$line =~ s|$add||;
		}
		return $line;
	}

	# Add case.
	$start = $stop = "";
	@line = ();
	if ($var eq "path") {
		$line =~ /(.*set\s+path\s*=\s*\()(.*)(\))/;
		$join = " "; $start = $1; $line = $2; $stop = " $3";
	} elsif ($line =~ /setenv/) {
		$line =~ /(.*setenv\s+$var\s+)(.*)/;
		$join = ":"; $start = $1; $line = $2; $stop = "";
	} else {
		if ($line =~ /(\"\s*$)/) {
			$stop = '"';
			$line =~ s/\"\s*$//;
		}
		$line =~ /(.*$var=\"?)(.*)/;
		$join = ":"; $start = $1; $line = $2;
	}
	@line = split(/[:\s]/, $line);
	#print "<$start> <$line> <$stop>\n";
	do {
		print "\nYour $var is: @line\n";
		$n = $#line + 1;
		print "You can put $add anywhere in this path.\n";
		print "To put it first, type '1',\n";
		print "to put it last, type '\$',\n";
		print "and to put it in the middle, type 2 for second, 3 for fourth, etc.\n";
		print "Your $var currently has $n paths, 1..$n.\n";
		print "\nPut $add where? ";
		chop($ans = <TTY>);
	} while ($ans !~ /^[\$1-9]/);
	if ($ans eq '$') {
		push(line, "$add");
	} else {
		@new = ();
		$ans--;
		# XXX - check for out of bounds!
		for ($i = 0; $i < $ans; $i++) {
			push(new, shift(line));
		}
		push(new, "$add");
		push(new, @line);
		@line = @new;
	}
	$line = $start . join($join, @line) . $stop;
	return $line;
}

# Look for a path/PATH variable.  Leaves F open, but it gets reused.
sub haspath
{
	local($f) = @_;

	open(F, $f) || die "$0: can't open $f\n";
	while (<F>) {
		# sh types
		return 1 if /^\s*PATH=/ || /XFILESEARCHPATH=/ || /MANPATH=/;

		# csh types
		return 1 if /set\s+path\s*=\s*\(/ || /setenv\s+PATH\s+/ ||
		    /setenv\s+MANPATH\s+/ || /setenv\s+XFILESEARCHPATH/;
	}
	return 0;
}
