#!/usr/bin/perl -w
# $Id: fixup.pl,v 1.6 1997/11/24 05:35:36 ray Exp ray $
#use strict;

($C = $0) =~ s%.*/%%;

my $Target = "";
my $Rght = "";
my $Wrng = "";
my $RE = "";

my $Help = 0;
my $OptErr = "";
my $Global = 0;
my $First = 1;
my $Orig = 0;
my $verbose = 0;
my $debug = 0;

sub Usage ($$) {
  my( $rv, $msg) = @_;
  print( STDERR $msg . "\n") if ( $msg );
  printf( STDERR "Usage: $C [options] target wrong right\n");
  $rv = 0 if ( $Opt{'help'} );
  exit( $rv);
}

{
  use Getopt::Long;
  $Getopt::Long::debug = 0;
  $Getopt::Long::ignorecase = 0;
  #$Getopt::Long::pass_through = 1;
  $Getopt::Long::bundling = 1;
  %Opt = ();

  Usage(1, "") unless ( GetOptions( \%Opt,
	'help|h', 'verbose|v', 'debug|d', 'orig|b',
	'global|g', 'interpreter-only|i',
	'target|T=s', 'RE|e=s') && ! $Opt{'help'} );

  ( $Global ++, $First = 0 ) if ( $Opt{'global'} );
  ( $RE = $Opt{'RE'}, $Global ++, $First = 0 ) if ( $Opt{'RE'} );
  $First ++ if ( $Opt{'interpreter-only'} );
  $Orig ++ if ( $Opt{'orig'} );
  $verbose ++ if ( $Opt{'verbose'} );
  ( $debug ++, $verbose ++ ) if ( $Opt{'debug'} );
  $Help ++ if ( $Opt{'help'} );
  $Target = $Opt{'target'} if ( $Opt{'target'} );

}


if ( $#ARGV >= $[ ) {
  Usage( 1, "") unless ( $#ARGV == $[ + 2 && ! $Target && ! $RE );
  $Target = shift;
  $Wrng = shift;
  $Rght = shift;
  printf( STDERR "Target='%s' Wrng='%s' Rght='%s'\n", $Target, $Wrng, $Rght)
     if ( $debug );
} elsif ( ! $Target ) {
  Usage( 2, "$C: no target specified.\n");
} elsif ( ! -e "$Target" ) {
  Usage( 3, "$C: $Target: no such object.\n");
} elsif ( ! $RE ) {
  Usage( 4, "");
}

if ( $First ) {
  Usage( 5, "$C: '--interpreter-only' and '--re' are mutual exclusive.\n")
     if ( $RE );
  Usage( 6, "$C: '--global' and '--interpreter-only' are mutual exclusive.\n")
     if ( $Global );
  Usage( 7, "$C: '--interpreter-only' requires 'wrong' and 'right'.\n")
     unless ( $Wrng && $Rght );
  $RE= 's^(\#\!\s*\S*)' . $Wrng . '$1' . $Rght . 'o';
} else {
  $RE= 's' . $Wrng . '' . $Rght . 'ogs' unless ( $RE );
}
undef( $Wrng);
undef( $Rght);
printf( STDERR "Target='%s' RE='%s'\n", $Target, $RE) if ( $debug );
#exit(42);

open( FIND, "find $Target -type f -print |") || die;

while ( defined($f = <FIND>) ) {
  chop($f);
  my $n = $f . ".fixed" . $$;
  my $m = 0;
  next unless ( -s $f );
  open( IN, "< $f") || die;
  open( OUT, "> $n") || die;

  $_ = <IN>;
  if ( $Global ) {
    do {
      $m += eval "$RE";
      print( OUT $_) || die;
    } while ( <IN> );
  } else {
    $m += eval $RE;
    if ( $m ) {  
      do {
        print( OUT $_) || die;
      } while ( <IN> );
    }
  }
  close( OUT);
  if ( $m ) {
    printf( "%s: %d occurance%s\n", $f, $m, ($m == 1)?"":"s") if ( $verbose );
    cpmod( $f, $n);
    if ( $Orig ) {
      rename( $f, $f . ".orig") || die;
    }
    rename( $n, $f) || die;
  } else {
    unlink( $n) || die;
    printf( "%s: OK\n", $f) if ( $verbose >= 2 );
  }
  close( IN);
}

exit( 0);

sub cpmod($$) {
  my( $Org, $Dup) = @_;
  my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
      $atime,$mtime,$ctime,$blksize,$blocks) = stat($Org);
  $mode &= 007777;
  chown( $uid, $gid, $Dup) || die( "$CMD: cannot chown( $uid, $gid, $Dup).\n");
  chmod( $mode, $Dup) || die( "$CMD: cannot chmod( $mode, $Dup).\n");
  utime( $atime, $mtime, $Dup) || die( "$CMD: cannot utime( $Dup).\n");
}

