#!/usr/bin/perl use POSIX; $action=0; defined($umask=umask) or die $!; $home= $ENV{'HOME'}.'/'; while ($ARGV[0] =~ m/^-/) { $_= shift(@ARGV); last if m/^--$/; while (m/^-./) { if (s/^-y/-/) { $action=1; } elsif (s/^-u([0-7]{3})/-/) { $umask= oct $1; } elsif (s/^-h/-/) { $home= $'; } else { die; } } } die if @ARGV; stat $home or die $!; -d _ or die; sub read_prep ($) { my ($inputfile) = @_; defined($c= open P, "-|") or die $!; if (!$c) { exec './gpt','config',$inputfile; die $!; } } sub fin_prep () { close P; die "$?" if $?; } read_prep('perms'); for (;;) { $!=0; defined($_=

) or die $!; chomp; s/^\s+//; s/\s+$//; next if m/^\#/; next unless m/\S/; last if m/^\.$/; if (m/(.*\S)\s+\-\>\s+(\S.*)/) { $linktargs{$1}= $2; } elsif (m/^(.*\S)\s+(\S+)$/) { ($of,$pe)=($1,$2); $isdir= $of =~ s,/$,,; if ($pe =~ m/^[0-7]+$/) { $pe= oct $&; } elsif ($pe eq '+x') { $pe= 0777&~$umask; } elsif ($pe eq '/') { $pe= 02777&~$umask; } else { die "$pe ?"; } ($isdir ? $dirperms{$of} : $fileperms{$of}) = $pe; } } fin_prep(); sub mkparents ($) { my ($parent) = @_; $parent =~ s,/[^/]+$,, or return; ensuredir($parent); } sub maybe_chmod ($$$) { my ($nowperms,$perms,$obj) = @_; return if $nowperms==$perms; if ($action) { chmod $perms, $home.$obj or die $!; } else { would($obj, sprintf 'chmod %04o -> %04o', $nowperms, $perms); } } sub ensuredir ($) { my ($dir) = @_; mkparents($dir); $perms= exists $dirperms{$dir} ? $dirperms{$dir} : 02777&~$umask; if (stat $home.$dir) { -d _ or die "$dir is not a directory!"; $nowperms= (stat _)[2] & 07777; maybe_chmod($nowperms,$perms,$dir); } else { die $! unless $!==&ENOENT; if ($action) { mkdir $home.$dir, $perms or die $!; } else { would($dir, sprintf 'mkdir %04o', $perms); } } } -d 'new' or mkdir 'new', 02700 or die $!; sub prep_proc ($$) { my ($if,$newf) = @_; my ($c); defined($c= fork) or die $!; if (!$c) { unlink $newf; open STDOUT, "> $newf" or die "$newf $!"; exec './gpt','config',$if; die $!; } $!=0; waitpid($c,0)==$c or die $!; $? and die $?; } opendir D, "files" or die $!; while ($if=readdir D) { next unless $if =~ m/^[_a-z0-9\\]/; $of= $if; $of =~ s,_,/,g; $of =~ s,^/,,; $of =~ s,//,_,g; $of =~ s/\\([0-9a-f][0-9a-f]|_|\\)/ length $1 eq 1 ? $1 : sprintf '%c', hex $1 /ge; mkparents($of); $newf= 'new/'.$if; prep_proc('files/'.$if,$newf); $perms= exists $fileperms{$of} ? $fileperms{$of} : 00666&~$umask; chmod $perms, $newf or die $!; if (stat $home.$of) { -f _ or die "$of is not a file!"; $nowperms= (stat _)[2] & 07777; if ($nowperms != $perms) { would($of, sprintf 'chmod %04o -> %04o', $nowperms, $perms); } system 'diff','-u',$home.$of,$newf; $?==0 or $?==256 or die $?; $changes++ if $?; } else { die unless $!==&ENOENT; would($of, sprintf 'create %04o', $perms); } if ($action) { rename $newf,$home.$of or die $!; } delete $fileperms{$of}; } closedir D or die $!; die join(', ', keys %fileperms) if %fileperms; foreach $link (keys %linktargs) { mkparents($link); $targ= $linktargs{$link}; if (lstat $home.$link) { -l _ or die "$link is not a link!"; defined($rl= readlink $home.$link) or die $!; } else { die unless $!==&ENOENT; $rl= undef; } if ($rl ne $targ) { would($link, "symlink $targ <-"); if ($action) { unlink $home.$link if defined $rl; symlink $targ,$home.$link or die $!; } } } foreach $dir (keys %dirperms) { ensuredir($dir); } sub would ($$) { my ($obj,$what) = @_; return if $would_done{$obj}++; print STDOUT "*** $what $obj\n" or die $!; $changes++; } if ($changes) { print STDOUT "=== $changes changes\n" or die $!; } else { print STDOUT "=== no changes\n" or die $!; } prep_proc('execute','new/,execute'); if ($action) { chmod 0700,'new/,execute' or die $!; system 'new/,execute'; $? and die $?; } close STDOUT or die $!;