#!/usr/bin/perl -w
#
# This is rpm-rewrite.pl, which extends syntax in RPM spec.
# It provide %rewritetrigger section
# in order to rewrite configuration files
# which belong to other RPMs.
# In fact, it translate %rewritetrigger into %triggerin/un.

# usage1: rpm-rewrite.pl < old.spec > new.spec
# usage2: rpm-rewrite.pl < new.spec > even_new.spec

# (C) Nobuyuki Tsuchimura (tutimura@nn.iij4u.or.jp)
# http://www.nn.iij4u.or.jp/~tutimura/rpm-rewrite/
# This script should be distributed under GPL.

$version = "0.5";
$begin_rpm = "# begin generated by rpm-rewrite.pl ";
$end_rpm   = "# end generated by rpm-rewrite.pl ";
$org_mark  = "ORIGINAL_CODE";
$begin_org = "cat <<$org_mark >/dev/null";
$end_org   = $org_mark;
$begin_cat = "Do not edit this line - begin %{name}-%{version}-%{release}";
$end_cat   = "Do not edit this line - end %{name}-%{version}-%{release}";

$rewrite_part = 0;
$generate_part = 0;
$output = 0;
@rewrite_line = ();
@empty_line = ();
$comment_char = "";

while(<>) {
    if ( $generate_part == 0 and $rewrite_part == 1 and /^\s*$/ ) {
	#print "empty\n";
	push( @empty_line, $_ ); next;
    }

    if ( /^$begin_rpm/ ) {
	$generate_part = 1;
	$rewrite_part = 0;
	$output = 1;
    } elsif ( /$org_mark/ and $generate_part == 1 ) {
	$generate_part = 2;
    } elsif ( /$org_mark/ and $generate_part == 2 ) {
	$generate_part = 1;
	$output = 1;
	shift(@rewrite_line);
	shift(@rewrite_line);
	pop(@rewrite_line);
    } elsif ( $generate_part == 0 ) {
	if ( $rewrite_part == 2 ) {
	    if ( /^$comment_char\s*$/ ) { $rewrite_part = 1; }
	} elsif ( $rewrite_part == 1 and /^%rewrite \S+\s+(\S)\s*$/ ) {
	    $rewrite_part = 2;
	    $comment_char = $1;
	} elsif ( /^%rewritetrigger\s/ or ( /^%/ and ! /^%rewrite/ ) ) {
	    $rewrite_part = 0;
	    $rewrite_part = 1 if ( /^%rewritetrigger\s/ );
	    $output = 1;
	}
    }

    if ( $output == 1 ) {
	$output = 0;
	if ( @rewrite_line ) {
	    print "$begin_rpm$version\n";
	    print "# http://www.nn.iij4u.or.jp/~tutimura/rpm-rewrite/\n";
	    rewrite( 0, @rewrite_line );
	    rewrite( 1, @rewrite_line );
	    print "$end_rpm$version\n";
	    @rewrite_line = ();
	    print @empty_line;  @empty_line = ();
	}
    }

    #print "$generate_part $rewrite_part $comment_char\n";
    if ( $generate_part == 2 or $rewrite_part > 0 ) {
	push( @rewrite_line, @empty_line, $_ );
	@empty_line = ();
    } elsif ( $generate_part == 0 ) {
	print @empty_line;  @empty_line = ();
	print;
    }

    if ( /^$end_rpm/ ) {
	$generate_part = 0;
    }
}



sub rewrite() {
    my ( $uninstall, @input ) = @_;
    my $rewrite_part = 0;
    my $comment_char = "";
    my $rewrite_file = "";
    my $append_file = "";
    my $cat = "";
    my $triggerin = "";
    my $triggerun = "";
    my $trigger = $input[0];  $trigger =~ s/%rewritetrigger /%triggerin /;

    if ( $uninstall == 0 ) {
	print "$trigger$begin_org\n";
	print "--------\n";
	print @input;
	print "--------\n";
	print "$end_org\n\n";
    } else {
	$trigger =~ s/%triggerin /%triggerun /;
	print "\n$trigger";
    }
    shift(@input); push(@input, "");

    foreach $in (@input) {
	if ( $rewrite_part == 1 ) {
	    if ( $in =~ /^$comment_char\s*$/ ) {
		$rewrite_part = 2;
	    } else {
		$cat = $cat . $in;
	    }
	} elsif ( $in =~ /^%rewrite / or $in =~ /^$/ ) {
	    if ( $append_file ne "" ) {
		if ( $uninstall == 0 ) {
		    triggerin_file( $rewrite_file, $comment_char,
				   $triggerin, $append_file );
		} else {
		    triggerun( $rewrite_file, $comment_char, $triggerun );
		}
		$append_file = "";
	    } elsif ( $cat ) {
		if ( $uninstall == 0 ) {
		    triggerin_cat( $rewrite_file, $comment_char,
				   $triggerin, $cat );
		} else {
		    triggerun( $rewrite_file, $comment_char, $triggerun );
		}
		$cat = "";
	    } else {
		if ( $uninstall == 0 ) {
		    print "$triggerin";
		} else {
		    print "$triggerun";
		}
	    }
	    $triggerin = $triggerun = "";

	    if ( $in =~ /^%rewrite (\S+)\s+(\S)\s*$/ ) {
		$rewrite_part = 1;
		$rewrite_file = $1;
		$comment_char = $2;
	    } elsif ( $in =~ /^%rewrite (\S+)\s+-f\s+(\S+)\s+(\S)\s*$/ ) {
		$rewrite_part = 2;
		$rewrite_file = $1;
		$append_file =  $2;
		$comment_char = $3;
	    } elsif ( ! ($in =~ /^$/) ) {
		print "%rewrite syntax error!($in)\n";
	    }
	}
	elsif ( $in =~ /^%rewritein/ ) { $rewrite_part = 3; }
	elsif ( $in =~ /^%rewriteun/ ) { $rewrite_part = 4; }
	elsif ( $rewrite_part == 3 ) { $triggerin = $triggerin . $in; }
	elsif ( $rewrite_part == 4 ) { $triggerun = $triggerun . $in; }
    }
}

sub triggerin_cat() {
    my ( $rewrite_file, $comment_char, $triggerin, $cat ) = @_;
    rewrite_script( $rewrite_file, $comment_char );

print <<EOS;
cat <<EOF >>$rewrite_file
$comment_char $begin_cat \$2
$comment_char This part was added and will be removed by RPM automatically.
$cat$comment_char $end_cat \$2
EOF
${triggerin}fi
EOS
}

sub triggerin_file() {
    my ( $rewrite_file, $comment_char, $triggerin, $file ) = @_;
    rewrite_script( $rewrite_file, $comment_char );

print <<EOS;
echo "$comment_char $begin_cat \$2" >> $rewrite_file
echo "$comment_char This part was added and will be removed by RPM automatically." >> $rewrite_file
cat $file >>$rewrite_file
echo "$comment_char $end_cat \$2" >> $rewrite_file
${triggerin}fi
EOS
}

sub triggerun() {
    my ( $rewrite_file, $comment_char, $triggerun ) = @_;
    rewrite_script( $rewrite_file, $comment_char );

print <<EOS;
${triggerun}fi
EOS
}

sub rewrite_script() {
    my ( $rewrite_file, $comment_char ) = @_;

print <<EOS
if [ -e $rewrite_file ]; then
cp -af $rewrite_file $rewrite_file.rpmtemp && \\
    sed -e '/^$comment_char $begin_cat 1\$/,/^$comment_char $end_cat 1\$/d' \\
        -e 's/^$comment_char $begin_cat 2\$/$comment_char $begin_cat 1/' \\
        -e 's/^$comment_char $end_cat 2\$/$comment_char $end_cat 1/' \\
    < $rewrite_file.rpmtemp > $rewrite_file
EOS
}
