chiark / gitweb /
0a6dba60474ea47ac3a6bb2aa8f1497fa4a14f7b
[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]|_|\\)/
94         length $1 eq 1 ? $1 : sprintf '%c', hex $1 
95             /ge;
96
97     $newf= 'new/'.$if;
98     mkparents($of);
99     defined($c= fork) or die $!;
100     if (!$c) {
101         unlink $newf;
102         open STDOUT, "> $newf" or die "$of $newf $!";
103         exec './gpt','config','files/'.$if; die $!;
104     }
105     $!=0; waitpid($c,0)==$c or die $!;
106     $? and die $?;
107
108     $perms= exists $fileperms{$of} ? $fileperms{$of} : 00666&~$umask;
109     chmod $perms, $newf or die $!;
110     
111     if (stat $home.$of) {
112         -f _ or die "$of is not a file!";
113         $nowperms= (stat _)[2] & 07777;
114         if (!$action) {
115             if ($nowperms != $perms) {
116                 would($of, sprintf 'chmod %04o -> %04o', $nowperms, $perms);
117             }
118             system 'diff','-u',$home.$of,$newf;
119             $?==0 or $?==256 or die $?;
120         }
121     } else {
122         would($of, sprintf 'create %04o', $perms);
123     }
124     if ($action) {
125         rename $newf,$home.$of or die $!;
126     }
127
128     delete $fileperms{$of};
129 }
130 closedir D or die $!;
131
132 die join(', ', keys %fileperms) if %fileperms;
133
134 foreach $dir (keys %dirperms) {
135     ensuredir($dir);
136 }
137
138 sub would ($$) {
139     my ($obj,$what) = @_;
140     return if $would_done{$obj}++;
141     print STDOUT "*** $what $obj\n" or die $!;
142 }
143
144 close STDOUT or die $!;