| 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 | } | 
|---|