#!/usr/bin/perl -w

# $Id$

# 20040410 stephan.duehr@suse.de
# Funktion dieses Scripts:
# Es sollen Konfigurationsdatei (z.B. in /etc und /var) im CVS gepflegt werden.
# Überprüfen welche Dateien sich gegenüber der CVS-Arbeitskopie geändert haben
# und kopiert diese auf Wunsch in das CVS-Arbeitsverzeichnis

# Parameter: CVS-Arbeitsverzeichnis
#            (dort muß die Verzeichnisstruktur bezogen auf / abgebildet sein, 
#            z.B. etc, var usw.

use strict;

use Env qw($DASSCM_PROD $DASSCM_REPO $USER $DASSCM_USER $DASSCM_PW);
use Cwd;
use POSIX qw/getpgrp tcgetpgrp/;
use File::Find;
use File::Compare;
use File::Copy;


my $cvsworkdir = $ARGV[0];
if(! defined $cvsworkdir) {
	$cvsworkdir = $DASSCM_REPO;
}
usage() if (! defined $cvsworkdir);
# Mit "." als Pfadangabe funktionieren diverse Funktionen nicht
# => ersetzen durch vollständigen absoluten Pfad
if ($cvsworkdir eq ".") {
  $cvsworkdir = $ENV{'PWD'};
}

# abschließenden "/" entfernen, falls vorhanden
$cvsworkdir =~ s/\/$//g;

(-d $cvsworkdir) || die "Fehler: $cvsworkdir ist kein Verzeichnis!";


my %changedfiles = ();

File::Find::find(\&cvscheck, $cvsworkdir);

# Liste der geänderten Files ausgeben, falls nicht leer
# Anzahl Elemente im Hash???
my @changedfiles = keys %changedfiles;

if ($#changedfiles > -1) {
  print "Geänderte Dateien:\n";
  foreach my $key (keys %changedfiles) {
    print "$key\n";
  }
#   if (I_am_interactive()) {
#     print "Die Dateien nach $cvsworkdir kopieren? (j/n)";
#     my $line = <STDIN>;
#     chomp($line);
#     if ($line eq "j") {
#       print "kopiere...\n";
#       foreach my $key (keys %changedfiles) {
#         print "$key --> $changedfiles{$key} ";
#         copy($key, $changedfiles{$key}) || print "(fehlgeschlagen)";
#         print "\n";
#       }
#       print "bitte noch manuell einen commit ... ausführen.\n";
#       # CVS Environment prüfen
#       #print "Hinweis: CVSROOT nicht gesetzt\n" unless defined $ENV{'CVSROOT'};
#     }
#  }
}
else {
  print "keine geänderten Dateien in $cvsworkdir gefunden.\n";
}
print "\n";

sub cvscheck {
  return unless -f;	# keine Directories
  return if $File::Find::dir =~ /\/CVS$/;	# ignoriere CVS-Verzeichnisse
  return if $File::Find::dir =~ /\/\.svn/;	# ignoriere Subversion Verzeichnisse (inkl. Unterverzeichnisse)
  my $cvsworkfile = "$File::Find::dir/$_";
  #print "$cvsworkfile\n";
  # Ursprungspfad ermitteln
  $cvsworkfile =~ /${cvsworkdir}\/(.+)/;
  my $realfile = "/" . $1;
  # relativer Pfad zur CVS-Arbeitsdatei
  my $relcvsworkfile = $1;
#  (-r $realfile) || die("Fehler: $realfile existiert nicht oder ist nicht lesbar");
  if( ! -r $realfile ) {
	print "d     $realfile\n";
  } else {
	(-r "$cvsworkfile") || die("Fehler: $cvsworkfile ist nicht lesbar");
	if (compare($cvsworkfile,$realfile) != 0) {
		# Dateien unterscheiden sich
		(-w $cvsworkfile) || die("Fehler: kein Schreibrecht auf $cvsworkfile");
		# Arbeitskopie durch Kopie ersetzen
		#copy($realfile,$cvsworkfile) || die("Fehler beim kopieren $realfile --> $cvsworkfile");
		$changedfiles{"$realfile"} = $cvsworkfile;
	}
  }
}


sub I_am_interactive {
    local *TTY;  # local file handle
    open(TTY, "/dev/tty") or die "can't open /dev/tty: $!";
    my $tpgrp = tcgetpgrp(fileno(TTY));
    my $pgrp  = getpgrp();
    close TTY;
    return ($tpgrp == $pgrp);
}

sub usage {
print <<EOF;
Funktion dieses Scripts:
Es sollen Konfigurationsdatei (z.B. in /etc und /var) 
im Versionskontrollsystem (Subversion oder CVS) gepflegt werden.
Überprüfen welche Dateien sich gegenüber der CVS-Arbeitskopie geändert haben und kopiert diese auf Wunsch in das Subversion/CVS-Arbeitsverzeichnis

Parameter: Subversion/CVS-Arbeitsverzeichnis
           (dort muß die Verzeichnisstruktur bezogen auf / abgebildet sein, 
           z.B. etc, var usw.)
	   Alternativ kann dieses über die Umgebungsvariable
	   \$DASSCM_REPO gesetzt sein.

EOF
exit 1;
}
