6 # alias cvsfiles='cvsutil --files --print'
7 # alias cvsignores='cvsutil --ignores --print'
8 # alias cvsignoresall='cvsutil --ignores --workings --print'
9 # alias cvsignoresrm='cvsutil --ignores --rm'
10 # alias cvsignoresrmall='cvsutil --ignores --workings --rm'
11 # alias cvsignoresallrm='cvsutil --ignores --workings --rm'
17 use Cwd qw(chdir fastgetcwd);
19 use Carp qw(confess cluck croak carp);
21 if (!eval q{ use File::Remove qw(remove); 1; }) {{
25 if ("SCALAR" eq ref $_[0]) {
29 my $cmd="rm -f $r ".join(" ",map({s/'/'\\''/g;"'$_'";} @_));
30 my $err=system($cmd) and confess("$cmd: $cmd");
36 use constant ENTRIES =>"CVS/Entries";
37 use constant CVSIGNORE=>".cvsignore";
38 use constant ROOT =>"CVS/Root";
40 my($opt_files,$opt_ignores,$opt_workings,$opt_dirs);
41 my($opt_rm,$opt_print);
42 our($opt_root); # undefined=>no rooting, ""=>print roots or first phase for root checking, ne ""=>set roots
43 my($opt_verbose,$opt_fatal);
44 my($opt_force); # set roots without their checking
47 $Getopt::Long::ignorecase=0;
48 $Getopt::Long::bundling=1;
49 die if !GetOptions_shortfilter(
50 "f|files!" ,\$opt_files,
51 "i|ignores!" ,\$opt_ignores,
52 "w|workings!",\$opt_workings,
53 "d|dirs!" ,\$opt_dirs,
55 "p|print!" ,\$opt_print,
57 "v|verbose!" ,\$opt_verbose,
58 "fatal!" ,\$opt_fatal,
59 "force!" ,\$opt_force,
60 "I|ignore=s" ,\@opt_ignore,
63 die "--root possible only with (optional and ignored) -d|--dirs"
64 if defined $opt_root && ($opt_files || $opt_ignores || $opt_workings || $opt_dirs || $opt_rm || $opt_print);
65 die "-d|--dirs forbidden with -r|--rm"
66 if $opt_dirs && $opt_rm;
67 die "Nothing to do (no -r|--rm, no -p|--print)"
68 if !$opt_rm && !$opt_print && !defined $opt_root;
69 die "Nothing to process (no -f|--files, no -i|--ignores, no -w|--workings, no -d|--dirs)"
70 if !defined $opt_root && (!$opt_files && !$opt_ignores && !$opt_workings && !$opt_dirs);
72 my @all_ignore=("CVS");
75 @all_ignore=() if $_ eq "!";
78 my($root_contents,@root_dirs);
80 @ARGV=(".") if !@ARGV;
82 our(@dir_files,@dir_ignores,@dir_workings,@dir_victims);
84 unless ((defined $opt_root && $opt_root ne "") && $opt_force) {
85 local($opt_root)=$opt_root;
86 $opt_root="" if defined $opt_root && $opt_root ne "";
90 actionrootfinal() if defined $opt_root && $opt_root eq "";
91 if (defined $opt_root && $opt_root ne "") {
92 die "Non-matching \"".ROOT."\" contents, use --force for override" if !@root_dirs && !$opt_force;
103 $msg.=" in \"".fastgetcwd."\" (CVS \"$dir_dirname\")".($opts{"noerrno"} ? "" : ": $errstr");
104 croak $msg if $opt_fatal;
112 my $origdir=fastgetcwd;
115 mayfatal "Unable to process directory \"$_\"";
125 my($localdirname)=@_;
127 verbose("localdir(\"$localdirname\") entry");
129 local(@dir_dirs,@dir_files,@dir_ignores,@dir_workings,@dir_victims);
130 local($dir_dirname)=$dir_dirname.$localdirname."/";
132 localreaddir() or return;
136 verbose("localdir(\"$localdirname\") exit");
141 localvictims() if !defined $opt_root;
144 fordirs \&localdir,@dir_dirs;
151 my %hash=map { $_=>1; } @$from;
161 if (!open E,ENTRIES) {
162 mayfatal "File \"".ENTRIES."\" cannot be opened";
168 do { push @dir_dirs ,$1; next; } if m#^D/([^/]*)/#;
169 next if m#^/[^/]*/-#; # deleted file: /filename/-1.1/dummy timestamp//
170 next if m#^/[^/]*/0/#; # new file: /filename/0/dummy timestamp//
171 do { push @dir_files,$1; next; } if m#^/([^/]*)/# ;
172 mayfatal "File ".ENTRIES." contains invalid line \"$_\"",("noerrno"=>1);
176 return 1 if defined $opt_root;
179 if (open I,CVSIGNORE) {
183 push @dir_ignores,$_ if -e $_;
188 @dir_ignores=filterout \@dir_ignores,@dir_dirs,@dir_files;
191 mayfatal "File \"".CVSIGNORE."\" cannot be opened" if !$!{ENOENT};
195 if (!opendir D,".") {
196 mayfatal "Cannot read directory \".\"";
199 @dir_workings=filterout [readdir D],@dir_dirs,@dir_files,@dir_ignores,@all_ignore,".","..";
206 push @dir_victims,@dir_files if $opt_files;
207 push @dir_victims,@dir_ignores if $opt_ignores;
208 push @dir_victims,@dir_workings if $opt_workings;
209 push @dir_victims,@dir_dirs if $opt_dirs;
216 mayfatal "File \"$filename\" does not exist",("noerrno"=>1) if !-e $filename;
217 print "${dir_dirname}$filename\n";
224 chmod 0700,$filename or do {
225 mayfatal "File \"$_\" cannot be chmod(2)ed" if !$!{ENOENT};
228 remove \1,$filename or do {
229 mayfatal "File \"$_\" cannot be removed" if !$!{ENOENT};
233 sub localactionrootset
236 if (!open R,'+<',ROOT) {
237 mayfatal "File \"".ROOT."\" cannot be written";
240 print R "$opt_root\n";
245 sub localactionrootprint
249 mayfatal "File \"".ROOT."\" cannot be opened";
253 localactionrootprintcheck(<R>);
257 sub localactionrootprintcheck
261 if (!defined $root_contents) {
262 push @root_dirs,$dir_dirname;
263 $root_contents=$contents;
266 if (@root_dirs && $root_contents eq $contents) {
267 push @root_dirs,$dir_dirname;
271 print map "$_: $root_contents",@root_dirs;
274 print "$dir_dirname: $contents";
279 return if !@root_dirs;
280 print $root_contents;
285 if ("" ne $dir_dirname && defined $opt_root) {
286 localactionrootset() if defined $opt_root && "" ne $opt_root;
287 localactionrootprint() if defined $opt_root && "" eq $opt_root;
291 localactionprint $_ if $opt_print;
292 localactionrm $_ if $opt_rm;
300 return if !$opt_verbose;
301 print fastgetcwd.": $msg\n";
304 sub GetOptions_shortfilter
310 push @r,$1,$ref,$',$ref;
315 return GetOptions @r;