# In this section, perl variables will be expanded during extraction.
# You can use $Config{...} to use Configure variables.
+my $versiononly = $Config{versiononly} ? $Config{version} : '';
+
print OUT <<"!GROK!THIS!";
$Config{startperl}
eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
# make sure creat()s are neither too much nor too little
INIT { eval { umask(0077) } } # doubtless someone has no mask
+(my \$pager = <<'/../') =~ s/\\s*\\z//;
+$Config{pager}
+/../
my \@pagers = ();
-push \@pagers, "$Config{'pager'}" if -x "$Config{'pager'}";
+push \@pagers, \$pager if -x \$pager;
+
+(my \$bindir = <<'/../') =~ s/\\s*\\z//;
+$Config{scriptdirexp}
+/../
+
+(my \$pod2man = <<'/../') =~ s/\\s*\\z//;
+pod2man$versiononly
+/../
!GROK!THIS!
use Fcntl; # for sysopen
use Getopt::Std;
use Config '%Config';
+use File::Spec::Functions qw(catfile splitdir);
#
# Perldoc revision #1 -- look up a piece of documentation in .pod format that
my $Is_VMS = $^O eq 'VMS';
my $Is_MSWin32 = $^O eq 'MSWin32';
my $Is_Dos = $^O eq 'dos';
+my $Is_OS2 = $^O eq 'os2';
sub usage{
warn "@_\n" if @_;
# refuse to run if we should be tainting and aren't
# (but regular users deserve protection too, though!)
-if (!($Is_VMS || $Is_MSWin32 || $Is_Dos) && ($> == 0 || $< == 0)
+if (!($Is_VMS || $Is_MSWin32 || $Is_Dos || $Is_OS2) && ($> == 0 || $< == 0)
&& !am_taint_checking())
{{
if ($opt_U) {
my $id = eval { getpwnam("nobody") };
$id = eval { getpwnam("nouser") } unless defined $id;
$id = -2 unless defined $id;
+ #
+ # According to Stevens' APUE and various
+ # (BSD, Solaris, HP-UX) man pages setting
+ # the real uid first and effective uid second
+ # is the way to go if one wants to drop privileges,
+ # because if one changes into an effective uid of
+ # non-zero, one cannot change the real uid any more.
+ #
+ # Actually, it gets even messier. There is
+ # a third uid, called the saved uid, and as
+ # long as that is zero, one can get back to
+ # uid of zero. Setting the real-effective *twice*
+ # helps in *most* systems (FreeBSD and Solaris)
+ # but apparently in HP-UX even this doesn't help:
+ # the saved uid stays zero (apparently the only way
+ # in HP-UX to change saved uid is to call setuid()
+ # when the effective uid is zero).
+ #
eval {
- $> = $id; # must do this one first!
- $< = $id;
+ $< = $id; # real uid
+ $> = $id; # effective uid
+ $< = $id; # real uid
+ $> = $id; # effective uid
};
last if !$@ && $< && $>;
}
eval q{ use lib qw(. lib); 1; } or die;
# don't add if superuser
- if ($< && $>) { # don't be looking too hard now!
- eval q{ use blib; 1 } or die;
+ if ($< && $> && -f "blib") { # don't be looking too hard now!
+ eval q{ use blib; 1 };
+ warn $@ if $@ && $opt_v;
}
}
sub minus_f_nocase {
my($dir,$file) = @_;
- my $path = join('/',$dir,$file); # XXX: dirseps
+ my $path = catfile($dir,$file);
return $path if -f $path and -r _;
if (!$opt_i or $Is_VMS or $Is_MSWin32 or $Is_Dos or $^O eq 'os2') {
# on a case-forgiving file system or if case is important
local($")="/";
my @p = ($dir);
my($p,$cip);
- foreach $p (split(m!/!, $file)){ # XXX: dirseps
- my $try = "@p/$p";
+ foreach $p (splitdir $file){
+ my $try = catfile @p, $p;
stat $try;
if (-d _) {
push @p, $p;
if ( $p eq $global_target) {
- my $tmp_path = join ('/', @p); # XXX: dirseps
+ my $tmp_path = catfile @p;
my $path_f = 0;
for (@global_found) {
$path_f = 1 if $_ eq $tmp_path;
my $ret;
my $i;
my $dir;
- $global_target = (split(m!/!, $s))[-1]; # XXX: dirseps
+ $global_target = (splitdir $s)[-1]; # XXX: why not use File::Basename?
for ($i=0; $i<@dirs; $i++) {
$dir = $dirs[$i];
($dir = VMS::Filespec::unixpath($dir)) =~ s!/\z!! if $Is_VMS;
- if ( ( $ret = check_file $dir,"$s.pod")
+ if ( (! $opt_m && ( $ret = check_file $dir,"$s.pod"))
or ( $ret = check_file $dir,"$s.pm")
or ( $ret = check_file $dir,$s)
or ( $Is_VMS and
if ($recurse) {
opendir(D,$dir) or die "Can't opendir $dir: $!";
- my @newdirs = map "$dir/$_", grep { # XXX: dirseps
+ my @newdirs = map catfile($dir, $_), grep {
not /^\.\.?\z/s and
not /^auto\z/s and # save time! don't search auto dirs
- -d "$dir/$_" # XXX: dirseps
+ -d catfile($dir, $_)
} readdir D;
closedir(D) or die "Can't closedir $dir: $!";
next unless @newdirs;
join "\n\n", @data;
}
-sub printout {
- my ($file, $tmp, $filter) = @_;
- my $err;
-
- if ($opt_t) {
- # why was this append?
- sysopen(OUT, $tmp, O_WRONLY | O_EXCL | O_CREAT, 0600)
- or die ("Can't open $tmp: $!");
- Pod::Text->new()->parse_from_file($file,\*OUT);
- close OUT or die "can't close $tmp: $!";
- }
- elsif (not $opt_u) {
- my $cmd = "pod2man --lax $file | $opt_n -man";
- $cmd .= " | col -x" if $^O =~ /hpux/;
- my $rslt = `$cmd`;
- $rslt = filter_nroff($rslt) if $filter;
- unless (($err = $?)) {
- # why was this append?
- sysopen(TMP, $tmp, O_WRONLY | O_EXCL | O_CREAT, 0600)
- or die "Can't open $tmp: $!";
- print TMP $rslt
- or die "Can't print $tmp: $!";
- close TMP
- or die "Can't close $tmp: $!";
- }
- }
- if ($opt_u or $err or -z $tmp) { # XXX: race with -z
- # why was this append?
- sysopen(OUT, $tmp, O_WRONLY | O_EXCL | O_CREAT, 0600)
- or die "Can't open $tmp: $!";
- open(IN,"<", $file) or die("Can't open $file: $!");
- my $cut = 1;
- local $_;
- while (<IN>) {
- $cut = $1 eq 'cut' if /^=(\w+)/;
- next if $cut;
- print OUT
- or die "Can't print $tmp: $!";
- }
- close IN or die "Can't close $file: $!";
- close OUT or die "Can't close $tmp: $!";
- }
-}
-
sub page {
my ($tmp, $no_tty, @pagers) = @_;
if ($no_tty) {
close TMP or die "Can't close while $tmp: $!";
}
else {
- foreach my $pager (@pagers) {
- last if system("$pager $tmp") == 0;
+ # On VMS, quoting prevents logical expansion, and temp files with no
+ # extension get the wrong default extension (such as .LIS for TYPE)
+
+ $tmp = VMS::Filespec::rmsexpand($tmp, '.') if ($Is_VMS);
+ foreach my $pager (@pagers) {
+ if ($Is_VMS) {
+ last if system("$pager $tmp") == 0;
+ } else {
+ last if system("$pager \"$tmp\"") == 0;
+ }
}
}
}
-sub cleanup {
- my @files = @_;
- for (@files) {
- if ($Is_VMS) {
- 1 while unlink($_); # XXX: expect failure
- } else {
- unlink($_); # or die "Can't unlink $_: $!";
- }
- }
-}
-
my @found;
foreach (@pages) {
if ($podidx && open(PODIDX, $podidx)) {
- my $searchfor = $_;
- $searchfor =~ s,::,/,g; # XXX: dirseps
+ my $searchfor = catfile split '::';
print STDERR "Searching for '$searchfor' in $podidx\n" if $opt_v;
local $_;
while (<PODIDX>) {
next;
}
print STDERR "Searching for $_\n" if $opt_v;
- # We must look both in @INC for library modules and in PATH
- # for executables, like h2xs or perldoc itself.
- my @searchdirs = @INC;
if ($opt_F) {
next unless -r;
push @found, $_ if $opt_m or containspod($_);
next;
}
+ # We must look both in @INC for library modules and in $bindir
+ # for executables, like h2xs or perldoc itself.
+ my @searchdirs = ($bindir, @INC);
unless ($opt_m) {
if ($Is_VMS) {
my($i,$trn);
print STDERR "Loosely found as @files\n" if $opt_v;
}
else {
- print STDERR "No documentation found for \"$_\".\n";
+ print STDERR "No " .
+ ($opt_m ? "module" : "documentation") . " found for \"$_\".\n";
if (@global_found) {
print STDERR "However, try\n";
for my $dir (@global_found) {
if (! -t STDOUT) { $no_tty = 1 }
END { close(STDOUT) || die "Can't close STDOUT: $!" }
-# until here we could simply exit or die
-# now we create temporary files that we have to clean up
-# namely $tmp, $buffer
-# that's because you did it wrong, should be descriptor based --tchrist
-
-my $tmp;
-my $buffer;
if ($Is_MSWin32) {
- $tmp = "$ENV{TEMP}\\perldoc1.$$";
- $buffer = "$ENV{TEMP}\\perldoc1.b$$";
push @pagers, qw( more< less notepad );
unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
for (@found) { s,/,\\,g }
}
elsif ($Is_VMS) {
- $tmp = 'Sys$Scratch:perldoc.tmp1_'.$$;
- $buffer = 'Sys$Scratch:perldoc.tmp1_b'.$$;
push @pagers, qw( most more less type/page );
}
elsif ($Is_Dos) {
- $tmp = "$ENV{TEMP}/perldoc1.$$";
- $buffer = "$ENV{TEMP}/perldoc1.b$$";
- $tmp =~ tr!\\/!//!s;
- $buffer =~ tr!\\/!//!s;
push @pagers, qw( less.exe more.com< );
unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
}
else {
if ($^O eq 'os2') {
- require POSIX;
- $tmp = POSIX::tmpnam();
- $buffer = POSIX::tmpnam();
unshift @pagers, 'less', 'cmd /c more <';
}
- else {
- # XXX: this is not secure, because it doesn't open it
- ($tmp, $buffer) = eval { require POSIX }
- ? (POSIX::tmpnam(), POSIX::tmpnam() )
- : ("/tmp/perldoc1.$$", "/tmp/perldoc1.b$$" );
- }
push @pagers, qw( more less pg view cat );
unshift @pagers, $ENV{PAGER} if $ENV{PAGER};
}
unshift @pagers, $ENV{PERLDOC_PAGER} if $ENV{PERLDOC_PAGER};
-# make sure cleanup called
-eval q{
- sub END { cleanup($tmp, $buffer) }
- 1;
-} || die;
-eval q{ use sigtrap qw(die INT TERM HUP QUIT) };
-
if ($opt_m) {
foreach my $pager (@pagers) {
if (system($pager, @found) == 0) {
$found = 1;
push @pod, "=head1 Found in $ARGV\n\n" unless $found_in{$ARGV}++;
}
- elsif (/^=head2/) {
+ elsif (/^=head[12]/) {
$found = 0;
}
next unless $found;
}
}
+require File::Temp;
+
+my ($tmpfd, $tmp) = File::Temp::tempfile(UNLINK => 1);
+
my $filter;
if (@pod) {
- sysopen(TMP, $buffer, O_WRONLY | O_EXCL | O_CREAT)
- or die("Can't open $buffer: $!");
- print TMP "=over 8\n\n";
- print TMP @pod or die "Can't print $buffer: $!";
- print TMP "=back\n";
- close TMP or die "Can't close $buffer: $!";
+ my ($buffd, $buffer) = File::Temp::tempfile(UNLINK => 1);
+ print $buffd "=over 8\n\n";
+ print $buffd @pod or die "Can't print $buffer: $!";
+ print $buffd "=back\n";
+ close $buffd or die "Can't close $buffer: $!";
@found = $buffer;
$filter = 1;
}
foreach (@found) {
- printout($_, $tmp, $filter);
+ my $file = $_;
+ my $err;
+
+ if ($opt_t) {
+ Pod::Text->new()->parse_from_file($file, $tmpfd);
+ }
+ elsif (not $opt_u) {
+ my $cmd = catfile($bindir, $pod2man) . " --lax $file | $opt_n -man";
+ $cmd .= " | col -x" if $^O =~ /hpux/;
+ my $rslt = `$cmd`;
+ $rslt = filter_nroff($rslt) if $filter;
+ unless (($err = $?)) {
+ print $tmpfd $rslt
+ or die "Can't print $tmp: $!";
+ }
+ }
+ if ($opt_u or $err) {
+ open(IN,"<", $file) or die("Can't open $file: $!");
+ my $cut = 1;
+ local $_;
+ while (<IN>) {
+ $cut = $1 eq 'cut' if /^=(\w+)/;
+ next if $cut;
+ print $tmpfd $_
+ or die "Can't print $tmp: $!";
+ }
+ close IN or die "Can't close $file: $!";
+ }
}
+close $tmpfd
+ or die "Can't close $tmp: $!";
page($tmp, $no_tty, @pagers);
exit;
=item B<-X> use an index if present
-The B<-X> option looks for a entry whose basename matches the name given on the
+The B<-X> option looks for an entry whose basename matches the name given on the
command line in the file C<$Config{archlib}/pod.idx>. The pod.idx file should
contain fully qualified filenames, one per line.
have security issues, it will not normally execute as the superuser.
If you use the B<-U> flag, it will do so, but only after setting
the effective and real IDs to nobody's or nouser's account, or -2
-if unavailable. If it cannot relinguish its privileges, it will not
+if unavailable. If it cannot relinquish its privileges, it will not
run.
=item B<PageName|ModuleName|ProgramName>
=head1 VERSION
-This is perldoc v2.01.
+This is perldoc v2.03.
=head1 AUTHOR
=cut
#
+# Version 2.03: Sun Apr 23 16:56:34 BST 2000
+# Hugo van der Sanden <hv@crypt0.demon.co.uk>
+# don't die when 'use blib' fails
# Version 2.02: Mon Mar 13 18:03:04 MST 2000
# Tom Christiansen <tchrist@perl.com>
# Added -U insecurity option