juha@ttds.tds.kth.se (Juha Sarlin) (09/13/90)
Larry Wall's dodir doesn't work exactly like the unix-command find:
- You always have to start in '.' and cannot give a list of files;
this could be fixed with something like:
chop($cwd = `pwd`);
grep(chdir $_ && (&dodir($_), chdir $cwd), @files);
- It always skips the starting directory. Eg, &dodir('.') doesn't
print '.'.
Here is dofiles, a modified version of dodir that fixes these problems
and also makes errors in chdir and opendir non-fatal:
#!/usr/local/bin/perl
# Recursive directory walker.
# Prints all pathnames given on the command line. If any of them
# are directories their contents are printed recursively.
# This is like: find ${*-.} -print
unshift(@ARGV, '.') if $#ARGV < $[;
&dofiles('', 0, @ARGV);
sub dofiles {
local($dir,$nlink,@filenames) = @_;
local($dev,$ino,$mode);
if ($nlink == 2) { # this dir has no subdirectories
for (@filenames) {
$name = $dir.$_;
print $name,"\n";
}
}
else { # this dir has subdirectories
local($back) = '..';
chop($back = `pwd`) unless $nlink; # first time
for (@filenames) {
$name = $dir.$_;
print $name,"\n";
if (($dev,$ino,$mode,$nlink) = lstat($_)) {
next unless -d _;
if (chdir $_) {
if (opendir(DIR,'.')) {
(readdir(DIR) =~ /^\.$/ && readdir(DIR) =~ /^\.\.$/)
|| die "Directory $name doesn't start with . and ..";
$name .= '/' unless /\/$/;
&dofiles($name, $nlink, readdir(DIR));
}
else {
print STDERR "Can't open $name: $!\n";
}
chdir $back;
}
else {
print STDERR "Can't cd to $name: $!\n";
}
}
else {
print STDERR "$name: $!\n";
}
}
}
}
--
Juha Sarlin juha@tds.kth.se