#!/usr/bin/perl -w # $Id: savepermscvs.pl,v 1.1 2001/04/11 14:32:04 stephand Exp $ # 20040411 stephan.duehr@suse.de # Funktion dieses Scripts: # Sichern der Permissions von Konfigurationsdateien, die im CVS gepflegt werden # im Format # FILEPATH OWNER.GROUP MODE # wie es von SuSEconfig in /etc/permissions verwendet wird. # (siehe man chkstat). # # Parameter: CVS-Arbeitsverzeichnis # (dort muß die Verzeichnisstruktur bezogen auf / abgebildet sein, # z.B. etc, var usw. use File::Find; use File::stat; use strict; my $cvsworkdir = $ARGV[0]; usage() if (! defined $cvsworkdir); # Mit "." als Pfadangabe funktionieren diverse Funktionen nicht # => ersetzen durch vollständigen absoluten Pfad if ($cvsworkdir eq ".") { $cvsworkdir = $ENV{'PWD'}; } # Pfad und Dateiname f. Sicherung der Permissions my $savepath = "etc"; my $savefile = "permissions.cvssave"; # abschließenden "/" entfernen, falls vorhanden $cvsworkdir =~ s/\/$//g; (-d $cvsworkdir) || die "Fehler: $cvsworkdir ist kein Verzeichnis!"; my %files = (); # cvsfilescb ist die Callback-Funktion File::Find::find(\&cvsfilescb, $cvsworkdir); # Permissions sichern bzw. ausgeben, falls Dateien gefunden wurden # Anzahl Elemente im Hash??? my @files = keys %files; if ($#files > -1) { # generieren der Permissions my @permissions = genperm(\%files); my $OUTFILE; my $tofile = 0; # Status für schreiben in File if (-d "$cvsworkdir/$savepath") { # Verzeichnis existiert => schreiben in $savefile print "Sicherung der Permissions in\n$cvsworkdir/$savepath/$savefile\n"; open(OUTFILE, ">$cvsworkdir/$savepath/$savefile") || die ("kann $cvsworkdir/$savepath/$savefile nicht schreiben"); $tofile=1; # Merken, daß in File geschrieben wird } else { # Pfad für Sicherungsdatei existiert nicht => schreiben auf stdout # Alias Filehandle für stdout erzeugen *OUTFILE=*STDOUT; } foreach my $line (@permissions) { print OUTFILE "$line\n"; } close(OUTFILE) if ($tofile); } # --------------------- Funktionen ------------------------ sub cvsfilescb { # callbackfunktion für File::Find return unless -f; # keine Directories return if $File::Find::dir =~ /\/CVS$/; # ignoriere CVS-Verzeichnisse return if $_ eq $savefile; # ignoriere vorhandenes Permission-savefile my $cvsworkfile = "$File::Find::dir/$_"; # Ursprungspfad ermitteln $cvsworkfile =~ /${cvsworkdir}\/(.+)/; my $realfile = "/" . $1; (-r $realfile) || die("Fehler: $realfile existiert nicht oder ist nicht lesbar"); $files{"$realfile"} = $cvsworkfile; } sub genperm { # generieren der Zeilen für Permission-Savefile my ($filesref) = @_; my @permlist = (); foreach my $key (keys %$filesref) { my $info = stat($key) || die "$key: stat error"; my $mode = get_type($info->mode) & 07777; my $modestring = sprintf("%04o", $mode); my $uid = $info->uid; my $uidname = getpwuid($uid); my $gid = $info->gid; my $gidname = getgrgid($gid); #print "$key $uidname" . "." . "$gidname $modestring\n"; push(@permlist, "$key $uidname" . "." . "$gidname $modestring"); } return @permlist; } sub get_type { # Funktion übernommen aus /usr/bin/chkstat my $S_IFLNK = 0120000; # symbolic link my $S_IFREG = 0100000; # regular file my $S_IFDIR = 0040000; # directory my $S_IFCHAR = 0020000; # character device my $S_IFBLK = 0060000; # block device my $S_IFFIFO = 0010000; # fifo my $S_IFSOCK = 0140000; # socket my $S_IFMT = 0170000; # type of file my $S_m; if (($_[0] & $S_IFMT) == $S_IFLNK) { $S_m = $_[0] - $S_IFLNK; } elsif (($_[0] & $S_IFMT) == $S_IFREG) { $S_m = $_[0] - $S_IFREG; } elsif (($_[0] & $S_IFMT) == $S_IFDIR) { $S_m = $_[0] - $S_IFDIR; } elsif (($_[0] & $S_IFMT) == $S_IFCHAR) { $S_m = $_[0] - $S_IFCHAR; } elsif (($_[0] & $S_IFMT) == $S_IFBLK) { $S_m = $_[0] - $S_IFBLK; } elsif (($_[0] & $S_IFMT) == $S_IFFIFO) { $S_m = $_[0] - $S_IFFIFO; } elsif (($_[0] & $S_IFMT) == $S_IFSOCK) { $S_m = $_[0] - $S_IFSOCK; } $S_m; } sub usage { print <