--- /dev/null
+#!/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(<CF>) {
+ 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 = <CHILD>);
+ 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(<IMG>) {
+ 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 "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;