| [4] | 1 | #!/usr/bin/perl -w | 
|---|
|  | 2 |  | 
|---|
|  | 3 | # $Id: savepermscvs.pl,v 1.1 2001/04/11 14:32:04 stephand Exp $ | 
|---|
|  | 4 |  | 
|---|
|  | 5 | # 20040411 stephan.duehr@suse.de | 
|---|
|  | 6 | # Funktion dieses Scripts: | 
|---|
|  | 7 | # Sichern der Permissions von Konfigurationsdateien, die im CVS gepflegt werden | 
|---|
|  | 8 | # im Format | 
|---|
|  | 9 | #       FILEPATH OWNER.GROUP MODE | 
|---|
|  | 10 | # wie es von SuSEconfig in /etc/permissions verwendet wird. | 
|---|
|  | 11 | # (siehe man chkstat). | 
|---|
|  | 12 | # | 
|---|
|  | 13 | # Parameter: CVS-Arbeitsverzeichnis | 
|---|
|  | 14 | #            (dort muß die Verzeichnisstruktur bezogen auf / abgebildet sein, | 
|---|
|  | 15 | #            z.B. etc, var usw. | 
|---|
|  | 16 |  | 
|---|
|  | 17 | use File::Find; | 
|---|
|  | 18 | use File::stat; | 
|---|
|  | 19 | use strict; | 
|---|
|  | 20 |  | 
|---|
|  | 21 | my $cvsworkdir = $ARGV[0]; | 
|---|
|  | 22 | usage() if (! defined $cvsworkdir); | 
|---|
|  | 23 | # Mit "." als Pfadangabe funktionieren diverse Funktionen nicht | 
|---|
|  | 24 | # => ersetzen durch vollständigen absoluten Pfad | 
|---|
|  | 25 | if ($cvsworkdir eq ".") { | 
|---|
|  | 26 | $cvsworkdir = $ENV{'PWD'}; | 
|---|
|  | 27 | } | 
|---|
|  | 28 |  | 
|---|
|  | 29 | # Pfad und Dateiname f. Sicherung der Permissions | 
|---|
|  | 30 | my $savepath = "etc"; | 
|---|
|  | 31 | my $savefile = "permissions.cvssave"; | 
|---|
|  | 32 |  | 
|---|
|  | 33 | # abschließenden "/" entfernen, falls vorhanden | 
|---|
|  | 34 | $cvsworkdir =~ s/\/$//g; | 
|---|
|  | 35 |  | 
|---|
|  | 36 | (-d $cvsworkdir) || die "Fehler: $cvsworkdir ist kein Verzeichnis!"; | 
|---|
|  | 37 |  | 
|---|
|  | 38 | my %files = (); | 
|---|
|  | 39 |  | 
|---|
|  | 40 | # cvsfilescb ist die Callback-Funktion | 
|---|
|  | 41 | File::Find::find(\&cvsfilescb, $cvsworkdir); | 
|---|
|  | 42 |  | 
|---|
|  | 43 | # Permissions sichern bzw. ausgeben, falls Dateien gefunden wurden | 
|---|
|  | 44 | # Anzahl Elemente im Hash??? | 
|---|
|  | 45 | my @files = keys %files; | 
|---|
|  | 46 |  | 
|---|
|  | 47 | if ($#files > -1) { | 
|---|
|  | 48 | # generieren der Permissions | 
|---|
|  | 49 | my @permissions = genperm(\%files); | 
|---|
|  | 50 | my $OUTFILE; | 
|---|
|  | 51 | my $tofile = 0;   # Status für schreiben in File | 
|---|
|  | 52 | if (-d "$cvsworkdir/$savepath") { | 
|---|
|  | 53 | # Verzeichnis existiert => schreiben in $savefile | 
|---|
|  | 54 | print "Sicherung der Permissions in\n$cvsworkdir/$savepath/$savefile\n"; | 
|---|
|  | 55 | open(OUTFILE, ">$cvsworkdir/$savepath/$savefile") || | 
|---|
|  | 56 | die ("kann $cvsworkdir/$savepath/$savefile nicht schreiben"); | 
|---|
|  | 57 | $tofile=1;     # Merken, daß in File geschrieben wird | 
|---|
|  | 58 | } | 
|---|
|  | 59 | else { | 
|---|
|  | 60 | # Pfad für Sicherungsdatei existiert nicht => schreiben auf stdout | 
|---|
|  | 61 | # Alias Filehandle für stdout erzeugen | 
|---|
|  | 62 | *OUTFILE=*STDOUT; | 
|---|
|  | 63 | } | 
|---|
|  | 64 | foreach my $line (@permissions) { | 
|---|
|  | 65 | print OUTFILE "$line\n"; | 
|---|
|  | 66 | } | 
|---|
|  | 67 | close(OUTFILE) if ($tofile); | 
|---|
|  | 68 |  | 
|---|
|  | 69 |  | 
|---|
|  | 70 | } | 
|---|
|  | 71 |  | 
|---|
|  | 72 | # --------------------- Funktionen ------------------------ | 
|---|
|  | 73 |  | 
|---|
|  | 74 | sub cvsfilescb { | 
|---|
|  | 75 | # callbackfunktion für File::Find | 
|---|
|  | 76 | return unless -f;     # keine Directories | 
|---|
|  | 77 | return if $File::Find::dir =~ /\/CVS$/;       # ignoriere CVS-Verzeichnisse | 
|---|
|  | 78 | return if $_ eq $savefile;  # ignoriere vorhandenes Permission-savefile | 
|---|
|  | 79 | my $cvsworkfile = "$File::Find::dir/$_"; | 
|---|
|  | 80 | # Ursprungspfad ermitteln | 
|---|
|  | 81 | $cvsworkfile =~ /${cvsworkdir}\/(.+)/; | 
|---|
|  | 82 | my $realfile = "/" . $1; | 
|---|
|  | 83 | (-r $realfile) || die("Fehler: $realfile existiert nicht oder ist nicht lesbar"); | 
|---|
|  | 84 | $files{"$realfile"} = $cvsworkfile; | 
|---|
|  | 85 | } | 
|---|
|  | 86 |  | 
|---|
|  | 87 | sub genperm { | 
|---|
|  | 88 | # generieren der Zeilen für Permission-Savefile | 
|---|
|  | 89 | my ($filesref) = @_; | 
|---|
|  | 90 | my @permlist = (); | 
|---|
|  | 91 | foreach my $key (keys %$filesref) { | 
|---|
|  | 92 | my $info = stat($key) || die "$key: stat error"; | 
|---|
|  | 93 | my $mode = get_type($info->mode) & 07777; | 
|---|
|  | 94 | my $modestring = sprintf("%04o", $mode); | 
|---|
|  | 95 | my $uid = $info->uid; | 
|---|
|  | 96 | my $uidname = getpwuid($uid); | 
|---|
|  | 97 | my $gid = $info->gid; | 
|---|
|  | 98 | my $gidname = getgrgid($gid); | 
|---|
|  | 99 | #print "$key $uidname" . "." . "$gidname $modestring\n"; | 
|---|
|  | 100 | push(@permlist, "$key $uidname" . "." . "$gidname $modestring"); | 
|---|
|  | 101 | } | 
|---|
|  | 102 | return @permlist; | 
|---|
|  | 103 | } | 
|---|
|  | 104 |  | 
|---|
|  | 105 | sub get_type { | 
|---|
|  | 106 | # Funktion übernommen aus /usr/bin/chkstat | 
|---|
|  | 107 | my $S_IFLNK  = 0120000;    # symbolic link | 
|---|
|  | 108 | my $S_IFREG  = 0100000;    # regular file | 
|---|
|  | 109 | my $S_IFDIR  = 0040000;    # directory | 
|---|
|  | 110 | my $S_IFCHAR = 0020000;    # character device | 
|---|
|  | 111 | my $S_IFBLK  = 0060000;    # block device | 
|---|
|  | 112 | my $S_IFFIFO = 0010000;    # fifo | 
|---|
|  | 113 | my $S_IFSOCK = 0140000;    # socket | 
|---|
|  | 114 | my $S_IFMT   = 0170000;    # type of file | 
|---|
|  | 115 |  | 
|---|
|  | 116 | my $S_m; | 
|---|
|  | 117 | if (($_[0] & $S_IFMT) == $S_IFLNK) { $S_m = $_[0] - $S_IFLNK; } | 
|---|
|  | 118 | elsif (($_[0] & $S_IFMT) == $S_IFREG) { $S_m = $_[0] - $S_IFREG; } | 
|---|
|  | 119 | elsif (($_[0] & $S_IFMT) == $S_IFDIR) { $S_m = $_[0] - $S_IFDIR; } | 
|---|
|  | 120 | elsif (($_[0] & $S_IFMT) == $S_IFCHAR) { $S_m = $_[0] - $S_IFCHAR; } | 
|---|
|  | 121 | elsif (($_[0] & $S_IFMT) == $S_IFBLK) { $S_m = $_[0] - $S_IFBLK; } | 
|---|
|  | 122 | elsif (($_[0] & $S_IFMT) == $S_IFFIFO) { $S_m = $_[0] - $S_IFFIFO; } | 
|---|
|  | 123 | elsif (($_[0] & $S_IFMT) == $S_IFSOCK) { $S_m = $_[0] - $S_IFSOCK; } | 
|---|
|  | 124 | $S_m; | 
|---|
|  | 125 | } | 
|---|
|  | 126 |  | 
|---|
|  | 127 | sub usage { | 
|---|
|  | 128 | print <<EOF; | 
|---|
|  | 129 | Funktion dieses Scripts: | 
|---|
|  | 130 | Sichern der Permissions von Konfigurationsdateien, die im CVS gepflegt werden | 
|---|
|  | 131 | im Format | 
|---|
|  | 132 | FILEPATH OWNER.GROUP MODE | 
|---|
|  | 133 | wie es von SuSEconfig in /etc/permissions verwendet wird. | 
|---|
|  | 134 | (siehe man chkstat). | 
|---|
|  | 135 |  | 
|---|
|  | 136 | Falss es im CVS-Arbeitsverzeichnis etc/ gibt, wird das Ergebnis dort in | 
|---|
|  | 137 | der Datei permissions.cvssave abglegt und ansonsten auf stdout ausgegeben. | 
|---|
|  | 138 | Diese Datei kann verwendet werden, um mit chkstat permissions.cvssave die | 
|---|
|  | 139 | Permissions wiederherzustellen. | 
|---|
|  | 140 |  | 
|---|
|  | 141 | Parameter: CVS-Arbeitsverzeichnis | 
|---|
|  | 142 | (dort muß die Verzeichnisstruktur bezogen auf / abgebildet sein, | 
|---|
|  | 143 | z.B. etc, var usw. | 
|---|
|  | 144 |  | 
|---|
|  | 145 | EOF | 
|---|
|  | 146 | exit 1; | 
|---|
|  | 147 | } | 
|---|