use Config;
use Cwd;
# List explicitly here the variables you want Configure to
# generate. Metaconfig only looks for shell variables, so you
# have to mention them as if they were shell variables, not
# %Config entries. Thus you write
# $startperl
# to ensure Configure will look for $Config{startperl}.
# This forces PL files to create target in same directory as PL file.
# This is so that make depend always knows where to find PL derivatives.
chdir dirname($0);
print "Extracting $file (with variable substitutions)\n";
# In this section, perl variables will be expanded during extraction.
# You can use $Config{...} to use Configure variables.
print OUT <<"!GROK!THIS!";
eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
if \$running_under_some_shell;
(my \$perlpath = <<'/../') =~ s/\\s*\\z//;
/../
# In the following, perl variables are not expanded during extraction.
print OUT <<'!NO!SUBS!';
use strict;
use vars qw/$statdone/;
my $startperl = "#! $perlpath -w";
#
# Modified September 26, 1993 to provide proper handling of years after 1999
# Tom Link <tml+@pitt.edu>
# University of Pittsburgh
#
# Modified April 7, 1998 with nasty hacks to implement the troublesome -follow
# Billy Constantine <wdconsta@cs.adelaide.edu.au> <billy@smug.adelaide.edu.au>
# University of Adelaide, Adelaide, South Australia
#
# Modified 1999-06-10, 1999-07-07 to migrate to cleaner perl5 usage
# Ken Pizzini <ken@halcyon.com>
#
# Modified 2000-01-28 to use the 'follow' option of File::Find
sub tab ();
sub n ($$);
sub fileglob_to_re ($);
sub quote ($);
my @roots = ();
while ($ARGV[0] =~ /^[^-!(]/) {
push(@roots, shift);
}
my $find = "find";
my $indent_depth = 1;
my $stat = 'lstat';
my $decl = '';
my $flushall = '';
my $initfile = '';
my $initnewer = '';
my $out = '';
my $declaresubs = "sub wanted;\n";
my %init = ();
my $print_needed = 1;
while (@ARGV) {
$_ = shift;
s/^-// || /^[()!]/ || die "Unrecognized switch: $_\n";
if ($_ eq '(') {
$indent_depth++;
next;
} elsif ($_ eq ')') {
--$indent_depth;
} elsif ($_ eq 'follow') {
$follow_in_effect= 1;
$stat = 'stat';
$Skip_And= 1;
} elsif ($_ eq '!') {
next;
} elsif ($_ eq 'name') {
} elsif ($_ eq 'perm') {
my $onum = shift;
|| die "Malformed -perm argument: $onum\n";
if ($onum =~ s/^-//) {
$out .= "((\$mode & $onum) == $onum)";
} else {
$out .= "((\$mode & 0777) == $onum)";
}
} elsif ($_ eq 'type') {
(my $filetest = shift) =~ tr/s/S/;
} elsif ($_ eq 'print') {
$print_needed = 0;
} elsif ($_ eq 'print0') {
$print_needed = 0;
} elsif ($_ eq 'fstype') {
my $type = shift;
if ($type eq 'nfs') {
$out .= '($dev < 0)';
} else {
}
} elsif ($_ eq 'user') {
my $uname = shift;
} elsif ($_ eq 'group') {
my $gname = shift;
} elsif ($_ eq 'nouser') {
} elsif ($_ eq 'nogroup') {
} elsif ($_ eq 'links') {
} elsif ($_ eq 'inum') {
} elsif ($_ eq 'size') {
$_ = shift;
my $n = 'int(((-s _) + 511) / 512)';
if (s/c\z//) {
$n = 'int(-s _)';
} elsif (s/k\z//) {
$n = 'int(((-s _) + 1023) / 1024)';
}
} elsif ($_ eq 'atime') {
} elsif ($_ eq 'mtime') {
} elsif ($_ eq 'ctime') {
} elsif ($_ eq 'exec') {
my @cmd = ();
{ push(@cmd, shift) }
shift;
&& $cmd[$#cmd] eq '{}'
if (@cmd == 2) {
$out .= '(unlink($_) || warn "$name: $!\n")';
} elsif (!@ARGV) {
$out .= 'unlink($_)';
} else {
$out .= '(unlink($_) || 1)';
}
} else {
for (@cmd)
{ s/'/\\'/g }
$declaresubs .= "sub doexec (\$\@);\n";
}
$print_needed = 0;
} elsif ($_ eq 'ok') {
my @cmd = ();
{ push(@cmd, shift) }
shift;
for (@cmd)
{ s/'/\\'/g }
$declaresubs .= "sub doexec (\$\@);\n";
$print_needed = 0;
} elsif ($_ eq 'prune') {
} elsif ($_ eq 'xdev') {
;
} elsif ($_ eq 'newer') {
my $file = shift;
$newername =~ s/\W/_/g;
} elsif ($_ eq 'eval') {
my $prog = shift;
$prog =~ s/'/\\'/g;
} elsif ($_ eq 'depth') {
$find = 'finddepth';
next;
} elsif ($_ eq 'ls') {
$declaresubs .= "sub ls ();\n";
$print_needed = 0;
} elsif ($_ eq 'tar') {
die "-tar must have a filename argument\n" unless @ARGV;
my $file = shift;
$fh =~ s/\W/_/g;
$flushall .= "tflushall;\n";
$declaresubs .= "sub tar;\nsub tflushall ();\n";
qq{) || die "Can't open $fh: \$!\\n";\n};
} elsif (/^(n?)cpio\z/) {
die "-$_ must have a filename argument\n" unless @ARGV;
my $file = shift;
$fh =~ s/\W/_/g;
$find = 'finddepth';
$flushall .= "cflushall;\n";
$declaresubs .= "sub cpio;\nsub cflushall ();\n";
qq{) || die "Can't open $fh: \$!\\n";\n};
} else {
die "Unrecognized switch: -$_\n";
}
if (@ARGV) {
shift;
} else {
$out .= "\n";
}
}
}
if ($print_needed) {
}
print <<"END";
eval 'exec $perlpath -S \$0 \${1+"\$@"}'
if 0; #\$running_under_some_shell
use strict;
# Set the variable \$File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.
# for the convenience of &wanted calls, including -eval statements:
END
print <<'END';
use Cwd ();
END
}
print <<'END';
END
}
print "my (%uid, %user);\n";
print "while (my (\$name, \$pw, \$uid) = getpwent) {\n";
print ' $uid{$name} = $uid{$uid} = $uid;', "\n"
print ' $user{$uid} = $name unless exists $user{$uid};', "\n"
print "}\n\n";
}
print "my (%gid, %group);\n";
print "while (my (\$name, \$pw, \$gid) = getgrent) {\n";
print ' $gid{$name} = $gid{$gid} = $gid;', "\n"
print ' $group{$gid} = $name unless exists $group{$gid};', "\n"
print "}\n\n";
}
$flushall .= "exit;\n";
if (exists $init{declarestat}) {
END
}
if ( $follow_in_effect ) {
$out =~ s/lstat\(\$_\)/lstat(_)/;
print <<"END";
$decl
# Traverse desired filesystems
sub wanted {
$out;
}
END
} else {
print <<"END";
$decl
# Traverse desired filesystems
sub wanted {
$out;
}
END
}
print <<'END';
sub doexec ($@) {
my $ok = shift;
my @command = @_; # copy so we don't try to s/// aliases to constants
{ $word =~ s#{}#$name#g }
if ($ok) {
$| = 1;
print "@command";
select($old);
return 0 unless <STDIN> =~ /^y/;
}
chdir $cwd; #sigh
system @command;
return !$?;
}
END
}
print <<'INTRO', <<"SUB", <<'END';
sub sizemm {
my $rdev = shift;
}
sub ls () {
$mode >>= 3;
$mode >>= 3;
if (-M _ > 365.25 / 2) {
$timeyear += 1900;
} else {
}
printf "%5lu %4ld %-10s %3d %-8s %-8s %8s %s %2d %5s %s\n",
$ino,
$blocks,
$perms,
$nlink,
$user,
$group,
$size,
$mday,
$timeyear,
$pname;
1;
}
END
}
print <<'END';
my %blocks = ();
sub flush {
no strict qw/refs/;
}
}
END
}
print <<'INTRO', <<"SUB", <<'END';
my %cpout = ();
my %nc = ();
sub cpio {
my $text = '';
local (*IN);
if ( ! defined $fname ) {
$fname = 'TRAILER!!!';
} else {
if (-f _) {
open(IN, "./$_\0") || do {
warn "Couldn't open $fname: $!\n";
return;
}
} else {
$text = readlink($_);
}
}
$fname =~ s#^\./##;
if ($nc eq 'n') {
sprintf("%06o%06o%06o%06o%06o%06o%06o%06o%011lo%06o%011lo%s\0",
070707,
$dev & 0777777,
$ino & 0777777,
$mode & 0777777,
$uid & 0777777,
$gid & 0777777,
$nlink & 0777777,
$rdev & 0177777,
$mtime,
length($fname)+1,
$size,
$fname);
} else {
}
if ($text ne '') {
} elsif ($size) {
my $l;
}
close IN;
}
}
sub cflushall () {
}
}
END
}
print <<'INTRO', <<"SUB", <<'END';
my %tarout = ();
my %linkseen = ();
sub tar {
my $prefix = '';
my $typeflag = '0';
my $linkname;
local (*IN);
if ($nlink > 1) {
if (length($linkname) > 100) {
warn "$0: omitting file with linkname ",
"too long for tar output: $linkname\n";
return;
}
$typeflag = '1';
$size = 0;
} else {
}
}
if ($typeflag eq '0') {
if (-f _) {
open(IN, "./$_\0") || do {
warn "Couldn't open $fname: $!\n";
return;
}
} else {
$linkname = readlink($_);
elsif (-c _) { $typeflag = '3' }
elsif (-b _) { $typeflag = '4' }
elsif (-d _) { $typeflag = '5' }
elsif (-p _) { $typeflag = '6' }
}
}
if (length($fname) > 100) {
warn "$0: omitting file with name too long for tar output: ",
$fname, "\n";
return;
}
}
my $header = pack("a100a8a8a8a12a12a8a1a100a6a2a32a32a8a8a155",
$fname,
sprintf("%11o ", $size),
sprintf("%11o ", $mtime),
' 'x8,
$typeflag,
"ustar\0",
"00",
$rdev & 0xff,
$prefix,
);
my $l = length($header) % 512;
if ($size) {
}
close IN;
}
}
sub tflushall () {
my $len;
}
}
END
}
exit;
############################################################################
sub tab () {
my $tabstring;
if (!$statdone) {
} else {
my $statcall = '(($dev,$ino,$mode,$nlink,$uid,$gid) = '
. $stat . '($_))';
} else {
}
$statdone = 1;
}
}
}
sub fileglob_to_re ($) {
my $x = shift;
$x =~ s#([./^\$()+])#\\$1#g;
$x =~ s#([?*])#.$1#g;
"^$x\\z";
}
sub n ($$) {
my ($pre, $n) = @_;
$n =~ s/^-/< / || $n =~ s/^\+/> / || $n =~ s/^/== /;
$n =~ s/ 0*(\d)/ $1/;
"($pre $n)";
}
sub quote ($) {
my $string = shift;
$string =~ s/\\/\\\\/g;
$string =~ s/'/\\'/g;
"'$string'";
}
=head1 NAME
find2perl - translate find command lines to Perl code
=head1 SYNOPSIS
find2perl [paths] [predicates] | perl
=head1 DESCRIPTION
find2perl is a little translator to convert find command lines to
equivalent Perl code. The resulting code is typically faster than
running find itself.
"paths" are a set of paths where find2perl will start its searches and
"predicates" are taken from the following list.
=over 4
=item C<! PREDICATE>
Negate the sense of the following predicate. The C<!> must be passed as
quoted from interpretation by the shell using a backslash (just as with
using C<find(1)>).
=item C<( PREDICATES )>
Group the given PREDICATES. The parentheses must be passed as distinct
quoted from interpretation by the shell using a backslash (just as with
using C<find(1)>).
=item C<PREDICATE1 PREDICATE2>
True if _both_ PREDICATE1 and PREDICATE2 are true; PREDICATE2 is not
evaluated if PREDICATE1 is false.
=item C<PREDICATE1 -o PREDICATE2>
True if either one of PREDICATE1 or PREDICATE2 is true; PREDICATE2 is
not evaluated if PREDICATE1 is true.
=item C<-follow>
Follow (dereference) symlinks. The checking of file attributes depends
on the position of the C<-follow> option. If it precedes the file
check option, an C<stat> is done which means the file check applies to the
file the symbolic link is pointing to. If C<-follow> option follows the
file check option, this now applies to the symbolic link itself, i.e.
an C<lstat> is done.
=item C<-depth>
Change directory traversal algorithm from breadth-first to depth-first.
=item C<-prune>
Do not descend into the directory currently matched.
=item C<-xdev>
Do not traverse mount points (prunes search at mount-point directories).
=item C<-name GLOB>
File name matches specified GLOB wildcard pattern. GLOB may need to be
quoted to avoid interpretation by the shell (just as with using
C<find(1)>).
=item C<-perm PERM>
Low-order 9 bits of permission match octal value PERM.
=item C<-perm -PERM>
The bits specified in PERM are all set in file's permissions.
=item C<-type X>
The file's type matches perl's C<-X> operator.
=item C<-fstype TYPE>
is implemented).
=item C<-user USER>
True if USER is owner of file.
=item C<-group GROUP>
True if file's group is GROUP.
=item C<-nouser>
True if file's owner is not in password database.
=item C<-nogroup>
True if file's group is not in group database.
=item C<-inum INUM>
True file's inode number is INUM.
=item C<-links N>
True if (hard) link count of file matches N (see below).
=item C<-size N>
True if file's size matches N (see below) N is normally counted in
512-byte blocks, but a suffix of "c" specifies that size should be
counted in characters (bytes) and a suffix of "k" specifes that
size should be counted in 1024-byte blocks.
=item C<-atime N>
True if last-access time of file matches N (measured in days) (see
below).
=item C<-ctime N>
True if last-changed time of file's inode matches N (measured in days,
see below).
=item C<-mtime N>
True if last-modified time of file matches N (measured in days, see below).
=item C<-newer FILE>
True if last-modified time of file matches N.
=item C<-print>
Print out path of file (always true). If none of C<-exec>, C<-ls>,
C<-print0>, or C<-ok> is specified, then C<-print> will be added
implicitly.
=item C<-print0>
Like -print, but terminates with \0 instead of \n.
=item C<-exec OPTIONS ;>
exec() the arguments in OPTIONS in a subprocess; any occurrence of {} in
OPTIONS will first be substituted with the path of the current
file. Note that the command "rm" has been special-cased to use perl's
unlink() function instead (as an optimization). The C<;> must be passed as
quoted from interpretation by the shell using a backslash (just as with
using C<find(1)>).
=item C<-ok OPTIONS ;>
Like -exec, but first prompts user; if user's response does not begin
with a y, skip the exec. The C<;> must be passed as
quoted from interpretation by the shell using a backslash (just as with
using C<find(1)>).
=item C<-eval EXPR>
Has the perl script eval() the EXPR.
=item C<-ls>
Simulates C<-exec ls -dils {} ;>
=item C<-tar FILE>
Adds current output to tar-format FILE.
=item C<-cpio FILE>
Adds current output to old-style cpio-format FILE.
=item C<-ncpio FILE>
Adds current output to "new"-style cpio-format FILE.
=back
Predicates which take a numeric argument N can come in three forms:
* N is prefixed with a +: match values greater than N
* N is prefixed with a -: match values less than N
* N is not prefixed with either + or -: match only values equal to N
=head1 SEE ALSO
find
=cut
close OUT or die "Can't close $file: $!";
chdir $origdir;