Added gpvi.
[utils.git] / cdtool
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;