#!/usr/bin/perl
#
# Xshutdown script- this program installs an X-shutdown button in xdm.
#    Copyright (C) 1998  Mike Wyer
#    Version 1.0
#
#    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# 
# Options: xshut -r -s -h -v -u
#          -r reboot
#          -s stop/halt
#          -h help
#          -v verbose
#          -u uninstall
# 
# No options: returns the current status.
#
# Bugs: verbose option not fully implemented yet.


# status(Quiet)
# Checks for existence of Xshutdown and Xshutup.
# If installed, checks whether Halt and/or Reboot buttons exist.
# If Quiet, no output is produced.

sub status {
    local($StatusString);
    $Quiet = $_[0];
    if (-f $DOWN) {
	if ($Verbose) {$StatusString .= "Found $DOWN\n";}
	if ( open (DOWN,$DOWN) ){
	    while ( <DOWN> ) {
       		if ( /shut.*\-h/ ) {$StatusString .= "Found Stop/Halt button\n" if $Verbose;$HaltFound=1;}
		elsif ( /shut.*\-r/ ) {$StatusString .= "Found Reboot button\n" if $Verbose;$RebootFound=1;}
	    }
	    close(DOWN);
	    $DownFound = ( $HaltFound || $RebootFound )
	}
	elsif ($Verbose) {$StatusString .= "Couldn't read $DOWN\n" if $Verbose;}
    }
    elsif ($Verbose) {$StatusString .= "Could not find $DOWN\n";}

    if ( -f $UP) {
	if ($Verbose) {$StatusString .= "Found $UP\n";}
	$UpFound=1;
    }
    elsif ($Verbose) {$StatusString .= "Could not find $UP\n";}
    
    open (SETUP, $SETUP) || ($StatusString .= "Could not open $SETUP\n");
    while ( <SETUP> ){
	if ( /Xshutdown &/ ) {$StatusString .= "Found Xshutdown call\n" if $Verbose;$SetupFound = 1;}
    }
    close SETUP;
    
    open (CONSOLE,$CONSOLE) || ($StatusString .= "Could not open $CONSOLE\n");
    while ( <CONSOLE> ){
	if ( /Xshutup/ ) {$StatusString .= "Found Xshutup call\n" if $Verbose;$ConsoleFound =1;}
    }
    close CONSOLE;

    unless ($Quiet){
	print $StatusString;
	if ( $DownFound && $UpFound && $SetupFound && $ConsoleFound ) { 
	    if ($HaltFound && $RebootFound) { print "Shutdown and Reboot\n";}
	    elsif ($HaltFound) { print "Shutdown\n";}
	    else { print "Reboot\n";}
	}
	else {
	    print "Xshutdown not installed\n";
	}
    }
}

# uninstall()
# Removes installed components.
sub uninstall {
    &status(1);
    unlink($DOWN) if $DownFound;
    unlink($UP) if $UpFound;
    if ($SetupFound) {
	open (IN,$SETUP) || die "Could not open $SETUP\n";
	open (OUT,">/tmp/xsh$$setup") || die "Could not write temporary file\n";
	while (<IN>){
	    print OUT unless /Xshut/;
	}
	close IN;
	close OUT;
	unlink($SETUP);
	rename "/tmp/xsh$$setup",$SETUP;
	chmod (0744,$SETUP);
    }
    if ($ConsoleFound) {
	open (IN,$CONSOLE) || die "Could not open /etc/X11/xdm/GiveConsole\n";
	open (OUT,">/tmp/xsh$$console") || die "Could not write temporary file\n";
	while (<IN>){
	    print OUT unless /Xshut/;
	}
	close IN;
	close OUT;
	unlink($CONSOLE);
	rename "/tmp/xsh$$console",$CONSOLE;
	chmod (0744,$CONSOLE);
    }
}

# addButton( 0-Halt / 1-Reboot )
# Adds specified button to the xdm system.
sub addButton {
    $Header = "\#\!/bin/sh\n\#the next line restarts using wish. Don't remove this: \\\nexec wish \"\$0\" \"\$\@\"\n";
    local ($Halt,$Reboot);
    @_[0] ? $Reboot = 1 : $Halt = 1;
    if (-f $DOWN){ $Header = 0;}
    open ( OUT,">>$DOWN") || die "Could not create $DOWN\n";
    print OUT $Header;
    if ($Reboot) { $B = "b";$Flag = "r";$Text = "Reboot";$Side="left"}
    else {$B = "c";$Flag = "h";$Text = "Shutdown";$Side="right"}
    print OUT "button .$B -width 10 -text \"$Text\" -command \"exec /sbin/shutdown -t5 -$Flag now\"\npack .$B -side $Side\n";
    close OUT;
    unless (-f $UP) {
	open (OUT,">$UP") || die "Could not create $UP\n";
	print OUT $Header;
	print OUT "send Xshutdown exit\nexit\n";
	close OUT;
    }
    # Check calls:
    open ( IN , $SETUP);
    $CallFound=0;
    while ( <IN> ) {
	if ( /Xshutdown &/ ) { $CallFound=1;}
    }
    close IN;
    unless ($CallFound) {
	open (OUT,">>$SETUP");
	print OUT "$DOWN \&\n";
	close OUT;
    }
    open (IN, $CONSOLE);
    open (OUT,">/tmp/xsh$$console");
    $CallFound=0;
    $ChownFound=0;
    while ( <IN> ){
	$ChownFound=1 if /chown/ ;
	$CallFound=1 if /Xshutup/;
	print OUT "$UP\n" if  ( $ChownFound && !$CallFound);
	print OUT;
    }
    close IN;
    close OUT;
    rename $CONSOLE,"${CONSOLE}.bak";
    rename "/tmp/xsh$$console",$CONSOLE;
    chmod (0744,$UP,$DOWN,$SETUP,$CONSOLE);
}


# Main program:
$PATH = "/etc/X11/xdm/";
$DOWN = "${PATH}Xshutdown";
$UP = "${PATH}Xshutup";
$SETUP = "${PATH}Xsetup_0";
$CONSOLE = "${PATH}GiveConsole";

if ( @ARGV == 0 ) {$Status = 1;}
foreach $i (@ARGV) {                  #Options: r s h f v u
    if ($i eq "-r") { $Reboot = 1;}
    elsif ($i eq "-s") { $Halt = 1;}
    elsif ($i eq "-h") { $Help = 1;$Reboot = $Halt = 0}
    elsif ($i eq "-v") { $Verbose = 1; if (@ARGV == 1) { $Status=1;} }
    elsif ($i eq "-u") { $Uninstall = 1;}
    else {
	$Help = 1;$Reboot=$Halt=0;
	print STDERR "$i : Invalid or Unrecognised Option\n";
    }
}
if ( $Status ) { &status(0);}
elsif ( $Help ) { print "xshut -r (reboot) -s (stop/halt) -h (help) -u (uninstall)] -v (verbose)\n";}
else {
    &status(1);
    if ( $Uninstall ){ print "Uninstalling\n";&uninstall;}
    else {if ( $Reboot && (!$RebootFound ) ){ &addButton(1);}
	  if ( $Halt && (!$HaltFound ) ){ &addButton(0);}
	  &status(0);
      }
}
