#!/usr/bin/perl
#  Copyright (C)1996 Austin Donnelly <and1000@cam.ac.uk>.
#  This is free software; you may modify and distribute it under the
#  terms of the GNU General Public Licence as published by the Free
#  Software Foundation, version 2 or at your option any later version.
#  There is NO WARRANTY.

die "$0: must be run as root!\n" if $< != 0;

$CONVPROG="/usr/bin/X11/fvwmrc_convert";

print "Checking which users have untranslated ~/.fvwmrc files...\n";

# Read password file & build list of affected users
@todo=();
setpwent();
($name,$passwd,$uid,$gid,
 $quota,$comment,$gcos,$dir,$shell) = getpwent();
while(defined($uid))
{
	push(@todo, [$uid,$gid,$name,$dir])
		if (-f "$dir/.fvwmrc" && ! -f "$dir/.fvwm2rc");
	($name,$passwd,$uid,$gid,
	 $quota,$comment,$gcos,$dir,$shell) = getpwent();
}
endpwent();

if ($#todo == -1)
{
	print "No user has an untranslated ~/.fvwmrc - no conversion necessary.\n";
	exit 0;
}

print ($#todo + 1);
print " users need conversion, shall I convert them all now?\n";
if ($#todo < 10)
{
	printf("The user%s: ", ($#todo == 1)? " is" : "s are");
	foreach $i (@todo) { print $i->[2], " " }
	print "\n";
}
$resp="<invalid>";
while(! (($resp eq "") || ($resp =~ /^y/i) || ($resp =~ /^n/i)))
{
	print "Type Y to convert, N to skip [Y]: ";
	chomp ($resp=<STDIN>);
}

if ($resp =~ /^n/i)
{
	print "Ok, not converting\n";
	exit 0;
}

print <<EOT ;

Warnings during the conversion process will be written to
/home/<username>/.fvwm2rc.conversion
for each user.

EOT

# Do all the files
$size= $#todo < 9 ? 1 : $#todo < 99 ? 2 : $#todo < 999 ? 3 :
	$#todo < 9999 ? 4 : 5;
$unum=1;
printf(STDERR "Processing user: %${size}d/%${size}d", 0, $#todo+1);
foreach $line (@todo)
{
	printf(STDERR "\b"x(2*$size+1)); # 7 backspaces
	printf(STDERR "%${size}d/%${size}d", $unum, $#todo+1);
	# XXX: assumes all directories in /home have corresponding uids.
	translate($line);
	$unum++;
}
print STDERR "\n";

print "All done!\n";
exit 0;

###########################

# run $CONVPROG
sub translate
{
	local ($line) = @_;
	local ($uid, $gid, $name, $dir);

	($uid,$gid,$name,$dir)=@$line;

	# fork: child drops privs & does work, while parent waits for child
	die "fork() failed: $!\n" unless defined($pid=fork());
	if ($pid==0) # child
	{
		$( = $gid;  # real gid
		$) = "$gid $gid";  # eff gid & clear groups list
		$< = $> = $uid;  # real, eff uid
		# ok, now plain mortal, so run conversion
		open(STDOUT, ">$dir/.fvwm2rc.conversion") ||
			die "\ncannot open $dir/.fvwm2rc.conversion for write: $!\n";
		my ($dev,$ino,$mode);
		($dev,$ino,$mode) = stat "$dir/.fvwmrc" or 
			die "Can't stat $dir/.fvwmrc: $!\n";
		chmod ($mode & 0777), "$dir/.fvwm2rc.conversion"; # Don't worry if can't
		open(SAVEERR, ">&STDERR") || die "Can't save stderr";
		open(STDERR, ">&STDOUT") || die "Can't dup stdout";
		exec $CONVPROG, "$dir/.fvwmrc", "$dir/.fvwm2rc";
		open(STDERR, ">&SAVEERR");
		die "\nexec() of $CONVPROG failed: $!\n";
	} else {
		# parent
		waitpid($pid, 0);
		$ret=$?>>8;
		warn "\nChild returned with non-zero exit status($ret)\n" if $ret;
		printf(STDERR "Processing user: %${size}d/%${size}d", $unum, $#todo+1)
			if $ret;
	}
}
