#!/usr/bin/perl -w if(($#ARGV < 0) || ($ARGV[0] eq "help")) { print STDERR "usage:\n"; print STDERR "\tcdtool add {FILES|-g GRAFTPOINT}...\n"; print STDERR "\tcdtool ls\n"; print STDERR "\tcdtool rm NAME\n"; print STDERR "\tcdtool szck\n"; print STDERR "\tcdtool setgp [GRAFTPOINT]\n"; print STDERR "\tcdtool setimg [IMAGE]\n"; print STDERR "\tcdtool mkiso\n"; exit 1; } if(-r $ENV{"HOME"} . "/.cdtool") { if(open CF, $ENV{"HOME"} . "/.cdtool") { while() { next if /^\#/; if(/^(\S+)\s+(.*)$/) { if($1 eq "gp") { $curgraft = $2; } elsif($1 eq "img") { $curimage = $2; } else { print STDERR "cdtool: warning: unknown .cdtool directive: $1\n"; } } } close CF; } } sub canonpath { my($path) = @_; $path = "./" . $path unless $path =~ m,^/,; $path =~ s,/$,,; $trailer = ""; while(!-d $path) { $path =~ s,/+([^/]*)$,,; $trailer .= "/" . $1; if($path eq "") { die "weird path given: $_[0]"; } } if(!open CHILD, "-|") { chdir $path; exec "pwd"; die; } chomp($cpath = ); close CHILD; return "$cpath$trailer"; } sub dirname { my($path) = @_; $path =~ s,/[^/]+/*$,,; return $path; } sub addfile { my($file, $graft) = @_; my($dir, $f, $basename); $basename = $file; $basename =~ s,^.*/,,; if(-f $file) { print "add $file to $graft\n" if $verbose; $img{"$graft$basename"} = $file; } elsif(-d $file) { $dir = canonpath $file; if(opendir DIR, "$dir") { for $f (sort grep !/^\./, readdir DIR) { addfile("$dir/$f", "$graft$basename/"); } closedir DIR; } else { print STDERR "cdtool: could not open $file for listing: $!\n"; } } else { print STDERR "cdtool: $file: not a regular file or directory\n"; } } sub readimage { my($file, $dieonerr) = @_; $dieonerr = 1 unless defined $dieonerr; if(!open(IMG, "<", $file)) { if($dieonerr) { die "$file: $!"; } else { return; } } while() { if(/^file (.*):::(.*)$/) { $img{$1} = $2; } elsif(/^name (.*)$/) { $imgname = $1; } elsif(/^rev (\d+)$/) { $rev = $1; } elsif(/^justburned/) { $justburned = 1; } } close IMG; } sub writeimage { my($file) = @_; open(IMG, ">", $file) || die "$file: $!"; print IMG "rev $rev\n"; print IMG "justburned\n" if $justburned; for $f (sort keys %img) { print IMG ("file " . $f . ":::" . $img{$f} . "\n"); } close IMG; } $image = $curimage; $imgname = $image; $justburned = 0; $imgname =~ s,^.*/,,; $rev = 1; $verbose = 0; while(($arg = shift @ARGV) =~ /^-(.+)/) { $opts = $1; while($opts =~ s/^(.)//) { if($1 eq "v") { $verbose = 1; } } } $cmd = $arg; if($cmd eq "add") { if(!defined $image) { print STDERR "cdtool: no image defined for adding\n"; exit 1; } readimage $image, 0; $justburned = 0; $graft = $curgraft; $graft .= "/" unless $graft eq ""; while(defined($arg = shift @ARGV)) { if($arg eq "-g") { $graft = shift @ARGV; $graft =~ s,/+$,,; $graft .= "/" unless $graft eq ""; } else { if(!defined $graft) { print STDERR "cdtool: no graft point defined when adding\n"; exit 1; } addfile canonpath($arg), $graft } } writeimage $image; } elsif($cmd eq "ls") { readimage $image; for $gf (sort keys %img) { print "$gf\n"; } } elsif($cmd eq "rm") { die "no name specified" unless defined($file = shift @ARGV); $file = canonpath $file; readimage $image; $found = 0; if(-d $file) { $file .= "/"; for $gname (grep substr($img{$_}, 0, length $file) eq $file, keys %img) { delete $img{$gname}; $found = 1; } } else { for $gname (grep $img{$_} eq $file, keys %img) { delete $img{$gname}; $found = 1; } } if(!$found) { print STDERR "cdtool: $file not found in image\n"; exit 1; } $justburned = 0; writeimage $image; } elsif($cmd eq "szck") { readimage $image; $size = 0; for $file (values %img) { $size += -s $file; } $size =~ s/(\d{3})/$1,/g; $size =~ s/,$//; print "$size\n"; } elsif($cmd eq "setgp") { $curgraft = shift @ARGV; $curgraft =~ s,/+$,,; } elsif($cmd eq "setimg") { $curimage = shift @ARGV; } elsif($cmd eq "imgck") { readimage $image; for $file (values %img) { if(! -r $file) { print "$file\n"; } } } elsif($cmd eq "mkiso") { readimage $image; open(ISO, "|-", "mkisofs", "-J", "-R", "-V", "$imgname r$rev", "-graft-points", "-path-list", "-") || die "mkisofs: $!"; for $gf (sort keys %img) { print ISO ($gf . "=" . $img{$gf} . "\n"); } close ISO; if(!$justburned) { $rev++; $justburned = 1; } writeimage $image; } else { print STDERR "cdtool: unknown command: $cmd\n"; exit 1; } die if(!open CF, ">" . $ENV{"HOME"} . "/.cdtool"); if(defined $curgraft) { print CF "gp $curgraft\n"; } if(defined $curimage) { print CF "img $curimage\n"; } close CF;