b16b19f3 |
1 | #!/usr/bin/perl -w |
2 | |
3 | if(($#ARGV < 0) || ($ARGV[0] eq "help")) { |
4 | print STDERR "usage:\n"; |
5 | print STDERR "\tcdtool add {FILES|-g GRAFTPOINT}...\n"; |
6 | print STDERR "\tcdtool ls\n"; |
7 | print STDERR "\tcdtool rm NAME\n"; |
8 | print STDERR "\tcdtool szck\n"; |
9 | print STDERR "\tcdtool setgp [GRAFTPOINT]\n"; |
10 | print STDERR "\tcdtool setimg [IMAGE]\n"; |
11 | print STDERR "\tcdtool mkiso\n"; |
12 | exit 1; |
13 | } |
14 | |
15 | if(-r $ENV{"HOME"} . "/.cdtool") { |
16 | if(open CF, $ENV{"HOME"} . "/.cdtool") { |
17 | while(<CF>) { |
18 | next if /^\#/; |
19 | if(/^(\S+)\s+(.*)$/) { |
20 | if($1 eq "gp") { |
21 | $curgraft = $2; |
22 | } elsif($1 eq "img") { |
23 | $curimage = $2; |
24 | } else { |
25 | print STDERR "cdtool: warning: unknown .cdtool directive: $1\n"; |
26 | } |
27 | } |
28 | } |
29 | close CF; |
30 | } |
31 | } |
32 | |
33 | sub canonpath { |
34 | my($path) = @_; |
35 | $path = "./" . $path unless $path =~ m,^/,; |
36 | $path =~ s,/$,,; |
37 | $trailer = ""; |
38 | while(!-d $path) { |
39 | $path =~ s,/+([^/]*)$,,; |
40 | $trailer .= "/" . $1; |
41 | if($path eq "") { |
42 | die "weird path given: $_[0]"; |
43 | } |
44 | } |
45 | if(!open CHILD, "-|") { |
46 | chdir $path; |
47 | exec "pwd"; |
48 | die; |
49 | } |
50 | chomp($cpath = <CHILD>); |
51 | close CHILD; |
52 | return "$cpath$trailer"; |
53 | } |
54 | |
55 | sub dirname { |
56 | my($path) = @_; |
57 | $path =~ s,/[^/]+/*$,,; |
58 | return $path; |
59 | } |
60 | |
61 | sub addfile { |
62 | my($file, $graft) = @_; |
63 | my($dir, $f, $basename); |
64 | $basename = $file; |
65 | $basename =~ s,^.*/,,; |
66 | if(-f $file) { |
67 | print "add $file to $graft\n" if $verbose; |
68 | $img{"$graft$basename"} = $file; |
69 | } elsif(-d $file) { |
70 | $dir = canonpath $file; |
71 | if(opendir DIR, "$dir") { |
72 | for $f (sort grep !/^\./, readdir DIR) { |
73 | addfile("$dir/$f", "$graft$basename/"); |
74 | } |
75 | closedir DIR; |
76 | } else { |
77 | print STDERR "cdtool: could not open $file for listing: $!\n"; |
78 | } |
79 | } else { |
80 | print STDERR "cdtool: $file: not a regular file or directory\n"; |
81 | } |
82 | } |
83 | |
84 | sub readimage { |
85 | my($file, $dieonerr) = @_; |
86 | $dieonerr = 1 unless defined $dieonerr; |
87 | if(!open(IMG, "<", $file)) { |
88 | if($dieonerr) { |
89 | die "$file: $!"; |
90 | } else { |
91 | return; |
92 | } |
93 | } |
94 | while(<IMG>) { |
95 | if(/^file (.*):::(.*)$/) { |
96 | $img{$1} = $2; |
97 | } elsif(/^name (.*)$/) { |
98 | $imgname = $1; |
99 | } elsif(/^rev (\d+)$/) { |
100 | $rev = $1; |
101 | } elsif(/^justburned/) { |
102 | $justburned = 1; |
103 | } |
104 | } |
105 | close IMG; |
106 | } |
107 | |
108 | sub writeimage { |
109 | my($file) = @_; |
110 | open(IMG, ">", $file) || die "$file: $!"; |
111 | print IMG "rev $rev\n"; |
112 | print IMG "justburned\n" if $justburned; |
113 | for $f (sort keys %img) { |
114 | print IMG ("file " . $f . ":::" . $img{$f} . "\n"); |
115 | } |
116 | close IMG; |
117 | } |
118 | |
119 | $image = $curimage; |
120 | $imgname = $image; |
121 | $justburned = 0; |
122 | $imgname =~ s,^.*/,,; |
123 | $rev = 1; |
124 | $verbose = 0; |
125 | |
126 | while(($arg = shift @ARGV) =~ /^-(.+)/) { |
127 | $opts = $1; |
128 | while($opts =~ s/^(.)//) { |
129 | if($1 eq "v") { |
130 | $verbose = 1; |
131 | } |
132 | } |
133 | } |
134 | |
135 | $cmd = $arg; |
136 | if($cmd eq "add") { |
137 | if(!defined $image) { |
138 | print STDERR "cdtool: no image defined for adding\n"; |
139 | exit 1; |
140 | } |
141 | |
142 | readimage $image, 0; |
143 | $justburned = 0; |
144 | $graft = $curgraft; |
145 | $graft .= "/" unless $graft eq ""; |
146 | while(defined($arg = shift @ARGV)) { |
147 | if($arg eq "-g") { |
148 | $graft = shift @ARGV; |
149 | $graft =~ s,/+$,,; |
150 | $graft .= "/" unless $graft eq ""; |
151 | } else { |
152 | if(!defined $graft) { |
153 | print STDERR "cdtool: no graft point defined when adding\n"; |
154 | exit 1; |
155 | } |
156 | addfile canonpath($arg), $graft |
157 | } |
158 | } |
159 | writeimage $image; |
160 | } elsif($cmd eq "ls") { |
161 | readimage $image; |
162 | for $gf (sort keys %img) { |
163 | print "$gf\n"; |
164 | } |
165 | } elsif($cmd eq "rm") { |
166 | die "no name specified" unless defined($file = shift @ARGV); |
167 | $file = canonpath $file; |
168 | readimage $image; |
169 | $found = 0; |
170 | if(-d $file) { |
171 | $file .= "/"; |
172 | for $gname (grep substr($img{$_}, 0, length $file) eq $file, keys %img) { |
173 | delete $img{$gname}; |
174 | $found = 1; |
175 | } |
176 | } else { |
177 | for $gname (grep $img{$_} eq $file, keys %img) { |
178 | delete $img{$gname}; |
179 | $found = 1; |
180 | } |
181 | } |
182 | if(!$found) { |
183 | print STDERR "cdtool: $file not found in image\n"; |
184 | exit 1; |
185 | } |
186 | $justburned = 0; |
187 | writeimage $image; |
188 | } elsif($cmd eq "szck") { |
189 | readimage $image; |
190 | $size = 0; |
191 | for $file (values %img) { |
192 | $size += -s $file; |
193 | } |
194 | $size =~ s/(\d{3})/$1,/g; |
195 | $size =~ s/,$//; |
196 | print "$size\n"; |
197 | } elsif($cmd eq "setgp") { |
198 | $curgraft = shift @ARGV; |
199 | $curgraft =~ s,/+$,,; |
200 | } elsif($cmd eq "setimg") { |
201 | $curimage = shift @ARGV; |
202 | } elsif($cmd eq "mkiso") { |
203 | readimage $image; |
204 | open(ISO, "|-", "mkisofs", "-J", "-R", "-V", "$imgname r$rev", "-graft-points", "-path-list", "-") || die "mkisofs: $!"; |
205 | for $gf (sort keys %img) { |
206 | print ISO ($gf . "=" . $img{$gf} . "\n"); |
207 | } |
208 | close ISO; |
209 | if(!$justburned) { |
210 | $rev++; |
211 | $justburned = 1; |
212 | } |
213 | writeimage $image; |
214 | } else { |
215 | print STDERR "cdtool: unknown command: $cmd\n"; |
216 | exit 1; |
217 | } |
218 | |
219 | die if(!open CF, ">" . $ENV{"HOME"} . "/.cdtool"); |
220 | if(defined $curgraft) { |
221 | print CF "gp $curgraft\n"; |
222 | } |
223 | if(defined $curimage) { |
224 | print CF "img $curimage\n"; |
225 | } |
226 | close CF; |