| 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 "imgck") { |
| 203 | readimage $image; |
| 204 | for $file (values %img) { |
| 205 | if(! -r $file) { |
| 206 | print "$file\n"; |
| 207 | } |
| 208 | } |
| 209 | } elsif($cmd eq "mkiso") { |
| 210 | readimage $image; |
| 211 | open(ISO, "|-", "mkisofs", "-J", "-R", "-V", "$imgname r$rev", "-graft-points", "-path-list", "-") || die "mkisofs: $!"; |
| 212 | for $gf (sort keys %img) { |
| 213 | print ISO ($gf . "=" . $img{$gf} . "\n"); |
| 214 | } |
| 215 | close ISO; |
| 216 | if(!$justburned) { |
| 217 | $rev++; |
| 218 | $justburned = 1; |
| 219 | } |
| 220 | writeimage $image; |
| 221 | } else { |
| 222 | print STDERR "cdtool: unknown command: $cmd\n"; |
| 223 | exit 1; |
| 224 | } |
| 225 | |
| 226 | die if(!open CF, ">" . $ENV{"HOME"} . "/.cdtool"); |
| 227 | if(defined $curgraft) { |
| 228 | print CF "gp $curgraft\n"; |
| 229 | } |
| 230 | if(defined $curimage) { |
| 231 | print CF "img $curimage\n"; |
| 232 | } |
| 233 | close CF; |