#! /usr/local/bin/perl
#
#   Remove CR's from MS-DOS files
#

$MAX = 4000000;	# max. file size
$tmp_dir = ".";
$debug = 0;
$dryrun = 0;

$verbose = 0;

sub basename {
	local($name) = @_;
	$name =~ s/^.*\///;
	$name;
}

sub dirname {
	local($name) = @_;
	$name =~ s/[^\/]+$//;
	$name;
}

$ego = &basename($0);
$base = $ego; $base =~ s/[.][^.]*$//;

if ($ARGV[0] eq "") {
	die "usage: $ego [-debug] [-verbose|-quiet] [-dryrun] files...\n";
}

$exit_status = 0;

while ($ARGV[0] =~ /^-/) {
	$_ = shift;
	if (/^-debug/) {
		$debug = 1;
		$verbose = 1;
		print STDERR "debug mode\n";
	} elsif (/^-dryrun/) {
		$dryrun = 1;
		print STDERR "dryrun mode\n";
	} elsif (/^-v/) {
		$verbose = 1;
	} elsif (/^-q/) {
		$verbose = 0;
	} else {
		die "$ego: Unrecognized switch: $_\n";
	}
}

sub unbuffer_output {
	select((select(STDOUT), $| = 1)[0]);	# unbuffer output
	select((select(STDERR), $| = 1)[0]);	# unbuffer output
}

sub handler {
	local($sig) = @_;
	print STDERR "\n$ego: Caught SIG$sig\n";
	&cleanup; exit(1);
}

$SIG{'HUP'} = 'handler';
$SIG{'INT'} = 'handler';
$SIG{'QUIT'} = 'handler';
$SIG{'TERM'} = 'handler';

&unbuffer_output;

#
#   Begin "protected" code"
#
eval
{

if ($ARGV[0]) {
	while ($ARGV[0]) {
		$file = $ARGV[0]; shift;
		$file =~ s/^\.\///;
		die "Can't open file $file\n" if !open(FILE, "<$file");
		binmode(FILE);
		read(FILE, $file_text, $MAX);
		close(FILE);
		if (length($file_text) > $MAX - 3) {
			print STDERR "$ego: error! file too big...skipping $file\n";
			next;
		}
		next if (-d $file);
		

		$mtime = &get_mtime($file);

		###print $file_text;
		$dir = &dirname($file);
		$num_changes = 0;
		$org_file_text = $file_text;
		$file_text =~ s/[\r][\n]/\n/g;

		if ($file_text ne $org_file_text) {
			$file_text =~ s/[\r]/\n/g;
			if ($dryrun == 0) {
				die "Can't open file $file\n" if !open(FILE, ">$file");
				binmode(FILE);
				print FILE $file_text;
				close(FILE);
                		$now = time;
                		if (!utime($now, $mtime, $file)) {
                        		print "Can't set modification time for $file!!\n";
                		}
			}
			$num_changes = length($org_file_text) - length($file_text);
			print STDERR "removed $num_changes CR's from $file\n" if ($verbose);
		} else {
			##print STDERR "no changes needed to $file\n" if ($verbose);
		}
	}
}

if ($exit_status) {
	print STDERR "$ego: fatal processing errors!\n";
}

sub get_mtime {
	local($file) = @_;
        local($dev, $ino, $mode, $nlink, $uid, $gid, $rdev);
        local($size, $atime, $mtime, $ctime, $blksize, $blocks);

        ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, 
                $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($file);
	return $mtime;
}

}; # end of eval

if ($@) {
	warn $@;
	$exit_status = 1;
}
#
#   Cleanup
#
&cleanup;
exit($exit_status);

sub cleanup {
	close(FILE);
	&unbuffer_output;
	print STDOUT '';
	print STDERR '';
	if ($debug) {
		print STDERR "cleanup...\n";
	} else {
		foreach $tmp (sort(keys %tmp_kill_list)) {
			##print "unlink $tmp\n";
			unlink $tmp;
		}
	}
}
