chiark / gitweb /
autotitle builds and installs. Various fixes.
[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[0] =~ 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 die if @ARGV;
25
26 stat $home or die $!;
27 -d _ or die;
28
29 sub read_prep ($) {
30     my ($inputfile) = @_;
31     defined($c= open P, "-|") or die $!;
32     if (!$c) { exec './gpt','config',$inputfile; die $!; }
33 }
34 sub fin_prep () {
35     $!=0; close P; die "$! $?" if $! or $?;
36 }
37
38 read_prep('perms');
39 for (;;) {
40     $!=0; defined($_=<P>) or die $!;
41     chomp; s/^\s+//; s/\s+$//;
42     next if m/^\#/; next unless m/\S/;
43     last if m/^\.$/;
44     m/^(.*\S)\s+([0-7]+)$/ or die;
45     ($of,$pe)=($1,oct $2);
46     $isdir= $of =~ s,/$,,;
47     ($isdir ? $dirperms{$of} : $fileperms{$of}) = $pe;
48 }
49 fin_prep();
50
51 sub mkparents ($) {
52     my ($parent) = @_;
53     $parent =~ s,/[^/]+$,, or return;
54     ensuredir($parent);
55 }
56
57 sub maybe_chmod ($$$) {
58     my ($nowperms,$perms,$obj) = @_;
59     return if $nowperms==$perms;
60     if ($action) {
61         chmod $perms, $home.$obj or die $!;
62     } else {
63         would($obj, sprintf 'chmod %04o -> %04o', $nowperms, $perms);
64     }
65 }
66
67 sub ensuredir ($) {
68     my ($dir) = @_;
69     mkparents($dir);
70     $perms= exists $dirperms{$dir} ? $dirperms{$dir} : 02777&~$umask;
71     if (stat $home.$dir) {
72         -d _ or die "$dir is not a directory!";
73         $nowperms= (stat _)[2] & 07777;
74         maybe_chmod($nowperms,$perms,$dir);
75     } else {
76         die $! unless $!==&ENOENT;
77         if ($action) {
78             mkdir $home.$dir, $perms or die $!;
79         } else {
80             would($dir, sprintf 'mkdir %04o', $perms);
81         }
82     }
83 }
84
85 -d 'new' or mkdir 'new', 02700 or die $!;
86
87 sub prep_proc ($$) {
88     my ($if,$newf) = @_;
89     my ($c);
90     defined($c= fork) or die $!;
91     if (!$c) {
92         unlink $newf;
93         open STDOUT, "> $newf" or die "$newf $!";
94         exec './gpt','config',$if; die $!;
95     }
96     $!=0; waitpid($c,0)==$c or die $!;
97     $? and die $?;
98 }
99
100 opendir D, "files" or die $!;
101 while ($if=readdir D) {
102     next unless $if =~ m/^[_a-z0-9\\]/;
103     $of= $if; 
104     $of =~ s,_,/,g; 
105     $of =~ s,^/,,;
106     $of =~ s,//,_,g;
107     $of =~ s/\\([0-9a-f][0-9a-f]|_|\\)/
108         length $1 eq 1 ? $1 : sprintf '%c', hex $1 
109             /ge;
110
111     mkparents($of);
112     $newf= 'new/'.$if;
113     prep_proc('files/'.$if,$newf);
114
115     $perms= exists $fileperms{$of} ? $fileperms{$of} : 00666&~$umask;
116     chmod $perms, $newf or die $!;
117     
118     if (stat $home.$of) {
119         -f _ or die "$of is not a file!";
120         $nowperms= (stat _)[2] & 07777;
121         if ($nowperms != $perms) {
122             would($of, sprintf 'chmod %04o -> %04o', $nowperms, $perms);
123         }
124         if (!$action) {
125             system 'diff','-u',$home.$of,$newf;
126             $?==0 or $?==256 or die $?;
127             $changes++ if $?;
128         }
129     } else {
130         would($of, sprintf 'create %04o', $perms);
131     }
132     if ($action) {
133         rename $newf,$home.$of or die $!;
134     }
135
136     delete $fileperms{$of};
137 }
138 closedir D or die $!;
139
140 die join(', ', keys %fileperms) if %fileperms;
141
142 foreach $dir (keys %dirperms) {
143     ensuredir($dir);
144 }
145
146 sub would ($$) {
147     my ($obj,$what) = @_;
148     return if $would_done{$obj}++;
149     print STDOUT "*** $what $obj\n" or die $!;
150     $changes++;
151 }
152
153 if ($changes) {
154     print STDOUT "=== $changes changes\n" or die $!;
155 } else {
156     print STDOUT "=== no changes\n" or die $!;
157 }
158
159 prep_proc('execute','new/,execute');
160 if ($action) {
161     chmod 0700,'new/,execute' or die $!;
162     system 'new/,execute'; $? and die $?;
163 }
164
165 close STDOUT or die $!;