chiark / gitweb /
Almost ready to try out on viking; must still remove colons.
[ian-dotfiles.git] / process
1 #!/usr/bin/perl
2
3 use POSIX;
4
5 $action=0;
6 defined($umask=umask) or die $!;
7 $home= $ENV{'HOME'}.'/';
8
9 while (@ARGV =~ m/^-/) {
10     $_= shift(@ARGV);
11     last if m/^--$/;
12     while (m/^-./) {
13         if (s/^-y/-/) {
14             $action=1;
15         } elsif (s/^-u([0-7]{3})/-/) {
16             $umask= oct $1;
17         } elsif (s/^-h/-/) {
18             $home= $';
19         } else {
20             die;
21         }
22     }
23 }
24
25 stat $home or die $!;
26 -d _ or die;
27
28 sub read_prep ($) {
29     my ($inputfile) = @_;
30     defined($c= open P, "-|") or die $!;
31     if (!$c) { exec './gpt','config',$inputfile; die $!; }
32 }
33 sub fin_prep () {
34     $!=0; close P; die "$! $?" if $! or $?;
35 }
36
37 read_prep('perms');
38 for (;;) {
39     $!=0; defined($_=<P>) or die $!;
40     chomp; s/^\s+//; s/\s+$//;
41     next if m/^\#/; next unless m/\S/;
42     last if m/^\.$/;
43     m/^(.*\S)\s+([0-7]+)$/ or die;
44     ($of,$pe)=($1,oct $2);
45     $isdir= $of =~ s,/$,,;
46     ($isdir ? $dirperms{$of} : $fileperms{$of}) = $pe;
47 }
48 fin_prep();
49
50 sub mkparents ($) {
51     my ($parent) = @_;
52     $parent =~ s,/[^/]+$,, or return;
53     ensuredir($parent);
54 }
55
56 sub maybe_chmod ($$$) {
57     my ($nowperms,$perms,$obj) = @_;
58     return if $nowperms==$perms;
59     if ($doing) {
60         chmod $perms, $home.$obj or die $!;
61     } else {
62         would($obj, sprintf 'chmod %04o -> %04o', $nowperms, $perms);
63     }
64 }
65
66 sub ensuredir ($) {
67     my ($dir) = @_;
68     mkparents($dir);
69     $perms= exists $dirperms{$dir} ? $dirperms{$dir} : 02777&~$umask;
70     if (stat $home.$dir) {
71         -d _ or die "$dir is not a directory!";
72         $nowperms= (stat _)[2] & 07777;
73         maybe_chmod($nowperms,$perms,$dir);
74     } else {
75         die $! unless $!==&ENOENT;
76         if ($doing) {
77             mkdir $home.$dir, $perms or die $!;
78         } else {
79             would($dir, sprintf 'mkdir %04o', $perms);
80         }
81     }
82 }
83
84 -d 'new' or mkdir 'new', 02700 or die $!;
85
86 opendir D, "files" or die $!;
87 while ($if=readdir D) {
88     next unless $if =~ m/^[:a-z0-9]/;
89     $of= $if; 
90     $of =~ s,\:,/,g; 
91     $of =~ s,^/,,;
92     $of =~ s,\\\;,:,g;
93     $of =~ s:\\([0-9a-f][0-9a-f]): sprintf '%c', hex $1 :ge;
94
95     $newf= 'new/'.$if;
96     mkparents($of);
97     defined($c= fork) or die $!;
98     if (!$c) {
99         unlink $newf;
100         open STDOUT, "> $newf" or die "$of $newf $!";
101         exec './gpt','config','files/'.$if; die $!;
102     }
103     $!=0; waitpid($c,0)==$c or die $!;
104     $? and die $?;
105
106     $perms= exists $fileperms{$of} ? $fileperms{$of} : 00666&~$umask;
107     chmod $perms, $newf or die $!;
108     
109     if (stat $home.$of) {
110         -f _ or die "$of is not a file!";
111         $nowperms= (stat _)[2] & 07777;
112         if (!$action) {
113             if ($nowperms != $perms) {
114                 would($of, sprintf 'chmod %04o -> %04o', $nowperms, $perms);
115             }
116             system 'diff','-u',$home.$of,$newf;
117             $?==0 or $?==256 or die $?;
118         }
119     } else {
120         would($of, sprintf 'create %04o', $perms);
121     }
122     if ($action) {
123         rename $newf,$home.$of or die $!;
124     }
125
126     delete $fileperms{$of};
127 }
128 closedir D or die $!;
129
130 die join(', ', keys %fileperms) if %fileperms;
131
132 foreach $dir (keys %dirperms) {
133     ensuredir($dir);
134 }
135
136 sub would ($$) {
137     my ($obj,$what) = @_;
138     return if $would_done{$obj}++;
139     print STDOUT "*** $what $obj\n" or die $!;
140 }
141
142 close STDOUT or die $!;