1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
4 $VERSION = eval $VERSION;
12 use ExtUtils::MakeMaker (); # $SelfLoader::DEBUG=1;
13 use File::Basename ();
22 use Text::ParseWords ();
24 no lib "."; # we need to run chdir all over and we would get at wrong
27 require Mac::BuildTools if $^O eq 'MacOS';
29 END { $End++; &cleanup; }
52 $CPAN::Frontend ||= "CPAN::Shell";
53 $CPAN::Defaultsite ||= "ftp://ftp.perl.org/pub/CPAN";
54 $CPAN::Perl ||= CPAN::find_perl();
55 $CPAN::Defaultdocs ||= "http://search.cpan.org/perldoc?";
56 $CPAN::Defaultrecent ||= "http://search.cpan.org/recent";
62 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $HAS_USABLE $term
63 $Signal $End $Suppress_readline $Frontend
64 $Defaultsite $Have_warned $Defaultdocs $Defaultrecent
67 @CPAN::ISA = qw(CPAN::Debug Exporter);
70 autobundle bundle expand force notest get cvs_import
71 install make readme recompile shell test clean
75 #-> sub CPAN::AUTOLOAD ;
80 @EXPORT{@EXPORT} = '';
81 CPAN::Config->load unless $CPAN::Config_loaded++;
82 if (exists $EXPORT{$l}){
85 $CPAN::Frontend->mywarn(qq{Unknown CPAN command "$AUTOLOAD". }.
95 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
96 CPAN::Config->load unless $CPAN::Config_loaded++;
98 my $oprompt = shift || "cpan> ";
99 my $prompt = $oprompt;
100 my $commandline = shift || "";
103 unless ($Suppress_readline) {
104 require Term::ReadLine;
107 $term->ReadLine eq "Term::ReadLine::Stub"
109 $term = Term::ReadLine->new('CPAN Monitor');
111 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
112 my $attribs = $term->Attribs;
113 $attribs->{attempted_completion_function} = sub {
114 &CPAN::Complete::gnu_cpl;
117 $readline::rl_completion_function =
118 $readline::rl_completion_function = 'CPAN::Complete::cpl';
120 if (my $histfile = $CPAN::Config->{'histfile'}) {{
121 unless ($term->can("AddHistory")) {
122 $CPAN::Frontend->mywarn("Terminal does not support AddHistory.\n");
125 my($fh) = FileHandle->new;
126 open $fh, "<$histfile" or last;
130 $term->AddHistory($_);
134 # $term->OUT is autoflushed anyway
135 my $odef = select STDERR;
142 # no strict; # I do not recall why no strict was here (2000-09-03)
144 my $cwd = CPAN::anycwd();
145 my $try_detect_readline;
146 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
147 my $rl_avail = $Suppress_readline ? "suppressed" :
148 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
149 "available (try 'install Bundle::CPAN')";
151 $CPAN::Frontend->myprint(
153 cpan shell -- CPAN exploration and modules installation (v%s)
160 unless $CPAN::Config->{'inhibit_startup_message'} ;
161 my($continuation) = "";
162 SHELLCOMMAND: while () {
163 if ($Suppress_readline) {
165 last SHELLCOMMAND unless defined ($_ = <> );
168 last SHELLCOMMAND unless
169 defined ($_ = $term->readline($prompt, $commandline));
171 $_ = "$continuation$_" if $continuation;
173 next SHELLCOMMAND if /^$/;
174 $_ = 'h' if /^\s*\?/;
175 if (/^(?:q(?:uit)?|bye|exit)$/i) {
185 use vars qw($import_done);
186 CPAN->import(':DEFAULT') unless $import_done++;
187 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
194 if ($] < 5.00322) { # parsewords had a bug until recently
197 eval { @line = Text::ParseWords::shellwords($_) };
198 warn($@), next SHELLCOMMAND if $@;
199 warn("Text::Parsewords could not parse the line [$_]"),
200 next SHELLCOMMAND unless @line;
202 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
203 my $command = shift @line;
204 eval { CPAN::Shell->$command(@line) };
206 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
207 $CPAN::Frontend->myprint("\n");
212 $commandline = ""; # I do want to be able to pass a default to
213 # shell, but on the second command I see no
216 CPAN::Queue->nullify_queue;
217 if ($try_detect_readline) {
218 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
220 $CPAN::META->has_inst("Term::ReadLine::Perl")
222 delete $INC{"Term/ReadLine.pm"};
224 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
225 require Term::ReadLine;
226 $CPAN::Frontend->myprint("\n$redef subroutines in ".
227 "Term::ReadLine redefined\n");
233 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
236 package CPAN::CacheMgr;
237 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
240 package CPAN::Config;
241 use vars qw(%can %keys $dot_cpan);
244 'commit' => "Commit changes to disk",
245 'defaults' => "Reload defaults from disk",
246 'init' => "Interactive setting of all options",
249 %keys = map { $_ => undef } qw(
250 build_cache build_dir
251 cache_metadata cpan_home curl
255 histfile histsize http_proxy
256 inactivity_timeout index_expire inhibit_startup_message
259 make make_arg make_install_arg make_install_make_command makepl_arg
260 ncftp ncftpget no_proxy pager
262 scan_cache shell show_upload_date
269 use vars qw($Ua $Thesite $Themethod);
270 @CPAN::FTP::ISA = qw(CPAN::Debug);
272 package CPAN::LWP::UserAgent;
273 use vars qw(@ISA $USER $PASSWD $SETUPDONE);
274 # we delay requiring LWP::UserAgent and setting up inheritance until we need it
276 package CPAN::Complete;
277 @CPAN::Complete::ISA = qw(CPAN::Debug);
278 @CPAN::Complete::COMMANDS = sort qw(
279 ! a b d h i m o q r u autobundle clean dump
280 make test install force readme reload look
281 cvs_import ls perldoc recent
282 ) unless @CPAN::Complete::COMMANDS;
285 use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03);
286 @CPAN::Index::ISA = qw(CPAN::Debug);
289 # use constant PROTOCOL => "2.0"; # outcommented to avoid warning on upgrade from 1.57
292 package CPAN::InfoObj;
293 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
295 package CPAN::Author;
296 @CPAN::Author::ISA = qw(CPAN::InfoObj);
298 package CPAN::Distribution;
299 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
301 package CPAN::Bundle;
302 @CPAN::Bundle::ISA = qw(CPAN::Module);
304 package CPAN::Module;
305 @CPAN::Module::ISA = qw(CPAN::InfoObj);
307 package CPAN::Exception::RecursiveDependency;
308 use overload '""' => "as_string";
315 for my $dep (@$deps) {
317 last if $seen{$dep}++;
319 bless { deps => \@deps }, $class;
324 "\nRecursive dependency detected:\n " .
325 join("\n => ", @{$self->{deps}}) .
326 ".\nCannot continue.\n";
330 use vars qw($AUTOLOAD @ISA $COLOR_REGISTERED $ADVANCED_QUERY $PRINT_ORNAMENTING);
331 @CPAN::Shell::ISA = qw(CPAN::Debug);
332 $COLOR_REGISTERED ||= 0;
333 $PRINT_ORNAMENTING ||= 0;
335 #-> sub CPAN::Shell::AUTOLOAD ;
337 my($autoload) = $AUTOLOAD;
338 my $class = shift(@_);
339 # warn "autoload[$autoload] class[$class]";
340 $autoload =~ s/.*:://;
341 if ($autoload =~ /^w/) {
342 if ($CPAN::META->has_inst('CPAN::WAIT')) {
343 CPAN::WAIT->$autoload(@_);
345 $CPAN::Frontend->mywarn(qq{
346 Commands starting with "w" require CPAN::WAIT to be installed.
347 Please consider installing CPAN::WAIT to use the fulltext index.
348 For this you just need to type
353 $CPAN::Frontend->mywarn(qq{Unknown shell command '$autoload'. }.
359 package CPAN::Tarzip;
360 use vars qw($AUTOLOAD @ISA $BUGHUNTING);
361 @CPAN::Tarzip::ISA = qw(CPAN::Debug);
362 $BUGHUNTING = 0; # released code must have turned off
366 # One use of the queue is to determine if we should or shouldn't
367 # announce the availability of a new CPAN module
369 # Now we try to use it for dependency tracking. For that to happen
370 # we need to draw a dependency tree and do the leaves first. This can
371 # easily be reached by running CPAN.pm recursively, but we don't want
372 # to waste memory and run into deep recursion. So what we can do is
375 # CPAN::Queue is the package where the queue is maintained. Dependencies
376 # often have high priority and must be brought to the head of the queue,
377 # possibly by jumping the queue if they are already there. My first code
378 # attempt tried to be extremely correct. Whenever a module needed
379 # immediate treatment, I either unshifted it to the front of the queue,
380 # or, if it was already in the queue, I spliced and let it bypass the
381 # others. This became a too correct model that made it impossible to put
382 # an item more than once into the queue. Why would you need that? Well,
383 # you need temporary duplicates as the manager of the queue is a loop
386 # (1) looks at the first item in the queue without shifting it off
388 # (2) cares for the item
390 # (3) removes the item from the queue, *even if its agenda failed and
391 # even if the item isn't the first in the queue anymore* (that way
392 # protecting against never ending queues)
394 # So if an item has prerequisites, the installation fails now, but we
395 # want to retry later. That's easy if we have it twice in the queue.
397 # I also expect insane dependency situations where an item gets more
398 # than two lives in the queue. Simplest example is triggered by 'install
399 # Foo Foo Foo'. People make this kind of mistakes and I don't want to
400 # get in the way. I wanted the queue manager to be a dumb servant, not
401 # one that knows everything.
403 # Who would I tell in this model that the user wants to be asked before
404 # processing? I can't attach that information to the module object,
405 # because not modules are installed but distributions. So I'd have to
406 # tell the distribution object that it should ask the user before
407 # processing. Where would the question be triggered then? Most probably
408 # in CPAN::Distribution::rematein.
409 # Hope that makes sense, my head is a bit off:-) -- AK
416 my $self = bless { qmod => $s }, $class;
421 # CPAN::Queue::first ;
427 # CPAN::Queue::delete_first ;
429 my($class,$what) = @_;
431 for my $i (0..$#All) {
432 if ( $All[$i]->{qmod} eq $what ) {
439 # CPAN::Queue::jumpqueue ;
443 CPAN->debug(sprintf("before jumpqueue All[%s] what[%s]",
444 join(",",map {$_->{qmod}} @All),
447 WHAT: for my $what (reverse @what) {
449 for (my $i=0; $i<$#All;$i++) { #prevent deep recursion
450 CPAN->debug("i[$All[$i]]what[$what]") if $CPAN::DEBUG;
451 if ($All[$i]->{qmod} eq $what){
453 if ($jumped > 100) { # one's OK if e.g. just
454 # processing now; more are OK if
455 # user typed it several times
456 $CPAN::Frontend->mywarn(
457 qq{Object [$what] queued more than 100 times, ignoring}
463 my $obj = bless { qmod => $what }, $class;
466 CPAN->debug(sprintf("after jumpqueue All[%s] what[%s]",
467 join(",",map {$_->{qmod}} @All),
472 # CPAN::Queue::exists ;
474 my($self,$what) = @_;
475 my @all = map { $_->{qmod} } @All;
476 my $exists = grep { $_->{qmod} eq $what } @All;
477 # warn "in exists what[$what] all[@all] exists[$exists]";
481 # CPAN::Queue::delete ;
484 @All = grep { $_->{qmod} ne $mod } @All;
487 # CPAN::Queue::nullify_queue ;
496 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
498 # from here on only subs.
499 ################################################################################
501 #-> sub CPAN::all_objects ;
503 my($mgr,$class) = @_;
504 CPAN::Config->load unless $CPAN::Config_loaded++;
505 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
507 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
509 *all = \&all_objects;
511 # Called by shell, not in batch mode. In batch mode I see no risk in
512 # having many processes updating something as installations are
513 # continually checked at runtime. In shell mode I suspect it is
514 # unintentional to open more than one shell at a time
516 #-> sub CPAN::checklock ;
519 my $lockfile = File::Spec->catfile($CPAN::Config->{cpan_home},".lock");
520 if (-f $lockfile && -M _ > 0) {
521 my $fh = FileHandle->new($lockfile) or
522 $CPAN::Frontend->mydie("Could not open $lockfile: $!");
523 my $otherpid = <$fh>;
524 my $otherhost = <$fh>;
526 if (defined $otherpid && $otherpid) {
529 if (defined $otherhost && $otherhost) {
532 my $thishost = hostname();
533 if (defined $otherhost && defined $thishost &&
534 $otherhost ne '' && $thishost ne '' &&
535 $otherhost ne $thishost) {
536 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile $lockfile\n".
537 "reports other host $otherhost and other process $otherpid.\n".
538 "Cannot proceed.\n"));
540 elsif (defined $otherpid && $otherpid) {
541 return if $$ == $otherpid; # should never happen
542 $CPAN::Frontend->mywarn(
544 There seems to be running another CPAN process (pid $otherpid). Contacting...
546 if (kill 0, $otherpid) {
547 $CPAN::Frontend->mydie(qq{Other job is running.
548 You may want to kill it and delete the lockfile, maybe. On UNIX try:
552 } elsif (-w $lockfile) {
554 ExtUtils::MakeMaker::prompt
555 (qq{Other job not responding. Shall I overwrite }.
556 qq{the lockfile? (Y/N)},"y");
557 $CPAN::Frontend->myexit("Ok, bye\n")
558 unless $ans =~ /^y/i;
561 qq{Lockfile $lockfile not writeable by you. }.
562 qq{Cannot proceed.\n}.
565 qq{ and then rerun us.\n}
569 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile $lockfile\n".
570 "reports other process with ID ".
571 "$otherpid. Cannot proceed.\n"));
574 my $dotcpan = $CPAN::Config->{cpan_home};
575 eval { File::Path::mkpath($dotcpan);};
577 # A special case at least for Jarkko.
582 $symlinkcpan = readlink $dotcpan;
583 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
584 eval { File::Path::mkpath($symlinkcpan); };
588 $CPAN::Frontend->mywarn(qq{
589 Working directory $symlinkcpan created.
593 unless (-d $dotcpan) {
595 Your configuration suggests "$dotcpan" as your
596 CPAN.pm working directory. I could not create this directory due
597 to this error: $firsterror\n};
599 As "$dotcpan" is a symlink to "$symlinkcpan",
600 I tried to create that, but I failed with this error: $seconderror
603 Please make sure the directory exists and is writable.
605 $CPAN::Frontend->mydie($diemess);
609 unless ($fh = FileHandle->new(">$lockfile")) {
610 if ($! =~ /Permission/) {
611 my $incc = $INC{'CPAN/Config.pm'};
612 my $myincc = File::Spec->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
613 $CPAN::Frontend->myprint(qq{
615 Your configuration suggests that CPAN.pm should use a working
617 $CPAN::Config->{cpan_home}
618 Unfortunately we could not create the lock file
620 due to permission problems.
622 Please make sure that the configuration variable
623 \$CPAN::Config->{cpan_home}
624 points to a directory where you can write a .lock file. You can set
625 this variable in either
632 $CPAN::Frontend->mydie("Could not open >$lockfile: $!");
634 $fh->print($$, "\n");
635 $fh->print(hostname(), "\n");
636 $self->{LOCK} = $lockfile;
640 $CPAN::Frontend->mydie("Got SIGTERM, leaving");
645 $CPAN::Frontend->mydie("Got another SIGINT") if $Signal;
646 print "Caught SIGINT\n";
650 # From: Larry Wall <larry@wall.org>
651 # Subject: Re: deprecating SIGDIE
652 # To: perl5-porters@perl.org
653 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
655 # The original intent of __DIE__ was only to allow you to substitute one
656 # kind of death for another on an application-wide basis without respect
657 # to whether you were in an eval or not. As a global backstop, it should
658 # not be used any more lightly (or any more heavily :-) than class
659 # UNIVERSAL. Any attempt to build a general exception model on it should
660 # be politely squashed. Any bug that causes every eval {} to have to be
661 # modified should be not so politely squashed.
663 # Those are my current opinions. It is also my optinion that polite
664 # arguments degenerate to personal arguments far too frequently, and that
665 # when they do, it's because both people wanted it to, or at least didn't
666 # sufficiently want it not to.
670 # global backstop to cleanup if we should really die
671 $SIG{__DIE__} = \&cleanup;
672 $self->debug("Signal handler set.") if $CPAN::DEBUG;
675 #-> sub CPAN::DESTROY ;
677 &cleanup; # need an eval?
680 #-> sub CPAN::anycwd ;
683 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
688 sub cwd {Cwd::cwd();}
690 #-> sub CPAN::getcwd ;
691 sub getcwd {Cwd::getcwd();}
693 #-> sub CPAN::find_perl ;
695 my($perl) = File::Spec->file_name_is_absolute($^X) ? $^X : "";
696 my $pwd = CPAN::anycwd();
697 my $candidate = File::Spec->catfile($pwd,$^X);
698 $perl ||= $candidate if MM->maybe_command($candidate);
701 my ($component,$perl_name);
702 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
703 PATH_COMPONENT: foreach $component (File::Spec->path(),
704 $Config::Config{'binexp'}) {
705 next unless defined($component) && $component;
706 my($abs) = File::Spec->catfile($component,$perl_name);
707 if (MM->maybe_command($abs)) {
719 #-> sub CPAN::exists ;
721 my($mgr,$class,$id) = @_;
722 CPAN::Config->load unless $CPAN::Config_loaded++;
724 ### Carp::croak "exists called without class argument" unless $class;
726 exists $META->{readonly}{$class}{$id} or
727 exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
730 #-> sub CPAN::delete ;
732 my($mgr,$class,$id) = @_;
733 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
734 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
737 #-> sub CPAN::has_usable
738 # has_inst is sometimes too optimistic, we should replace it with this
739 # has_usable whenever a case is given
741 my($self,$mod,$message) = @_;
742 return 1 if $HAS_USABLE->{$mod};
743 my $has_inst = $self->has_inst($mod,$message);
744 return unless $has_inst;
747 LWP => [ # we frequently had "Can't locate object
748 # method "new" via package "LWP::UserAgent" at
749 # (eval 69) line 2006
751 sub {require LWP::UserAgent},
752 sub {require HTTP::Request},
753 sub {require URI::URL},
756 sub {require Net::FTP},
757 sub {require Net::Config},
760 if ($usable->{$mod}) {
761 for my $c (0..$#{$usable->{$mod}}) {
762 my $code = $usable->{$mod}[$c];
763 my $ret = eval { &$code() };
765 warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
770 return $HAS_USABLE->{$mod} = 1;
773 #-> sub CPAN::has_inst
775 my($self,$mod,$message) = @_;
776 Carp::croak("CPAN->has_inst() called without an argument")
778 if (defined $message && $message eq "no"
780 exists $CPAN::META->{dontload_hash}{$mod} # unsafe meta access, ok
782 exists $CPAN::Config->{dontload_hash}{$mod}
784 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
792 # checking %INC is wrong, because $INC{LWP} may be true
793 # although $INC{"URI/URL.pm"} may have failed. But as
794 # I really want to say "bla loaded OK", I have to somehow
796 ### warn "$file in %INC"; #debug
798 } elsif (eval { require $file }) {
799 # eval is good: if we haven't yet read the database it's
800 # perfect and if we have installed the module in the meantime,
801 # it tries again. The second require is only a NOOP returning
802 # 1 if we had success, otherwise it's retrying
804 $CPAN::Frontend->myprint("CPAN: $mod loaded ok\n");
805 if ($mod eq "CPAN::WAIT") {
806 push @CPAN::Shell::ISA, 'CPAN::WAIT';
809 } elsif ($mod eq "Net::FTP") {
810 $CPAN::Frontend->mywarn(qq{
811 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
813 install Bundle::libnet
815 }) unless $Have_warned->{"Net::FTP"}++;
817 } elsif ($mod eq "Digest::MD5"){
818 $CPAN::Frontend->myprint(qq{
819 CPAN: MD5 security checks disabled because Digest::MD5 not installed.
820 Please consider installing the Digest::MD5 module.
824 } elsif ($mod eq "Module::Signature"){
825 unless ($Have_warned->{"Module::Signature"}++) {
826 # No point in complaining unless the user can
827 # reasonably install and use it.
828 if (eval { require Crypt::OpenPGP; 1 } ||
829 defined $CPAN::Config->{'gpg'}) {
830 $CPAN::Frontend->myprint(qq{
831 CPAN: Module::Signature security checks disabled because Module::Signature
832 not installed. Please consider installing the Module::Signature module.
833 You may also need to be able to connect over the Internet to the public
834 keyservers like pgp.mit.edu (port 11371).
841 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
846 #-> sub CPAN::instance ;
848 my($mgr,$class,$id) = @_;
851 # unsafe meta access, ok?
852 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
853 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
861 #-> sub CPAN::cleanup ;
863 # warn "cleanup called with arg[@_] End[$End] Signal[$Signal]";
864 local $SIG{__DIE__} = '';
869 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
871 $subroutine eq '(eval)';
873 return if $ineval && !$End;
874 return unless defined $META->{LOCK};
875 return unless -f $META->{LOCK};
877 unlink $META->{LOCK};
879 # Carp::cluck("DEBUGGING");
880 $CPAN::Frontend->mywarn("Lockfile removed.\n");
883 #-> sub CPAN::savehist
886 my($histfile,$histsize);
887 unless ($histfile = $CPAN::Config->{'histfile'}){
888 $CPAN::Frontend->mywarn("No history written (no histfile specified).\n");
891 $histsize = $CPAN::Config->{'histsize'} || 100;
893 unless ($CPAN::term->can("GetHistory")) {
894 $CPAN::Frontend->mywarn("Terminal does not support GetHistory.\n");
900 my @h = $CPAN::term->GetHistory;
901 splice @h, 0, @h-$histsize if @h>$histsize;
902 my($fh) = FileHandle->new;
903 open $fh, ">$histfile" or $CPAN::Frontend->mydie("Couldn't open >$histfile: $!");
904 local $\ = local $, = "\n";
910 my($self,$what) = @_;
911 $self->{is_tested}{$what} = 1;
915 my($self,$what) = @_;
916 delete $self->{is_tested}{$what};
921 $self->{is_tested} ||= {};
922 return unless %{$self->{is_tested}};
923 my $env = $ENV{PERL5LIB};
924 $env = $ENV{PERLLIB} unless defined $env;
926 push @env, $env if defined $env and length $env;
927 my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}};
928 $CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
929 $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
932 package CPAN::CacheMgr;
934 #-> sub CPAN::CacheMgr::as_string ;
936 eval { require Data::Dumper };
938 return shift->SUPER::as_string;
940 return Data::Dumper::Dumper(shift);
944 #-> sub CPAN::CacheMgr::cachesize ;
949 #-> sub CPAN::CacheMgr::tidyup ;
952 return unless -d $self->{ID};
953 while ($self->{DU} > $self->{'MAX'} ) {
954 my($toremove) = shift @{$self->{FIFO}};
955 $CPAN::Frontend->myprint(sprintf(
956 "Deleting from cache".
957 ": $toremove (%.1f>%.1f MB)\n",
958 $self->{DU}, $self->{'MAX'})
960 return if $CPAN::Signal;
961 $self->force_clean_cache($toremove);
962 return if $CPAN::Signal;
966 #-> sub CPAN::CacheMgr::dir ;
971 #-> sub CPAN::CacheMgr::entries ;
974 return unless defined $dir;
975 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
976 $dir ||= $self->{ID};
977 my($cwd) = CPAN::anycwd();
978 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
979 my $dh = DirHandle->new(File::Spec->curdir)
980 or Carp::croak("Couldn't opendir $dir: $!");
983 next if $_ eq "." || $_ eq "..";
985 push @entries, File::Spec->catfile($dir,$_);
987 push @entries, File::Spec->catdir($dir,$_);
989 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
992 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
993 sort { -M $b <=> -M $a} @entries;
996 #-> sub CPAN::CacheMgr::disk_usage ;
999 return if exists $self->{SIZE}{$dir};
1000 return if $CPAN::Signal;
1004 $File::Find::prune++ if $CPAN::Signal;
1006 if ($^O eq 'MacOS') {
1008 my $cat = Mac::Files::FSpGetCatInfo($_);
1009 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
1016 return if $CPAN::Signal;
1017 $self->{SIZE}{$dir} = $Du/1024/1024;
1018 push @{$self->{FIFO}}, $dir;
1019 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
1020 $self->{DU} += $Du/1024/1024;
1024 #-> sub CPAN::CacheMgr::force_clean_cache ;
1025 sub force_clean_cache {
1026 my($self,$dir) = @_;
1027 return unless -e $dir;
1028 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
1030 File::Path::rmtree($dir);
1031 $self->{DU} -= $self->{SIZE}{$dir};
1032 delete $self->{SIZE}{$dir};
1035 #-> sub CPAN::CacheMgr::new ;
1042 ID => $CPAN::Config->{'build_dir'},
1043 MAX => $CPAN::Config->{'build_cache'},
1044 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
1047 File::Path::mkpath($self->{ID});
1048 my $dh = DirHandle->new($self->{ID});
1049 bless $self, $class;
1052 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
1054 CPAN->debug($debug) if $CPAN::DEBUG;
1058 #-> sub CPAN::CacheMgr::scan_cache ;
1061 return if $self->{SCAN} eq 'never';
1062 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
1063 unless $self->{SCAN} eq 'atstart';
1064 $CPAN::Frontend->myprint(
1065 sprintf("Scanning cache %s for sizes\n",
1068 for $e ($self->entries($self->{ID})) {
1069 next if $e eq ".." || $e eq ".";
1070 $self->disk_usage($e);
1071 return if $CPAN::Signal;
1076 package CPAN::Debug;
1078 #-> sub CPAN::Debug::debug ;
1080 my($self,$arg) = @_;
1081 my($caller,$func,$line,@rest) = caller(1); # caller(0) eg
1082 # Complete, caller(1)
1084 ($caller) = caller(0);
1085 $caller =~ s/.*:://;
1086 $arg = "" unless defined $arg;
1087 my $rest = join "|", map { defined $_ ? $_ : "UNDEF" } @rest;
1088 if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
1089 if ($arg and ref $arg) {
1090 eval { require Data::Dumper };
1092 $CPAN::Frontend->myprint($arg->as_string);
1094 $CPAN::Frontend->myprint(Data::Dumper::Dumper($arg));
1097 $CPAN::Frontend->myprint("Debug($caller:$func,$line,[$rest]): $arg\n");
1102 package CPAN::Config;
1104 #-> sub CPAN::Config::edit ;
1105 # returns true on successful action
1107 my($self,@args) = @_;
1108 return unless @args;
1109 CPAN->debug("self[$self]args[".join(" | ",@args)."]");
1110 my($o,$str,$func,$args,$key_exists);
1116 CPAN->debug("o[$o]") if $CPAN::DEBUG;
1117 unless (exists $keys{$o}) {
1118 $CPAN::Frontend->mywarn("Warning: unknown configuration variable '$o'\n");
1120 if ($o =~ /list$/) {
1121 $func = shift @args;
1123 CPAN->debug("func[$func]") if $CPAN::DEBUG;
1125 # Let's avoid eval, it's easier to comprehend without.
1126 if ($func eq "push") {
1127 push @{$CPAN::Config->{$o}}, @args;
1129 } elsif ($func eq "pop") {
1130 pop @{$CPAN::Config->{$o}};
1132 } elsif ($func eq "shift") {
1133 shift @{$CPAN::Config->{$o}};
1135 } elsif ($func eq "unshift") {
1136 unshift @{$CPAN::Config->{$o}}, @args;
1138 } elsif ($func eq "splice") {
1139 splice @{$CPAN::Config->{$o}}, @args;
1142 $CPAN::Config->{$o} = [@args];
1145 $self->prettyprint($o);
1147 if ($o eq "urllist" && $changed) {
1148 # reset the cached values
1149 undef $CPAN::FTP::Thesite;
1150 undef $CPAN::FTP::Themethod;
1154 $CPAN::Config->{$o} = $args[0] if defined $args[0];
1155 $self->prettyprint($o);
1162 my $v = $CPAN::Config->{$k};
1164 my(@report) = ref $v eq "ARRAY" ?
1166 map { sprintf(" %-18s => [%s]\n",
1168 defined $v->{$_} ? $v->{$_} : "UNDEFINED"
1170 $CPAN::Frontend->myprint(
1177 map {"\t[$_]\n"} @report
1180 } elsif (defined $v) {
1181 $CPAN::Frontend->myprint(sprintf " %-18s [%s]\n", $k, $v);
1183 $CPAN::Frontend->myprint(sprintf " %-18s [%s]\n", $k, "UNDEFINED");
1187 #-> sub CPAN::Config::commit ;
1189 my($self,$configpm) = @_;
1190 unless (defined $configpm){
1191 $configpm ||= $INC{"CPAN/MyConfig.pm"};
1192 $configpm ||= $INC{"CPAN/Config.pm"};
1193 $configpm || Carp::confess(q{
1194 CPAN::Config::commit called without an argument.
1195 Please specify a filename where to save the configuration or try
1196 "o conf init" to have an interactive course through configing.
1201 $mode = (stat $configpm)[2];
1202 if ($mode && ! -w _) {
1203 Carp::confess("$configpm is not writable");
1208 $msg = <<EOF unless $configpm =~ /MyConfig/;
1210 # This is CPAN.pm's systemwide configuration file. This file provides
1211 # defaults for users, and the values can be changed in a per-user
1212 # configuration file. The user-config file is being looked for as
1213 # ~/.cpan/CPAN/MyConfig.pm.
1217 my($fh) = FileHandle->new;
1218 rename $configpm, "$configpm~" if -f $configpm;
1219 open $fh, ">$configpm" or
1220 $CPAN::Frontend->mydie("Couldn't open >$configpm: $!");
1221 $fh->print(qq[$msg\$CPAN::Config = \{\n]);
1222 foreach (sort keys %$CPAN::Config) {
1225 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}),
1230 $fh->print("};\n1;\n__END__\n");
1233 #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
1234 #chmod $mode, $configpm;
1235 ###why was that so? $self->defaults;
1236 $CPAN::Frontend->myprint("commit: wrote $configpm\n");
1240 *default = \&defaults;
1241 #-> sub CPAN::Config::defaults ;
1251 undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
1260 # This is a piece of repeated code that is abstracted here for
1261 # maintainability. RMB
1264 my($configpmdir, $configpmtest) = @_;
1265 if (-w $configpmtest) {
1266 return $configpmtest;
1267 } elsif (-w $configpmdir) {
1268 #_#_# following code dumped core on me with 5.003_11, a.k.
1269 my $configpm_bak = "$configpmtest.bak";
1270 unlink $configpm_bak if -f $configpm_bak;
1271 if( -f $configpmtest ) {
1272 if( rename $configpmtest, $configpm_bak ) {
1273 $CPAN::Frontend->mywarn(<<END);
1274 Old configuration file $configpmtest
1275 moved to $configpm_bak
1279 my $fh = FileHandle->new;
1280 if ($fh->open(">$configpmtest")) {
1282 return $configpmtest;
1284 # Should never happen
1285 Carp::confess("Cannot open >$configpmtest");
1290 #-> sub CPAN::Config::load ;
1292 my($self, %args) = @_;
1293 $CPAN::Be_Silent++ if $args{be_silent};
1297 eval {require CPAN::Config;}; # We eval because of some
1298 # MakeMaker problems
1299 unless ($dot_cpan++){
1300 unshift @INC, File::Spec->catdir($ENV{HOME},".cpan");
1301 eval {require CPAN::MyConfig;}; # where you can override
1302 # system wide settings
1305 return unless @miss = $self->missing_config_data;
1307 require CPAN::FirstTime;
1308 my($configpm,$fh,$redo,$theycalled);
1310 $theycalled++ if @miss==1 && $miss[0] eq 'inhibit_startup_message';
1311 if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
1312 $configpm = $INC{"CPAN/Config.pm"};
1314 } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
1315 $configpm = $INC{"CPAN/MyConfig.pm"};
1318 my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
1319 my($configpmdir) = File::Spec->catdir($path_to_cpan,"CPAN");
1320 my($configpmtest) = File::Spec->catfile($configpmdir,"Config.pm");
1321 if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
1322 $configpm = _configpmtest($configpmdir,$configpmtest);
1324 unless ($configpm) {
1325 $configpmdir = File::Spec->catdir($ENV{HOME},".cpan","CPAN");
1326 File::Path::mkpath($configpmdir);
1327 $configpmtest = File::Spec->catfile($configpmdir,"MyConfig.pm");
1328 $configpm = _configpmtest($configpmdir,$configpmtest);
1329 unless ($configpm) {
1330 my $text = qq{WARNING: CPAN.pm is unable to } .
1331 qq{create a configuration file.};
1332 output($text, 'confess');
1337 $CPAN::Frontend->myprint(<<END) if $redo && ! $theycalled;
1338 We have to reconfigure CPAN.pm due to following uninitialized parameters:
1342 $CPAN::Frontend->myprint(qq{
1343 $configpm initialized.
1347 CPAN::FirstTime::init($configpm, %args);
1350 #-> sub CPAN::Config::missing_config_data ;
1351 sub missing_config_data {
1354 "cpan_home", "keep_source_where", "build_dir", "build_cache",
1355 "scan_cache", "index_expire", "gzip", "tar", "unzip", "make",
1357 "makepl_arg", "make_arg", "make_install_arg", "urllist",
1358 "inhibit_startup_message", "ftp_proxy", "http_proxy", "no_proxy",
1359 "prerequisites_policy",
1362 push @miss, $_ unless defined $CPAN::Config->{$_};
1367 #-> sub CPAN::Config::unload ;
1369 delete $INC{'CPAN/MyConfig.pm'};
1370 delete $INC{'CPAN/Config.pm'};
1373 #-> sub CPAN::Config::help ;
1375 $CPAN::Frontend->myprint(q[
1377 defaults reload default config values from disk
1378 commit commit session changes to disk
1379 init go through a dialog to set all parameters
1381 You may edit key values in the follow fashion (the "o" is a literal
1384 o conf build_cache 15
1386 o conf build_dir "/foo/bar"
1388 o conf urllist shift
1390 o conf urllist unshift ftp://ftp.foo.bar/
1393 undef; #don't reprint CPAN::Config
1396 #-> sub CPAN::Config::cpl ;
1398 my($word,$line,$pos) = @_;
1400 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1401 my(@words) = split " ", substr($line,0,$pos+1);
1406 $words[2] =~ /list$/ && @words == 3
1408 $words[2] =~ /list$/ && @words == 4 && length($word)
1411 return grep /^\Q$word\E/, qw(splice shift unshift pop push);
1412 } elsif (@words >= 4) {
1416 my(@o_conf) = sort grep { !$seen{$_}++ }
1417 keys %CPAN::Config::can,
1418 keys %$CPAN::Config,
1419 keys %CPAN::Config::keys;
1420 return grep /^\Q$word\E/, @o_conf;
1423 package CPAN::Shell;
1425 #-> sub CPAN::Shell::h ;
1427 my($class,$about) = @_;
1428 if (defined $about) {
1429 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
1431 $CPAN::Frontend->myprint(q{
1433 command argument description
1434 a,b,d,m WORD or /REGEXP/ about authors, bundles, distributions, modules
1435 i WORD or /REGEXP/ about any of the above
1436 r NONE report updatable modules
1437 ls AUTHOR about files in the author's directory
1438 (with WORD being a module, bundle or author name or a distribution
1439 name of the form AUTHOR/DISTRIBUTION)
1441 Download, Test, Make, Install...
1442 get download clean make clean
1443 make make (implies get) look open subshell in dist directory
1444 test make test (implies make) readme display these README files
1445 install make install (implies test) perldoc display POD documentation
1448 force COMMAND unconditionally do command
1449 notest COMMAND skip testing
1452 h,? display this menu ! perl-code eval a perl command
1453 o conf [opt] set and query options q quit the cpan shell
1454 reload cpan load CPAN.pm again reload index load newer indices
1455 autobundle Snapshot recent latest CPAN uploads});
1461 #-> sub CPAN::Shell::a ;
1463 my($self,@arg) = @_;
1464 # authors are always UPPERCASE
1466 $_ = uc $_ unless /=/;
1468 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1471 #-> sub CPAN::Shell::ls ;
1473 my($self,@arg) = @_;
1475 if ($arg[0] eq "*") {
1476 @arg = map { $_->id } $self->expand('Author','/./');
1479 unless (/^[A-Z0-9\-]+$/i) {
1480 $CPAN::Frontend->mywarn("ls command rejects argument $_: not an author\n");
1483 push @accept, uc $_;
1485 my $silent = @accept>1;
1486 my $last_alpha = "";
1487 for my $a (@accept){
1488 my $author = $self->expand('Author',$a) or die "No author found for $a";
1489 $author->ls($silent); # silent if more than one author
1491 my $alphadot = substr $author->id, 0, 1;
1493 if ($alphadot eq $last_alpha) {
1497 $last_alpha = $alphadot;
1499 $CPAN::Frontend->myprint($ad);
1504 #-> sub CPAN::Shell::local_bundles ;
1506 my($self,@which) = @_;
1507 my($incdir,$bdir,$dh);
1508 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1509 my @bbase = "Bundle";
1510 while (my $bbase = shift @bbase) {
1511 $bdir = File::Spec->catdir($incdir,split /::/, $bbase);
1512 CPAN->debug("bdir[$bdir]\@bbase[@bbase]") if $CPAN::DEBUG;
1513 if ($dh = DirHandle->new($bdir)) { # may fail
1515 for $entry ($dh->read) {
1516 next if $entry =~ /^\./;
1517 if (-d File::Spec->catdir($bdir,$entry)){
1518 push @bbase, "$bbase\::$entry";
1520 next unless $entry =~ s/\.pm(?!\n)\Z//;
1521 $CPAN::META->instance('CPAN::Bundle',"$bbase\::$entry");
1529 #-> sub CPAN::Shell::b ;
1531 my($self,@which) = @_;
1532 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1533 $self->local_bundles;
1534 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1537 #-> sub CPAN::Shell::d ;
1538 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1540 #-> sub CPAN::Shell::m ;
1541 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
1543 $CPAN::Frontend->myprint($self->format_result('Module',@_));
1546 #-> sub CPAN::Shell::i ;
1550 @args = '/./' unless @args;
1552 for my $type (qw/Bundle Distribution Module/) {
1553 push @result, $self->expand($type,@args);
1555 # Authors are always uppercase.
1556 push @result, $self->expand("Author", map { uc $_ } @args);
1558 my $result = @result == 1 ?
1559 $result[0]->as_string :
1561 "No objects found of any type for argument @args\n" :
1563 (map {$_->as_glimpse} @result),
1564 scalar @result, " items found\n",
1566 $CPAN::Frontend->myprint($result);
1569 #-> sub CPAN::Shell::o ;
1571 # CPAN::Shell::o and CPAN::Config::edit are closely related. 'o conf'
1572 # should have been called set and 'o debug' maybe 'set debug'
1574 my($self,$o_type,@o_what) = @_;
1576 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1577 if ($o_type eq 'conf') {
1578 shift @o_what if @o_what && $o_what[0] eq 'help';
1579 if (!@o_what) { # print all things, "o conf"
1581 $CPAN::Frontend->myprint("CPAN::Config options");
1582 if (exists $INC{'CPAN/Config.pm'}) {
1583 $CPAN::Frontend->myprint(" from $INC{'CPAN/Config.pm'}");
1585 if (exists $INC{'CPAN/MyConfig.pm'}) {
1586 $CPAN::Frontend->myprint(" and $INC{'CPAN/MyConfig.pm'}");
1588 $CPAN::Frontend->myprint(":\n");
1589 for $k (sort keys %CPAN::Config::can) {
1590 $v = $CPAN::Config::can{$k};
1591 $CPAN::Frontend->myprint(sprintf " %-18s [%s]\n", $k, $v);
1593 $CPAN::Frontend->myprint("\n");
1594 for $k (sort keys %$CPAN::Config) {
1595 CPAN::Config->prettyprint($k);
1597 $CPAN::Frontend->myprint("\n");
1598 } elsif (!CPAN::Config->edit(@o_what)) {
1599 $CPAN::Frontend->myprint(qq{Type 'o conf' to view configuration }.
1600 qq{edit options\n\n});
1602 } elsif ($o_type eq 'debug') {
1604 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1607 my($what) = shift @o_what;
1608 if ($what =~ s/^-// && exists $CPAN::DEBUG{$what}) {
1609 $CPAN::DEBUG &= $CPAN::DEBUG ^ $CPAN::DEBUG{$what};
1612 if ( exists $CPAN::DEBUG{$what} ) {
1613 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1614 } elsif ($what =~ /^\d/) {
1615 $CPAN::DEBUG = $what;
1616 } elsif (lc $what eq 'all') {
1618 for (values %CPAN::DEBUG) {
1621 $CPAN::DEBUG = $max;
1624 for (keys %CPAN::DEBUG) {
1625 next unless lc($_) eq lc($what);
1626 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1629 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1634 my $raw = "Valid options for debug are ".
1635 join(", ",sort(keys %CPAN::DEBUG), 'all').
1636 qq{ or a number. Completion works on the options. }.
1637 qq{Case is ignored.};
1639 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
1640 $CPAN::Frontend->myprint("\n\n");
1643 $CPAN::Frontend->myprint("Options set for debugging:\n");
1645 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1646 $v = $CPAN::DEBUG{$k};
1647 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
1648 if $v & $CPAN::DEBUG;
1651 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1654 $CPAN::Frontend->myprint(qq{
1656 conf set or get configuration variables
1657 debug set or get debugging options
1662 sub paintdots_onreload {
1665 if ( $_[0] =~ /[Ss]ubroutine ([\w:]+) redefined/ ) {
1669 # $CPAN::Frontend->myprint(".($subr)");
1670 $CPAN::Frontend->myprint(".");
1677 #-> sub CPAN::Shell::reload ;
1679 my($self,$command,@arg) = @_;
1681 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1682 if ($command =~ /cpan/i) {
1683 for my $f (qw(CPAN.pm CPAN/FirstTime.pm)) {
1684 next unless $INC{$f};
1685 my $pwd = CPAN::anycwd();
1686 CPAN->debug("reloading the whole '$f' from '$INC{$f}' while pwd='$pwd'")
1688 my $fh = FileHandle->new($INC{$f});
1692 local($SIG{__WARN__}) = paintdots_onreload(\$redef);
1694 CPAN->debug("evaling '$eval'")
1698 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1700 } elsif ($command =~ /index/) {
1701 CPAN::Index->force_reload;
1703 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN.pm file
1704 index re-reads the index files\n});
1708 #-> sub CPAN::Shell::_binary_extensions ;
1709 sub _binary_extensions {
1710 my($self) = shift @_;
1711 my(@result,$module,%seen,%need,$headerdone);
1712 for $module ($self->expand('Module','/./')) {
1713 my $file = $module->cpan_file;
1714 next if $file eq "N/A";
1715 next if $file =~ /^Contact Author/;
1716 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
1717 next if $dist->isa_perl;
1718 next unless $module->xs_file;
1720 $CPAN::Frontend->myprint(".");
1721 push @result, $module;
1723 # print join " | ", @result;
1724 $CPAN::Frontend->myprint("\n");
1728 #-> sub CPAN::Shell::recompile ;
1730 my($self) = shift @_;
1731 my($module,@module,$cpan_file,%dist);
1732 @module = $self->_binary_extensions();
1733 for $module (@module){ # we force now and compile later, so we
1735 $cpan_file = $module->cpan_file;
1736 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1738 $dist{$cpan_file}++;
1740 for $cpan_file (sort keys %dist) {
1741 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1742 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1744 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1745 # stop a package from recompiling,
1746 # e.g. IO-1.12 when we have perl5.003_10
1750 #-> sub CPAN::Shell::_u_r_common ;
1752 my($self) = shift @_;
1753 my($what) = shift @_;
1754 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1755 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
1756 $what && $what =~ /^[aru]$/;
1758 @args = '/./' unless @args;
1759 my(@result,$module,%seen,%need,$headerdone,
1760 $version_undefs,$version_zeroes);
1761 $version_undefs = $version_zeroes = 0;
1762 my $sprintf = "%s%-25s%s %9s %9s %s\n";
1763 my @expand = $self->expand('Module',@args);
1764 my $expand = scalar @expand;
1765 if (0) { # Looks like noise to me, was very useful for debugging
1766 # for metadata cache
1767 $CPAN::Frontend->myprint(sprintf "%d matches in the database\n", $expand);
1769 MODULE: for $module (@expand) {
1770 my $file = $module->cpan_file;
1771 next MODULE unless defined $file; # ??
1772 my($latest) = $module->cpan_version;
1773 my($inst_file) = $module->inst_file;
1775 return if $CPAN::Signal;
1778 $have = $module->inst_version;
1779 } elsif ($what eq "r") {
1780 $have = $module->inst_version;
1782 if ($have eq "undef"){
1784 } elsif ($have == 0){
1787 next MODULE unless CPAN::Version->vgt($latest, $have);
1788 # to be pedantic we should probably say:
1789 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1790 # to catch the case where CPAN has a version 0 and we have a version undef
1791 } elsif ($what eq "u") {
1797 } elsif ($what eq "r") {
1799 } elsif ($what eq "u") {
1803 return if $CPAN::Signal; # this is sometimes lengthy
1806 push @result, sprintf "%s %s\n", $module->id, $have;
1807 } elsif ($what eq "r") {
1808 push @result, $module->id;
1809 next MODULE if $seen{$file}++;
1810 } elsif ($what eq "u") {
1811 push @result, $module->id;
1812 next MODULE if $seen{$file}++;
1813 next MODULE if $file =~ /^Contact/;
1815 unless ($headerdone++){
1816 $CPAN::Frontend->myprint("\n");
1817 $CPAN::Frontend->myprint(sprintf(
1820 "Package namespace",
1832 $CPAN::META->has_inst("Term::ANSIColor")
1834 $module->{RO}{description}
1836 $color_on = Term::ANSIColor::color("green");
1837 $color_off = Term::ANSIColor::color("reset");
1839 $CPAN::Frontend->myprint(sprintf $sprintf,
1846 $need{$module->id}++;
1850 $CPAN::Frontend->myprint("No modules found for @args\n");
1851 } elsif ($what eq "r") {
1852 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1856 if ($version_zeroes) {
1857 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1858 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1859 qq{a version number of 0\n});
1861 if ($version_undefs) {
1862 my $s_has = $version_undefs > 1 ? "s have" : " has";
1863 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1864 qq{parseable version number\n});
1870 #-> sub CPAN::Shell::r ;
1872 shift->_u_r_common("r",@_);
1875 #-> sub CPAN::Shell::u ;
1877 shift->_u_r_common("u",@_);
1880 #-> sub CPAN::Shell::autobundle ;
1883 CPAN::Config->load unless $CPAN::Config_loaded++;
1884 my(@bundle) = $self->_u_r_common("a",@_);
1885 my($todir) = File::Spec->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1886 File::Path::mkpath($todir);
1887 unless (-d $todir) {
1888 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
1891 my($y,$m,$d) = (localtime)[5,4,3];
1895 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1896 my($to) = File::Spec->catfile($todir,"$me.pm");
1898 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1899 $to = File::Spec->catfile($todir,"$me.pm");
1901 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1903 "package Bundle::$me;\n\n",
1904 "\$VERSION = '0.01';\n\n",
1908 "Bundle::$me - Snapshot of installation on ",
1909 $Config::Config{'myhostname'},
1912 "\n\n=head1 SYNOPSIS\n\n",
1913 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1914 "=head1 CONTENTS\n\n",
1915 join("\n", @bundle),
1916 "\n\n=head1 CONFIGURATION\n\n",
1918 "\n\n=head1 AUTHOR\n\n",
1919 "This Bundle has been generated automatically ",
1920 "by the autobundle routine in CPAN.pm.\n",
1923 $CPAN::Frontend->myprint("\nWrote bundle file
1927 #-> sub CPAN::Shell::expandany ;
1930 CPAN->debug("s[$s]") if $CPAN::DEBUG;
1931 if ($s =~ m|/|) { # looks like a file
1932 $s = CPAN::Distribution->normalize($s);
1933 return $CPAN::META->instance('CPAN::Distribution',$s);
1934 # Distributions spring into existence, not expand
1935 } elsif ($s =~ m|^Bundle::|) {
1936 $self->local_bundles; # scanning so late for bundles seems
1937 # both attractive and crumpy: always
1938 # current state but easy to forget
1940 return $self->expand('Bundle',$s);
1942 return $self->expand('Module',$s)
1943 if $CPAN::META->exists('CPAN::Module',$s);
1948 #-> sub CPAN::Shell::expand ;
1951 my($type,@args) = @_;
1953 CPAN->debug("type[$type]args[@args]") if $CPAN::DEBUG;
1955 my($regex,$command);
1956 if ($arg =~ m|^/(.*)/$|) {
1958 } elsif ($arg =~ m/=/) {
1961 my $class = "CPAN::$type";
1963 CPAN->debug(sprintf "class[%s]regex[%s]command[%s]",
1965 defined $regex ? $regex : "UNDEFINED",
1966 $command || "UNDEFINED",
1968 if (defined $regex) {
1972 $CPAN::META->all_objects($class)
1975 # BUG, we got an empty object somewhere
1976 require Data::Dumper;
1977 CPAN->debug(sprintf(
1978 "Bug in CPAN: Empty id on obj[%s][%s]",
1980 Data::Dumper::Dumper($obj)
1985 if $obj->id =~ /$regex/i
1989 $] < 5.00303 ### provide sort of
1990 ### compatibility with 5.003
1995 $obj->name =~ /$regex/i
1998 } elsif ($command) {
1999 die "equal sign in command disabled (immature interface), ".
2001 ! \$CPAN::Shell::ADVANCED_QUERY=1
2002 to enable it. But please note, this is HIGHLY EXPERIMENTAL code
2003 that may go away anytime.\n"
2004 unless $ADVANCED_QUERY;
2005 my($method,$criterion) = $arg =~ /(.+?)=(.+)/;
2006 my($matchcrit) = $criterion =~ m/^~(.+)/;
2010 $CPAN::META->all_objects($class)
2012 my $lhs = $self->$method() or next; # () for 5.00503
2014 push @m, $self if $lhs =~ m/$matchcrit/;
2016 push @m, $self if $lhs eq $criterion;
2021 if ( $type eq 'Bundle' ) {
2022 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
2023 } elsif ($type eq "Distribution") {
2024 $xarg = CPAN::Distribution->normalize($arg);
2026 if ($CPAN::META->exists($class,$xarg)) {
2027 $obj = $CPAN::META->instance($class,$xarg);
2028 } elsif ($CPAN::META->exists($class,$arg)) {
2029 $obj = $CPAN::META->instance($class,$arg);
2036 return wantarray ? @m : $m[0];
2039 #-> sub CPAN::Shell::format_result ;
2042 my($type,@args) = @_;
2043 @args = '/./' unless @args;
2044 my(@result) = $self->expand($type,@args);
2045 my $result = @result == 1 ?
2046 $result[0]->as_string :
2048 "No objects of type $type found for argument @args\n" :
2050 (map {$_->as_glimpse} @result),
2051 scalar @result, " items found\n",
2056 #-> sub CPAN::Shell::report_fh ;
2058 my $installation_report_fh;
2059 my $previously_noticed = 0;
2062 return $installation_report_fh if $installation_report_fh;
2063 $installation_report_fh = File::Temp->new(
2064 template => 'cpan_install_XXXX',
2068 unless ( $installation_report_fh ) {
2069 warn("Couldn't open installation report file; " .
2070 "no report file will be generated."
2071 ) unless $previously_noticed++;
2077 # The only reason for this method is currently to have a reliable
2078 # debugging utility that reveals which output is going through which
2079 # channel. No, I don't like the colors ;-)
2081 #-> sub CPAN::Shell::print_ornameted ;
2082 sub print_ornamented {
2083 my($self,$what,$ornament) = @_;
2085 return unless defined $what;
2087 local $| = 1; # Flush immediately
2088 if ( $CPAN::Be_Silent ) {
2089 print {report_fh()} $what;
2093 if ($CPAN::Config->{term_is_latin}){
2096 =~ s{([\xC0-\xDF])([\x80-\xBF])}{chr(ord($1)<<6&0xC0|ord($2)&0x3F)}eg; #};
2098 if ($PRINT_ORNAMENTING) {
2099 unless (defined &color) {
2100 if ($CPAN::META->has_inst("Term::ANSIColor")) {
2101 import Term::ANSIColor "color";
2103 *color = sub { return "" };
2107 for $line (split /\n/, $what) {
2108 $longest = length($line) if length($line) > $longest;
2110 my $sprintf = "%-" . $longest . "s";
2112 $what =~ s/(.*\n?)//m;
2115 my($nl) = chomp $line ? "\n" : "";
2116 # print "line[$line]ornament[$ornament]sprintf[$sprintf]\n";
2117 print color($ornament), sprintf($sprintf,$line), color("reset"), $nl;
2121 # $what .= "\n"; # newlines unless $PRINT_ORNAMENTING
2127 my($self,$what) = @_;
2129 $self->print_ornamented($what, 'bold blue on_yellow');
2133 my($self,$what) = @_;
2134 $self->myprint($what);
2139 my($self,$what) = @_;
2140 $self->print_ornamented($what, 'bold red on_yellow');
2144 my($self,$what) = @_;
2145 $self->print_ornamented($what, 'bold red on_white');
2146 Carp::confess "died";
2150 my($self,$what) = @_;
2151 $self->print_ornamented($what, 'bold red on_white');
2156 return if -t STDOUT;
2157 my $odef = select STDERR;
2164 #-> sub CPAN::Shell::rematein ;
2165 # RE-adme||MA-ke||TE-st||IN-stall
2168 my($meth,@some) = @_;
2170 while($meth =~ /^(force|notest)$/) {
2171 push @pragma, $meth;
2172 $meth = shift @some;
2175 CPAN->debug("pragma[@pragma]meth[$meth]some[@some]") if $CPAN::DEBUG;
2177 # Here is the place to set "test_count" on all involved parties to
2178 # 0. We then can pass this counter on to the involved
2179 # distributions and those can refuse to test if test_count > X. In
2180 # the first stab at it we could use a 1 for "X".
2182 # But when do I reset the distributions to start with 0 again?
2183 # Jost suggested to have a random or cycling interaction ID that
2184 # we pass through. But the ID is something that is just left lying
2185 # around in addition to the counter, so I'd prefer to set the
2186 # counter to 0 now, and repeat at the end of the loop. But what
2187 # about dependencies? They appear later and are not reset, they
2188 # enter the queue but not its copy. How do they get a sensible
2191 # construct the queue
2193 foreach $s (@some) {
2196 CPAN->debug("s is an object[$s]") if $CPAN::DEBUG;
2198 } elsif ($s =~ m|^/|) { # looks like a regexp
2199 $CPAN::Frontend->mywarn("Sorry, $meth with a regular expression is ".
2204 CPAN->debug("calling expandany [$s]") if $CPAN::DEBUG;
2205 $obj = CPAN::Shell->expandany($s);
2208 $obj->color_cmd_tmps(0,1);
2209 CPAN::Queue->new($obj->id);
2211 } elsif ($CPAN::META->exists('CPAN::Author',uc($s))) {
2212 $obj = $CPAN::META->instance('CPAN::Author',uc($s));
2213 if ($meth =~ /^(dump|ls)$/) {
2216 $CPAN::Frontend->myprint(
2218 "Don't be silly, you can't $meth ",
2226 ->myprint(qq{Warning: Cannot $meth $s, }.
2227 qq{don\'t know what it is.
2232 to find objects with matching identifiers.
2238 # queuerunner (please be warned: when I started to change the
2239 # queue to hold objects instead of names, I made one or two
2240 # mistakes and never found which. I reverted back instead)
2241 while ($s = CPAN::Queue->first) {
2244 $obj = $s; # I do not believe, we would survive if this happened
2246 $obj = CPAN::Shell->expandany($s);
2248 for my $pragma (@pragma) {
2251 ($] < 5.00303 || $obj->can($pragma))){
2252 ### compatibility with 5.003
2253 $obj->$pragma($meth); # the pragma "force" in
2254 # "CPAN::Distribution" must know
2255 # what we are intending
2258 if ($]>=5.00303 && $obj->can('called_for')) {
2259 $obj->called_for($s);
2262 qq{pragma[@pragma]meth[$meth]obj[$obj]as_string\[}.
2268 CPAN::Queue->delete($s);
2270 CPAN->debug("failed");
2274 CPAN::Queue->delete_first($s);
2276 for my $obj (@qcopy) {
2277 $obj->color_cmd_tmps(0,0);
2281 #-> sub CPAN::Shell::recent ;
2285 CPAN::Distribution::_display_url( $self, $CPAN::Defaultrecent );
2290 # set up the dispatching methods
2292 for my $command (qw(
2293 clean cvs_import dump force get install look
2294 make notest perldoc readme test
2296 *$command = sub { shift->rematein($command, @_); };
2300 package CPAN::LWP::UserAgent;
2303 return if $SETUPDONE;
2304 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2305 require LWP::UserAgent;
2306 @ISA = qw(Exporter LWP::UserAgent);
2309 $CPAN::Frontend->mywarn("LWP::UserAgent not available\n");
2313 sub get_basic_credentials {
2314 my($self, $realm, $uri, $proxy) = @_;
2315 return unless $proxy;
2316 if ($USER && $PASSWD) {
2317 } elsif (defined $CPAN::Config->{proxy_user} &&
2318 defined $CPAN::Config->{proxy_pass}) {
2319 $USER = $CPAN::Config->{proxy_user};
2320 $PASSWD = $CPAN::Config->{proxy_pass};
2322 require ExtUtils::MakeMaker;
2323 ExtUtils::MakeMaker->import(qw(prompt));
2324 $USER = prompt("Proxy authentication needed!
2325 (Note: to permanently configure username and password run
2326 o conf proxy_user your_username
2327 o conf proxy_pass your_password
2329 if ($CPAN::META->has_inst("Term::ReadKey")) {
2330 Term::ReadKey::ReadMode("noecho");
2332 $CPAN::Frontend->mywarn("Warning: Term::ReadKey seems not to be available, your password will be echoed to the terminal!\n");
2334 $PASSWD = prompt("Password:");
2335 if ($CPAN::META->has_inst("Term::ReadKey")) {
2336 Term::ReadKey::ReadMode("restore");
2338 $CPAN::Frontend->myprint("\n\n");
2340 return($USER,$PASSWD);
2343 # mirror(): Its purpose is to deal with proxy authentication. When we
2344 # call SUPER::mirror, we relly call the mirror method in
2345 # LWP::UserAgent. LWP::UserAgent will then call
2346 # $self->get_basic_credentials or some equivalent and this will be
2347 # $self->dispatched to our own get_basic_credentials method.
2349 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
2351 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
2352 # although we have gone through our get_basic_credentials, the proxy
2353 # server refuses to connect. This could be a case where the username or
2354 # password has changed in the meantime, so I'm trying once again without
2355 # $USER and $PASSWD to give the get_basic_credentials routine another
2356 # chance to set $USER and $PASSWD.
2358 # mirror(): Its purpose is to deal with proxy authentication. When we
2359 # call SUPER::mirror, we relly call the mirror method in
2360 # LWP::UserAgent. LWP::UserAgent will then call
2361 # $self->get_basic_credentials or some equivalent and this will be
2362 # $self->dispatched to our own get_basic_credentials method.
2364 # Our own get_basic_credentials sets $USER and $PASSWD, two globals.
2366 # 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
2367 # although we have gone through our get_basic_credentials, the proxy
2368 # server refuses to connect. This could be a case where the username or
2369 # password has changed in the meantime, so I'm trying once again without
2370 # $USER and $PASSWD to give the get_basic_credentials routine another
2371 # chance to set $USER and $PASSWD.
2374 my($self,$url,$aslocal) = @_;
2375 my $result = $self->SUPER::mirror($url,$aslocal);
2376 if ($result->code == 407) {
2379 $result = $self->SUPER::mirror($url,$aslocal);
2386 #-> sub CPAN::FTP::ftp_get ;
2388 my($class,$host,$dir,$file,$target) = @_;
2390 qq[Going to fetch file [$file] from dir [$dir]
2391 on host [$host] as local [$target]\n]
2393 my $ftp = Net::FTP->new($host);
2394 return 0 unless defined $ftp;
2395 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
2396 $class->debug(qq[Going to login("anonymous","$Config::Config{cf_email}")]);
2397 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
2398 warn "Couldn't login on $host";
2401 unless ( $ftp->cwd($dir) ){
2402 warn "Couldn't cwd $dir";
2406 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
2407 unless ( $ftp->get($file,$target) ){
2408 warn "Couldn't fetch $file from $host\n";
2411 $ftp->quit; # it's ok if this fails
2415 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
2417 # > *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
2418 # > --- /tmp/cp Wed Sep 24 13:26:40 1997
2420 # > *** 1562,1567 ****
2421 # > --- 1562,1580 ----
2422 # > return 1 if substr($url,0,4) eq "file";
2423 # > return 1 unless $url =~ m|://([^/]+)|;
2425 # > + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
2427 # > + $proxy =~ m|://([^/:]+)|;
2429 # > + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
2430 # > + if ($noproxy) {
2431 # > + if ($host !~ /$noproxy$/) {
2432 # > + $host = $proxy;
2435 # > + $host = $proxy;
2438 # > require Net::Ping;
2439 # > return 1 unless $Net::Ping::VERSION >= 2;
2443 #-> sub CPAN::FTP::localize ;
2445 my($self,$file,$aslocal,$force) = @_;
2447 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
2448 unless defined $aslocal;
2449 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
2452 if ($^O eq 'MacOS') {
2453 # Comment by AK on 2000-09-03: Uniq short filenames would be
2454 # available in CHECKSUMS file
2455 my($name, $path) = File::Basename::fileparse($aslocal, '');
2456 if (length($name) > 31) {
2467 my $size = 31 - length($suf);
2468 while (length($name) > $size) {
2472 $aslocal = File::Spec->catfile($path, $name);
2476 return $aslocal if -f $aslocal && -r _ && !($force & 1);
2479 rename $aslocal, "$aslocal.bak";
2483 my($aslocal_dir) = File::Basename::dirname($aslocal);
2484 File::Path::mkpath($aslocal_dir);
2485 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
2486 qq{directory "$aslocal_dir".
2487 I\'ll continue, but if you encounter problems, they may be due
2488 to insufficient permissions.\n}) unless -w $aslocal_dir;
2490 # Inheritance is not easier to manage than a few if/else branches
2491 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2493 CPAN::LWP::UserAgent->config;
2494 eval {$Ua = CPAN::LWP::UserAgent->new;}; # Why is has_usable still not fit enough?
2496 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n")
2500 $Ua->proxy('ftp', $var)
2501 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
2502 $Ua->proxy('http', $var)
2503 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
2506 # >>>>> On Wed, 13 Dec 2000 09:21:34 -0500, "Robison, Jonathon (J.M.)" <jrobiso2@visteon.com> said:
2508 # > I note that although CPAN.pm can use proxies, it doesn't seem equipped to
2509 # > use ones that require basic autorization.
2511 # > Example of when I use it manually in my own stuff:
2513 # > $ua->proxy(['http','ftp'], http://my.proxy.server:83');
2514 # > $req->proxy_authorization_basic("username","password");
2515 # > $res = $ua->request($req);
2519 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
2523 for my $prx (qw(ftp_proxy http_proxy no_proxy)) {
2524 $ENV{$prx} = $CPAN::Config->{$prx} if $CPAN::Config->{$prx};
2527 # Try the list of urls for each single object. We keep a record
2528 # where we did get a file from
2529 my(@reordered,$last);
2530 $CPAN::Config->{urllist} ||= [];
2531 unless (ref $CPAN::Config->{urllist} eq 'ARRAY') {
2532 warn "Malformed urllist; ignoring. Configuration file corrupt?\n";
2534 $last = $#{$CPAN::Config->{urllist}};
2535 if ($force & 2) { # local cpans probably out of date, don't reorder
2536 @reordered = (0..$last);
2540 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
2542 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
2553 @levels = ($Themethod, grep {$_ ne $Themethod} qw/easy hard hardest/);
2555 @levels = qw/easy hard hardest/;
2557 @levels = qw/easy/ if $^O eq 'MacOS';
2559 for $levelno (0..$#levels) {
2560 my $level = $levels[$levelno];
2561 my $method = "host$level";
2562 my @host_seq = $level eq "easy" ?
2563 @reordered : 0..$last; # reordered has CDROM up front
2564 @host_seq = (0) unless @host_seq;
2565 my $ret = $self->$method(\@host_seq,$file,$aslocal);
2567 $Themethod = $level;
2569 # utime $now, $now, $aslocal; # too bad, if we do that, we
2570 # might alter a local mirror
2571 $self->debug("level[$level]") if $CPAN::DEBUG;
2575 last if $CPAN::Signal; # need to cleanup
2578 unless ($CPAN::Signal) {
2581 qq{Please check, if the URLs I found in your configuration file \(}.
2582 join(", ", @{$CPAN::Config->{urllist}}).
2583 qq{\) are valid. The urllist can be edited.},
2584 qq{E.g. with 'o conf urllist push ftp://myurl/'};
2585 $CPAN::Frontend->myprint(Text::Wrap::wrap("","",@mess). "\n\n");
2587 $CPAN::Frontend->myprint("Could not fetch $file\n");
2590 rename "$aslocal.bak", $aslocal;
2591 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
2592 $self->ls($aslocal));
2599 my($self,$host_seq,$file,$aslocal) = @_;
2601 HOSTEASY: for $i (@$host_seq) {
2602 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2603 $url .= "/" unless substr($url,-1) eq "/";
2605 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
2606 if ($url =~ /^file:/) {
2608 if ($CPAN::META->has_inst('URI::URL')) {
2609 my $u = URI::URL->new($url);
2611 } else { # works only on Unix, is poorly constructed, but
2612 # hopefully better than nothing.
2613 # RFC 1738 says fileurl BNF is
2614 # fileurl = "file://" [ host | "localhost" ] "/" fpath
2615 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
2617 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
2618 $l =~ s|^file:||; # assume they
2621 $l =~ s|^/||s unless -f $l; # e.g. /P:
2622 $self->debug("without URI::URL we try local file $l") if $CPAN::DEBUG;
2624 if ( -f $l && -r _) {
2628 # Maybe mirror has compressed it?
2630 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
2631 CPAN::Tarzip->gunzip("$l.gz", $aslocal);
2638 if ($CPAN::META->has_usable('LWP')) {
2639 $CPAN::Frontend->myprint("Fetching with LWP:
2643 CPAN::LWP::UserAgent->config;
2644 eval { $Ua = CPAN::LWP::UserAgent->new; };
2646 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@\n");
2649 my $res = $Ua->mirror($url, $aslocal);
2650 if ($res->is_success) {
2653 utime $now, $now, $aslocal; # download time is more
2654 # important than upload time
2656 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2657 my $gzurl = "$url.gz";
2658 $CPAN::Frontend->myprint("Fetching with LWP:
2661 $res = $Ua->mirror($gzurl, "$aslocal.gz");
2662 if ($res->is_success &&
2663 CPAN::Tarzip->gunzip("$aslocal.gz",$aslocal)
2669 $CPAN::Frontend->myprint(sprintf(
2670 "LWP failed with code[%s] message[%s]\n",
2674 # Alan Burlison informed me that in firewall environments
2675 # Net::FTP can still succeed where LWP fails. So we do not
2676 # skip Net::FTP anymore when LWP is available.
2679 $CPAN::Frontend->myprint("LWP not available\n");
2681 return if $CPAN::Signal;
2682 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2683 # that's the nice and easy way thanks to Graham
2684 my($host,$dir,$getfile) = ($1,$2,$3);
2685 if ($CPAN::META->has_usable('Net::FTP')) {
2687 $CPAN::Frontend->myprint("Fetching with Net::FTP:
2690 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
2691 "aslocal[$aslocal]") if $CPAN::DEBUG;
2692 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
2696 if ($aslocal !~ /\.gz(?!\n)\Z/) {
2697 my $gz = "$aslocal.gz";
2698 $CPAN::Frontend->myprint("Fetching with Net::FTP
2701 if (CPAN::FTP->ftp_get($host,
2705 CPAN::Tarzip->gunzip($gz,$aslocal)
2714 return if $CPAN::Signal;
2719 my($self,$host_seq,$file,$aslocal) = @_;
2721 # Came back if Net::FTP couldn't establish connection (or
2722 # failed otherwise) Maybe they are behind a firewall, but they
2723 # gave us a socksified (or other) ftp program...
2726 my($devnull) = $CPAN::Config->{devnull} || "";
2728 my($aslocal_dir) = File::Basename::dirname($aslocal);
2729 File::Path::mkpath($aslocal_dir);
2730 HOSTHARD: for $i (@$host_seq) {
2731 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2732 $url .= "/" unless substr($url,-1) eq "/";
2734 my($proto,$host,$dir,$getfile);
2736 # Courtesy Mark Conty mark_conty@cargill.com change from
2737 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2739 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
2740 # proto not yet used
2741 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
2743 next HOSTHARD; # who said, we could ftp anything except ftp?
2745 next HOSTHARD if $proto eq "file"; # file URLs would have had
2746 # success above. Likely a bogus URL
2748 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
2750 # Try the most capable first and leave ncftp* for last as it only
2752 for my $f (qw(curl wget lynx ncftpget ncftp)) {
2753 my $funkyftp = $CPAN::Config->{$f};
2754 next unless defined $funkyftp;
2755 next if $funkyftp =~ /^\s*$/;
2757 my($asl_ungz, $asl_gz);
2758 ($asl_ungz = $aslocal) =~ s/\.gz//;
2759 $asl_gz = "$asl_ungz.gz";
2761 my($src_switch) = "";
2763 my($stdout_redir) = " > $asl_ungz";
2765 $src_switch = " -source";
2766 } elsif ($f eq "ncftp"){
2767 $src_switch = " -c";
2768 } elsif ($f eq "wget"){
2769 $src_switch = " -O $asl_ungz";
2771 } elsif ($f eq 'curl'){
2772 $src_switch = ' -L';
2775 if ($f eq "ncftpget"){
2776 $chdir = "cd $aslocal_dir && ";
2779 $CPAN::Frontend->myprint(
2781 Trying with "$funkyftp$src_switch" to get
2785 "$chdir$funkyftp$src_switch \"$url\" $devnull$stdout_redir";
2786 $self->debug("system[$system]") if $CPAN::DEBUG;
2788 if (($wstatus = system($system)) == 0
2791 -s $asl_ungz # lynx returns 0 when it fails somewhere
2797 } elsif ($asl_ungz ne $aslocal) {
2798 # test gzip integrity
2799 if (CPAN::Tarzip->gtest($asl_ungz)) {
2800 # e.g. foo.tar is gzipped --> foo.tar.gz
2801 rename $asl_ungz, $aslocal;
2803 CPAN::Tarzip->gzip($asl_ungz,$asl_gz);
2808 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2810 -f $asl_ungz && -s _ == 0;
2811 my $gz = "$aslocal.gz";
2812 my $gzurl = "$url.gz";
2813 $CPAN::Frontend->myprint(
2815 Trying with "$funkyftp$src_switch" to get
2818 my($system) = "$funkyftp$src_switch \"$url.gz\" $devnull > $asl_gz";
2819 $self->debug("system[$system]") if $CPAN::DEBUG;
2821 if (($wstatus = system($system)) == 0
2825 # test gzip integrity
2826 if (CPAN::Tarzip->gtest($asl_gz)) {
2827 CPAN::Tarzip->gunzip($asl_gz,$aslocal);
2829 # somebody uncompressed file for us?
2830 rename $asl_ungz, $aslocal;
2835 unlink $asl_gz if -f $asl_gz;
2838 my $estatus = $wstatus >> 8;
2839 my $size = -f $aslocal ?
2840 ", left\n$aslocal with size ".-s _ :
2841 "\nWarning: expected file [$aslocal] doesn't exist";
2842 $CPAN::Frontend->myprint(qq{
2843 System call "$system"
2844 returned status $estatus (wstat $wstatus)$size
2847 return if $CPAN::Signal;
2848 } # transfer programs
2853 my($self,$host_seq,$file,$aslocal) = @_;
2856 my($aslocal_dir) = File::Basename::dirname($aslocal);
2857 File::Path::mkpath($aslocal_dir);
2858 my $ftpbin = $CPAN::Config->{ftp};
2859 HOSTHARDEST: for $i (@$host_seq) {
2860 unless (length $ftpbin && MM->maybe_command($ftpbin)) {
2861 $CPAN::Frontend->myprint("No external ftp command available\n\n");
2864 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2865 $url .= "/" unless substr($url,-1) eq "/";
2867 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
2868 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2871 my($host,$dir,$getfile) = ($1,$2,$3);
2873 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
2874 $ctime,$blksize,$blocks) = stat($aslocal);
2875 $timestamp = $mtime ||= 0;
2876 my($netrc) = CPAN::FTP::netrc->new;
2877 my($netrcfile) = $netrc->netrc;
2878 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
2879 my $targetfile = File::Basename::basename($aslocal);
2885 map("cd $_", split /\//, $dir), # RFC 1738
2887 "get $getfile $targetfile",
2891 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
2892 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
2893 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
2895 $netrc->contains($host))) if $CPAN::DEBUG;
2896 if ($netrc->protected) {
2897 $CPAN::Frontend->myprint(qq{
2898 Trying with external ftp to get
2900 As this requires some features that are not thoroughly tested, we\'re
2901 not sure, that we get it right....
2905 $self->talk_ftp("$ftpbin$verbose $host",
2907 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2908 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2910 if ($mtime > $timestamp) {
2911 $CPAN::Frontend->myprint("GOT $aslocal\n");
2915 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
2917 return if $CPAN::Signal;
2919 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
2920 qq{correctly protected.\n});
2923 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
2924 nor does it have a default entry\n");
2927 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
2928 # then and login manually to host, using e-mail as
2930 $CPAN::Frontend->myprint(qq{Issuing "$ftpbin$verbose -n"\n});
2934 "user anonymous $Config::Config{'cf_email'}"
2936 $self->talk_ftp("$ftpbin$verbose -n", @dialog);
2937 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2938 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2940 if ($mtime > $timestamp) {
2941 $CPAN::Frontend->myprint("GOT $aslocal\n");
2945 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
2947 return if $CPAN::Signal;
2948 $CPAN::Frontend->myprint("Can't access URL $url.\n\n");
2954 my($self,$command,@dialog) = @_;
2955 my $fh = FileHandle->new;
2956 $fh->open("|$command") or die "Couldn't open ftp: $!";
2957 foreach (@dialog) { $fh->print("$_\n") }
2958 $fh->close; # Wait for process to complete
2960 my $estatus = $wstatus >> 8;
2961 $CPAN::Frontend->myprint(qq{
2962 Subprocess "|$command"
2963 returned status $estatus (wstat $wstatus)
2967 # find2perl needs modularization, too, all the following is stolen
2971 my($self,$name) = @_;
2972 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
2973 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
2975 my($perms,%user,%group);
2979 $blocks = int(($blocks + 1) / 2);
2982 $blocks = int(($sizemm + 1023) / 1024);
2985 if (-f _) { $perms = '-'; }
2986 elsif (-d _) { $perms = 'd'; }
2987 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
2988 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
2989 elsif (-p _) { $perms = 'p'; }
2990 elsif (-S _) { $perms = 's'; }
2991 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
2993 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
2994 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
2995 my $tmpmode = $mode;
2996 my $tmp = $rwx[$tmpmode & 7];
2998 $tmp = $rwx[$tmpmode & 7] . $tmp;
3000 $tmp = $rwx[$tmpmode & 7] . $tmp;
3001 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
3002 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
3003 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
3006 my $user = $user{$uid} || $uid; # too lazy to implement lookup
3007 my $group = $group{$gid} || $gid;
3009 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
3011 my($moname) = $moname[$mon];
3012 if (-M _ > 365.25 / 2) {
3013 $timeyear = $year + 1900;
3016 $timeyear = sprintf("%02d:%02d", $hour, $min);
3019 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
3033 package CPAN::FTP::netrc;
3037 my $file = File::Spec->catfile($ENV{HOME},".netrc");
3039 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
3040 $atime,$mtime,$ctime,$blksize,$blocks)
3045 my($fh,@machines,$hasdefault);
3047 $fh = FileHandle->new or die "Could not create a filehandle";
3049 if($fh->open($file)){
3050 $protected = ($mode & 077) == 0;
3052 NETRC: while (<$fh>) {
3053 my(@tokens) = split " ", $_;
3054 TOKEN: while (@tokens) {
3055 my($t) = shift @tokens;
3056 if ($t eq "default"){
3060 last TOKEN if $t eq "macdef";
3061 if ($t eq "machine") {
3062 push @machines, shift @tokens;
3067 $file = $hasdefault = $protected = "";
3071 'mach' => [@machines],
3073 'hasdefault' => $hasdefault,
3074 'protected' => $protected,
3078 # CPAN::FTP::hasdefault;
3079 sub hasdefault { shift->{'hasdefault'} }
3080 sub netrc { shift->{'netrc'} }
3081 sub protected { shift->{'protected'} }
3083 my($self,$mach) = @_;
3084 for ( @{$self->{'mach'}} ) {
3085 return 1 if $_ eq $mach;
3090 package CPAN::Complete;
3093 my($text, $line, $start, $end) = @_;
3094 my(@perlret) = cpl($text, $line, $start);
3095 # find longest common match. Can anybody show me how to peruse
3096 # T::R::Gnu to have this done automatically? Seems expensive.
3097 return () unless @perlret;
3098 my($newtext) = $text;
3099 for (my $i = length($text)+1;;$i++) {
3100 last unless length($perlret[0]) && length($perlret[0]) >= $i;
3101 my $try = substr($perlret[0],0,$i);
3102 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
3103 # warn "try[$try]tries[@tries]";
3104 if (@tries == @perlret) {
3110 ($newtext,@perlret);
3113 #-> sub CPAN::Complete::cpl ;
3115 my($word,$line,$pos) = @_;
3119 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3121 if ($line =~ s/^(force\s*)//) {
3126 @return = grep /^$word/, @CPAN::Complete::COMMANDS;
3127 } elsif ( $line !~ /^[\!abcdghimorutl]/ ) {
3129 } elsif ($line =~ /^(a|ls)\s/) {
3130 @return = cplx('CPAN::Author',uc($word));
3131 } elsif ($line =~ /^b\s/) {
3132 CPAN::Shell->local_bundles;
3133 @return = cplx('CPAN::Bundle',$word);
3134 } elsif ($line =~ /^d\s/) {
3135 @return = cplx('CPAN::Distribution',$word);
3136 } elsif ($line =~ m/^(
3137 [mru]|make|clean|dump|get|test|install|readme|look|cvs_import|perldoc|recent
3139 if ($word =~ /^Bundle::/) {
3140 CPAN::Shell->local_bundles;
3142 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
3143 } elsif ($line =~ /^i\s/) {
3144 @return = cpl_any($word);
3145 } elsif ($line =~ /^reload\s/) {
3146 @return = cpl_reload($word,$line,$pos);
3147 } elsif ($line =~ /^o\s/) {
3148 @return = cpl_option($word,$line,$pos);
3149 } elsif ($line =~ m/^\S+\s/ ) {
3150 # fallback for future commands and what we have forgotten above
3151 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
3158 #-> sub CPAN::Complete::cplx ;
3160 my($class, $word) = @_;
3161 # I believed for many years that this was sorted, today I
3162 # realized, it wasn't sorted anymore. Now (rev 1.301 / v 1.55) I
3163 # make it sorted again. Maybe sort was dropped when GNU-readline
3164 # support came in? The RCS file is difficult to read on that:-(
3165 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
3168 #-> sub CPAN::Complete::cpl_any ;
3172 cplx('CPAN::Author',$word),
3173 cplx('CPAN::Bundle',$word),
3174 cplx('CPAN::Distribution',$word),
3175 cplx('CPAN::Module',$word),
3179 #-> sub CPAN::Complete::cpl_reload ;
3181 my($word,$line,$pos) = @_;
3183 my(@words) = split " ", $line;
3184 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3185 my(@ok) = qw(cpan index);
3186 return @ok if @words == 1;
3187 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
3190 #-> sub CPAN::Complete::cpl_option ;
3192 my($word,$line,$pos) = @_;
3194 my(@words) = split " ", $line;
3195 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
3196 my(@ok) = qw(conf debug);
3197 return @ok if @words == 1;
3198 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
3200 } elsif ($words[1] eq 'index') {
3202 } elsif ($words[1] eq 'conf') {
3203 return CPAN::Config::cpl(@_);
3204 } elsif ($words[1] eq 'debug') {
3205 return sort grep /^\Q$word\E/,
3206 sort keys %CPAN::DEBUG, 'all';
3210 package CPAN::Index;
3212 #-> sub CPAN::Index::force_reload ;
3215 $CPAN::Index::LAST_TIME = 0;
3219 #-> sub CPAN::Index::reload ;
3221 my($cl,$force) = @_;
3224 # XXX check if a newer one is available. (We currently read it
3225 # from time to time)
3226 for ($CPAN::Config->{index_expire}) {
3227 $_ = 0.001 unless $_ && $_ > 0.001;
3229 unless (1 || $CPAN::Have_warned->{readmetadatacache}++) {
3230 # debug here when CPAN doesn't seem to read the Metadata
3232 Carp::cluck("META-PROTOCOL[$CPAN::META->{PROTOCOL}]");
3234 unless ($CPAN::META->{PROTOCOL}) {
3235 $cl->read_metadata_cache;
3236 $CPAN::META->{PROTOCOL} ||= "1.0";
3238 if ( $CPAN::META->{PROTOCOL} < PROTOCOL ) {
3239 # warn "Setting last_time to 0";
3240 $LAST_TIME = 0; # No warning necessary
3242 return if $LAST_TIME + $CPAN::Config->{index_expire}*86400 > $time
3245 # IFF we are developing, it helps to wipe out the memory
3246 # between reloads, otherwise it is not what a user expects.
3247 undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
3248 $CPAN::META = CPAN->new;
3252 local $LAST_TIME = $time;
3253 local $CPAN::META->{PROTOCOL} = PROTOCOL;
3255 my $needshort = $^O eq "dos";
3257 $cl->rd_authindex($cl
3259 "authors/01mailrc.txt.gz",
3261 File::Spec->catfile('authors', '01mailrc.gz') :
3262 File::Spec->catfile('authors', '01mailrc.txt.gz'),
3265 $debug = "timing reading 01[".($t2 - $time)."]";
3267 return if $CPAN::Signal; # this is sometimes lengthy
3268 $cl->rd_modpacks($cl
3270 "modules/02packages.details.txt.gz",
3272 File::Spec->catfile('modules', '02packag.gz') :
3273 File::Spec->catfile('modules', '02packages.details.txt.gz'),
3276 $debug .= "02[".($t2 - $time)."]";
3278 return if $CPAN::Signal; # this is sometimes lengthy
3281 "modules/03modlist.data.gz",
3283 File::Spec->catfile('modules', '03mlist.gz') :
3284 File::Spec->catfile('modules', '03modlist.data.gz'),
3286 $cl->write_metadata_cache;
3288 $debug .= "03[".($t2 - $time)."]";
3290 CPAN->debug($debug) if $CPAN::DEBUG;
3293 $CPAN::META->{PROTOCOL} = PROTOCOL;
3296 #-> sub CPAN::Index::reload_x ;
3298 my($cl,$wanted,$localname,$force) = @_;
3299 $force |= 2; # means we're dealing with an index here
3300 CPAN::Config->load; # we should guarantee loading wherever we rely
3302 $localname ||= $wanted;
3303 my $abs_wanted = File::Spec->catfile($CPAN::Config->{'keep_source_where'},
3307 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
3310 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
3311 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
3312 qq{day$s. I\'ll use that.});
3315 $force |= 1; # means we're quite serious about it.
3317 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
3320 #-> sub CPAN::Index::rd_authindex ;
3322 my($cl, $index_target) = @_;
3324 return unless defined $index_target;
3325 $CPAN::Frontend->myprint("Going to read $index_target\n");
3327 tie *FH, 'CPAN::Tarzip', $index_target;
3329 push @lines, split /\012/ while <FH>;
3331 my($userid,$fullname,$email) =
3332 m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
3333 next unless $userid && $fullname && $email;
3335 # instantiate an author object
3336 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
3337 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
3338 return if $CPAN::Signal;
3343 my($self,$dist) = @_;
3344 $dist = $self->{'id'} unless defined $dist;
3345 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
3349 #-> sub CPAN::Index::rd_modpacks ;
3351 my($self, $index_target) = @_;
3353 return unless defined $index_target;
3354 $CPAN::Frontend->myprint("Going to read $index_target\n");
3355 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3357 while ($_ = $fh->READLINE) {
3359 my @ls = map {"$_\n"} split /\n/, $_;
3360 unshift @ls, "\n" x length($1) if /^(\n+)/;
3364 my($line_count,$last_updated);
3366 my $shift = shift(@lines);
3367 last if $shift =~ /^\s*$/;
3368 $shift =~ /^Line-Count:\s+(\d+)/ and $line_count = $1;
3369 $shift =~ /^Last-Updated:\s+(.+)/ and $last_updated = $1;
3371 if (not defined $line_count) {
3373 warn qq{Warning: Your $index_target does not contain a Line-Count header.
3374 Please check the validity of the index file by comparing it to more
3375 than one CPAN mirror. I'll continue but problems seem likely to
3380 } elsif ($line_count != scalar @lines) {
3382 warn sprintf qq{Warning: Your %s
3383 contains a Line-Count header of %d but I see %d lines there. Please
3384 check the validity of the index file by comparing it to more than one
3385 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
3386 $index_target, $line_count, scalar(@lines);
3389 if (not defined $last_updated) {
3391 warn qq{Warning: Your $index_target does not contain a Last-Updated header.
3392 Please check the validity of the index file by comparing it to more
3393 than one CPAN mirror. I'll continue but problems seem likely to
3401 ->myprint(sprintf qq{ Database was generated on %s\n},
3403 $DATE_OF_02 = $last_updated;
3405 if ($CPAN::META->has_inst('HTTP::Date')) {
3407 my($age) = (time - HTTP::Date::str2time($last_updated))/3600/24;
3412 qq{Warning: This index file is %d days old.
3413 Please check the host you chose as your CPAN mirror for staleness.
3414 I'll continue but problems seem likely to happen.\a\n},
3419 $CPAN::Frontend->myprint(" HTTP::Date not available\n");
3424 # A necessity since we have metadata_cache: delete what isn't
3426 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
3427 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
3431 # before 1.56 we split into 3 and discarded the rest. From
3432 # 1.57 we assign remaining text to $comment thus allowing to
3433 # influence isa_perl
3434 my($mod,$version,$dist,$comment) = split " ", $_, 4;
3435 my($bundle,$id,$userid);
3437 if ($mod eq 'CPAN' &&
3439 CPAN::Queue->exists('Bundle::CPAN') ||
3440 CPAN::Queue->exists('CPAN')
3444 if ($version > $CPAN::VERSION){
3445 $CPAN::Frontend->myprint(qq{
3446 There's a new CPAN.pm version (v$version) available!
3447 [Current version is v$CPAN::VERSION]
3448 You might want to try
3449 install Bundle::CPAN
3451 without quitting the current session. It should be a seamless upgrade
3452 while we are running...
3455 $CPAN::Frontend->myprint(qq{\n});
3457 last if $CPAN::Signal;
3458 } elsif ($mod =~ /^Bundle::(.*)/) {
3463 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
3464 # Let's make it a module too, because bundles have so much
3465 # in common with modules.
3467 # Changed in 1.57_63: seems like memory bloat now without
3468 # any value, so commented out
3470 # $CPAN::META->instance('CPAN::Module',$mod);
3474 # instantiate a module object
3475 $id = $CPAN::META->instance('CPAN::Module',$mod);
3479 # Although CPAN prohibits same name with different version the
3480 # indexer may have changed the version for the same distro
3481 # since the last time ("Force Reindexing" feature)
3482 if ($id->cpan_file ne $dist
3484 $id->cpan_version ne $version
3486 $userid = $id->userid || $self->userid($dist);
3488 'CPAN_USERID' => $userid,
3489 'CPAN_VERSION' => $version,
3490 'CPAN_FILE' => $dist,
3494 # instantiate a distribution object
3495 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
3496 # we do not need CONTAINSMODS unless we do something with
3497 # this dist, so we better produce it on demand.
3499 ## my $obj = $CPAN::META->instance(
3500 ## 'CPAN::Distribution' => $dist
3502 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
3504 $CPAN::META->instance(
3505 'CPAN::Distribution' => $dist
3507 'CPAN_USERID' => $userid,
3508 'CPAN_COMMENT' => $comment,
3512 for my $name ($mod,$dist) {
3513 CPAN->debug("exists name[$name]") if $CPAN::DEBUG;
3514 $exists{$name} = undef;
3517 return if $CPAN::Signal;
3521 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
3522 for my $o ($CPAN::META->all_objects($class)) {
3523 next if exists $exists{$o->{ID}};
3524 $CPAN::META->delete($class,$o->{ID});
3525 CPAN->debug("deleting ID[$o->{ID}] in class[$class]")
3532 #-> sub CPAN::Index::rd_modlist ;
3534 my($cl,$index_target) = @_;
3535 return unless defined $index_target;
3536 $CPAN::Frontend->myprint("Going to read $index_target\n");
3537 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3540 while ($_ = $fh->READLINE) {
3542 my @ls = map {"$_\n"} split /\n/, $_;
3543 unshift @ls, "\n" x length($1) if /^(\n+)/;
3547 my $shift = shift(@eval);
3548 if ($shift =~ /^Date:\s+(.*)/){
3549 return if $DATE_OF_03 eq $1;
3552 last if $shift =~ /^\s*$/;
3555 push @eval, q{CPAN::Modulelist->data;};
3557 my($comp) = Safe->new("CPAN::Safe1");
3558 my($eval) = join("", @eval);
3559 my $ret = $comp->reval($eval);
3560 Carp::confess($@) if $@;
3561 return if $CPAN::Signal;
3563 my $obj = $CPAN::META->instance("CPAN::Module",$_);
3564 delete $ret->{$_}{modid}; # not needed here, maybe elsewhere
3565 $obj->set(%{$ret->{$_}});
3566 return if $CPAN::Signal;
3570 #-> sub CPAN::Index::write_metadata_cache ;
3571 sub write_metadata_cache {
3573 return unless $CPAN::Config->{'cache_metadata'};
3574 return unless $CPAN::META->has_usable("Storable");
3576 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
3577 CPAN::Distribution)) {
3578 $cache->{$k} = $CPAN::META->{readonly}{$k}; # unsafe meta access, ok
3580 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3581 $cache->{last_time} = $LAST_TIME;
3582 $cache->{DATE_OF_02} = $DATE_OF_02;
3583 $cache->{PROTOCOL} = PROTOCOL;
3584 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
3585 eval { Storable::nstore($cache, $metadata_file) };
3586 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
3589 #-> sub CPAN::Index::read_metadata_cache ;
3590 sub read_metadata_cache {
3592 return unless $CPAN::Config->{'cache_metadata'};
3593 return unless $CPAN::META->has_usable("Storable");
3594 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3595 return unless -r $metadata_file and -f $metadata_file;
3596 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
3598 eval { $cache = Storable::retrieve($metadata_file) };
3599 $CPAN::Frontend->mywarn($@) if $@; # ?? missing "\n" after $@ in mywarn ??
3600 if (!$cache || ref $cache ne 'HASH'){
3604 if (exists $cache->{PROTOCOL}) {
3605 if (PROTOCOL > $cache->{PROTOCOL}) {
3606 $CPAN::Frontend->mywarn(sprintf("Ignoring Metadata cache written ".
3607 "with protocol v%s, requiring v%s\n",
3614 $CPAN::Frontend->mywarn("Ignoring Metadata cache written ".
3615 "with protocol v1.0\n");
3620 while(my($class,$v) = each %$cache) {
3621 next unless $class =~ /^CPAN::/;
3622 $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok
3623 while (my($id,$ro) = each %$v) {
3624 $CPAN::META->{readwrite}{$class}{$id} ||=
3625 $class->new(ID=>$id, RO=>$ro);
3630 unless ($clcnt) { # sanity check
3631 $CPAN::Frontend->myprint("Warning: Found no data in $metadata_file\n");
3634 if ($idcnt < 1000) {
3635 $CPAN::Frontend->myprint("Warning: Found only $idcnt objects ".
3636 "in $metadata_file\n");
3639 $CPAN::META->{PROTOCOL} ||=
3640 $cache->{PROTOCOL}; # reading does not up or downgrade, but it
3641 # does initialize to some protocol
3642 $LAST_TIME = $cache->{last_time};
3643 $DATE_OF_02 = $cache->{DATE_OF_02};
3644 $CPAN::Frontend->myprint(" Database was generated on $DATE_OF_02\n")
3645 if defined $DATE_OF_02; # An old cache may not contain DATE_OF_02
3649 package CPAN::InfoObj;
3654 $self->{RO}{CPAN_USERID}
3657 sub id { shift->{ID}; }
3659 #-> sub CPAN::InfoObj::new ;
3661 my $this = bless {}, shift;
3666 # The set method may only be used by code that reads index data or
3667 # otherwise "objective" data from the outside world. All session
3668 # related material may do anything else with instance variables but
3669 # must not touch the hash under the RO attribute. The reason is that
3670 # the RO hash gets written to Metadata file and is thus persistent.
3672 #-> sub CPAN::InfoObj::set ;
3674 my($self,%att) = @_;
3675 my $class = ref $self;
3677 # This must be ||=, not ||, because only if we write an empty
3678 # reference, only then the set method will write into the readonly
3679 # area. But for Distributions that spring into existence, maybe
3680 # because of a typo, we do not like it that they are written into
3681 # the readonly area and made permanent (at least for a while) and
3682 # that is why we do not "allow" other places to call ->set.
3683 unless ($self->id) {
3684 CPAN->debug("Bug? Empty ID, rejecting");
3687 my $ro = $self->{RO} =
3688 $CPAN::META->{readonly}{$class}{$self->id} ||= {};
3690 while (my($k,$v) = each %att) {
3695 #-> sub CPAN::InfoObj::as_glimpse ;
3699 my $class = ref($self);
3700 $class =~ s/^CPAN:://;
3701 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
3705 #-> sub CPAN::InfoObj::as_string ;
3709 my $class = ref($self);
3710 $class =~ s/^CPAN:://;
3711 push @m, $class, " id = $self->{ID}\n";
3712 for (sort keys %{$self->{RO}}) {
3713 # next if m/^(ID|RO)$/;
3715 if ($_ eq "CPAN_USERID") {
3716 $extra .= " (".$self->author;
3717 my $email; # old perls!
3718 if ($email = $CPAN::META->instance("CPAN::Author",
3721 $extra .= " <$email>";
3723 $extra .= " <no email>";
3726 } elsif ($_ eq "FULLNAME") { # potential UTF-8 conversion
3727 push @m, sprintf " %-12s %s\n", $_, $self->fullname;
3730 next unless defined $self->{RO}{$_};
3731 push @m, sprintf " %-12s %s%s\n", $_, $self->{RO}{$_}, $extra;
3733 for (sort keys %$self) {
3734 next if m/^(ID|RO)$/;
3735 if (ref($self->{$_}) eq "ARRAY") {
3736 push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
3737 } elsif (ref($self->{$_}) eq "HASH") {
3741 join(" ",keys %{$self->{$_}}),
3744 push @m, sprintf " %-12s %s\n", $_, $self->{$_};
3750 #-> sub CPAN::InfoObj::author ;
3753 $CPAN::META->instance("CPAN::Author",$self->cpan_userid)->fullname;
3756 #-> sub CPAN::InfoObj::dump ;
3759 require Data::Dumper;
3760 print Data::Dumper::Dumper($self);
3763 package CPAN::Author;
3765 #-> sub CPAN::Author::id
3768 my $id = $self->{ID};
3769 $CPAN::Frontend->mydie("Illegal author id[$id]") unless $id =~ /^[A-Z]/;
3773 #-> sub CPAN::Author::as_glimpse ;
3777 my $class = ref($self);
3778 $class =~ s/^CPAN:://;
3779 push @m, sprintf(qq{%-15s %s ("%s" <%s>)\n},
3787 #-> sub CPAN::Author::fullname ;
3789 shift->{RO}{FULLNAME};
3793 #-> sub CPAN::Author::email ;
3794 sub email { shift->{RO}{EMAIL}; }
3796 #-> sub CPAN::Author::ls ;
3799 my $silent = shift || 0;
3802 # adapted from CPAN::Distribution::verifyMD5 ;
3803 my(@csf); # chksumfile
3804 @csf = $self->id =~ /(.)(.)(.*)/;
3805 $csf[1] = join "", @csf[0,1];
3806 $csf[2] = join "", @csf[1,2]; # ("A","AN","ANDK")
3808 @dl = $self->dir_listing([$csf[0],"CHECKSUMS"], 0, 1);
3809 unless (grep {$_->[2] eq $csf[1]} @dl) {
3810 $CPAN::Frontend->myprint("Directory $csf[1]/ does not exist\n") unless $silent ;
3813 @dl = $self->dir_listing([@csf[0,1],"CHECKSUMS"], 0, 1);
3814 unless (grep {$_->[2] eq $csf[2]} @dl) {
3815 $CPAN::Frontend->myprint("Directory $id/ does not exist\n") unless $silent;
3818 @dl = $self->dir_listing([@csf,"CHECKSUMS"], 1, 1);
3819 $CPAN::Frontend->myprint(join "", map {
3820 sprintf("%8d %10s %s/%s\n", $_->[0], $_->[1], $id, $_->[2])
3821 } sort { $a->[2] cmp $b->[2] } @dl) unless $silent;
3824 # returns an array of arrays, the latter contain (size,mtime,filename)
3825 #-> sub CPAN::Author::dir_listing ;
3828 my $chksumfile = shift;
3829 my $recursive = shift;
3830 my $may_ftp = shift;
3832 File::Spec->catfile($CPAN::Config->{keep_source_where},
3833 "authors", "id", @$chksumfile);
3837 # Purge and refetch old (pre-PGP) CHECKSUMS; they are a security
3838 # hazard. (Without GPG installed they are not that much better,
3840 $fh = FileHandle->new;
3841 if (open($fh, $lc_want)) {
3842 my $line = <$fh>; close $fh;
3843 unlink($lc_want) unless $line =~ /PGP/;
3847 # connect "force" argument with "index_expire".
3849 if (my @stat = stat $lc_want) {
3850 $force = $stat[9] + $CPAN::Config->{index_expire}*86400 <= time;
3854 $lc_file = CPAN::FTP->localize(
3855 "authors/id/@$chksumfile",
3860 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
3861 $chksumfile->[-1] .= ".gz";
3862 $lc_file = CPAN::FTP->localize("authors/id/@$chksumfile",
3865 $lc_file =~ s{\.gz(?!\n)\Z}{}; #};
3866 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
3872 $lc_file = $lc_want;
3873 # we *could* second-guess and if the user has a file: URL,
3874 # then we could look there. But on the other hand, if they do
3875 # have a file: URL, wy did they choose to set
3876 # $CPAN::Config->{show_upload_date} to false?
3879 # adapted from CPAN::Distribution::MD5_check_file ;
3880 $fh = FileHandle->new;
3882 if (open $fh, $lc_file){
3885 $eval =~ s/\015?\012/\n/g;
3887 my($comp) = Safe->new();
3888 $cksum = $comp->reval($eval);
3890 rename $lc_file, "$lc_file.bad";
3891 Carp::confess($@) if $@;
3893 } elsif ($may_ftp) {
3894 Carp::carp "Could not open $lc_file for reading.";
3896 # Maybe should warn: "You may want to set show_upload_date to a true value"
3900 for $f (sort keys %$cksum) {
3901 if (exists $cksum->{$f}{isdir}) {
3903 my(@dir) = @$chksumfile;
3905 push @dir, $f, "CHECKSUMS";
3907 [$_->[0], $_->[1], "$f/$_->[2]"]
3908 } $self->dir_listing(\@dir,1,$may_ftp);
3910 push @result, [ 0, "-", $f ];
3914 ($cksum->{$f}{"size"}||0),
3915 $cksum->{$f}{"mtime"}||"---",
3923 package CPAN::Distribution;
3926 sub cpan_comment { shift->{RO}{CPAN_COMMENT} }
3930 delete $self->{later};
3933 # CPAN::Distribution::normalize
3936 $s = $self->id unless defined $s;
3940 $s !~ m|[A-Z]/[A-Z-]{2}/[A-Z-]{2,}/|
3942 return $s if $s =~ m:^N/A|^Contact Author: ;
3943 $s =~ s|^(.)(.)([^/]*/)(.+)$|$1/$1$2/$1$2$3$4| or
3944 $CPAN::Frontend->mywarn("Strange distribution name [$s]\n");
3945 CPAN->debug("s[$s]") if $CPAN::DEBUG;
3950 #-> sub CPAN::Distribution::color_cmd_tmps ;
3951 sub color_cmd_tmps {
3953 my($depth) = shift || 0;
3954 my($color) = shift || 0;
3955 my($ancestors) = shift || [];
3956 # a distribution needs to recurse into its prereq_pms
3958 return if exists $self->{incommandcolor}
3959 && $self->{incommandcolor}==$color;
3961 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
3963 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
3964 my $prereq_pm = $self->prereq_pm;
3965 if (defined $prereq_pm) {
3966 for my $pre (keys %$prereq_pm) {
3967 my $premo = CPAN::Shell->expand("Module",$pre);
3968 $premo->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
3972 delete $self->{sponsored_mods};
3973 delete $self->{badtestcnt};
3975 $self->{incommandcolor} = $color;
3978 #-> sub CPAN::Distribution::as_string ;
3981 $self->containsmods;
3983 $self->SUPER::as_string(@_);
3986 #-> sub CPAN::Distribution::containsmods ;
3989 return keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
3990 my $dist_id = $self->{ID};
3991 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
3992 my $mod_file = $mod->cpan_file or next;
3993 my $mod_id = $mod->{ID} or next;
3994 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
3996 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
3998 keys %{$self->{CONTAINSMODS}};
4001 #-> sub CPAN::Distribution::upload_date ;
4004 return $self->{UPLOAD_DATE} if exists $self->{UPLOAD_DATE};
4005 my(@local_wanted) = split(/\//,$self->id);
4006 my $filename = pop @local_wanted;
4007 push @local_wanted, "CHECKSUMS";
4008 my $author = CPAN::Shell->expand("Author",$self->cpan_userid);
4009 return unless $author;
4010 my @dl = $author->dir_listing(\@local_wanted,0,$CPAN::Config->{show_upload_date});
4012 my($dirent) = grep { $_->[2] eq $filename } @dl;
4013 # warn sprintf "dirent[%s]id[%s]", $dirent, $self->id;
4014 return unless $dirent->[1];
4015 return $self->{UPLOAD_DATE} = $dirent->[1];
4018 #-> sub CPAN::Distribution::uptodate ;
4022 foreach $c ($self->containsmods) {
4023 my $obj = CPAN::Shell->expandany($c);
4024 return 0 unless $obj->uptodate;
4029 #-> sub CPAN::Distribution::called_for ;
4032 $self->{CALLED_FOR} = $id if defined $id;
4033 return $self->{CALLED_FOR};
4036 #-> sub CPAN::Distribution::safe_chdir ;
4038 my($self,$todir) = @_;
4039 # we die if we cannot chdir and we are debuggable
4040 Carp::confess("safe_chdir called without todir argument")
4041 unless defined $todir and length $todir;
4043 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
4046 my $cwd = CPAN::anycwd();
4047 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
4048 qq{to todir[$todir]: $!});
4052 #-> sub CPAN::Distribution::get ;
4057 exists $self->{'build_dir'} and push @e,
4058 "Is already unwrapped into directory $self->{'build_dir'}";
4059 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4061 my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
4064 # Get the file on local disk
4069 File::Spec->catfile(
4070 $CPAN::Config->{keep_source_where},
4073 split(/\//,$self->id)
4076 $self->debug("Doing localize") if $CPAN::DEBUG;
4077 unless ($local_file =
4078 CPAN::FTP->localize("authors/id/$self->{ID}",
4081 if ($CPAN::Index::DATE_OF_02) {
4082 $note = "Note: Current database in memory was generated ".
4083 "on $CPAN::Index::DATE_OF_02\n";
4085 $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n$note");
4087 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
4088 $self->{localfile} = $local_file;
4089 return if $CPAN::Signal;
4094 if ($CPAN::META->has_inst("Digest::MD5")) {
4095 $self->debug("Digest::MD5 is installed, verifying");
4098 $self->debug("Digest::MD5 is NOT installed");
4100 return if $CPAN::Signal;
4103 # Create a clean room and go there
4105 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
4106 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
4107 $self->safe_chdir($builddir);
4108 $self->debug("Removing tmp") if $CPAN::DEBUG;
4109 File::Path::rmtree("tmp");
4110 mkdir "tmp", 0755 or Carp::croak "Couldn't mkdir tmp: $!";
4112 $self->safe_chdir($sub_wd);
4115 $self->safe_chdir("tmp");
4120 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
4121 if ($local_file =~ /(\.tar\.(gz|Z)|\.tgz)(?!\n)\Z/i){
4122 $self->{was_uncompressed}++ unless CPAN::Tarzip->gtest($local_file);
4123 $self->untar_me($local_file);
4124 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
4125 $self->unzip_me($local_file);
4126 } elsif ( $local_file =~ /\.pm(\.(gz|Z))?(?!\n)\Z/) {
4127 $self->{was_uncompressed}++ unless CPAN::Tarzip->gtest($local_file);
4128 $self->debug("calling pm2dir for local_file[$local_file]") if $CPAN::DEBUG;
4129 $self->pm2dir_me($local_file);
4131 $self->{archived} = "NO";
4132 $self->safe_chdir($sub_wd);
4136 # we are still in the tmp directory!
4137 # Let's check if the package has its own directory.
4138 my $dh = DirHandle->new(File::Spec->curdir)
4139 or Carp::croak("Couldn't opendir .: $!");
4140 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
4142 my ($distdir,$packagedir);
4143 if (@readdir == 1 && -d $readdir[0]) {
4144 $distdir = $readdir[0];
4145 $packagedir = File::Spec->catdir($builddir,$distdir);
4146 $self->debug("packagedir[$packagedir]builddir[$builddir]distdir[$distdir]")
4148 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
4150 File::Path::rmtree($packagedir);
4151 File::Copy::move($distdir,$packagedir) or
4152 Carp::confess("Couldn't move $distdir to $packagedir: $!");
4153 $self->debug(sprintf("moved distdir[%s] to packagedir[%s] -e[%s]-d[%s]",
4160 my $userid = $self->cpan_userid;
4162 CPAN->debug("no userid? self[$self]");
4165 my $pragmatic_dir = $userid . '000';
4166 $pragmatic_dir =~ s/\W_//g;
4167 $pragmatic_dir++ while -d "../$pragmatic_dir";
4168 $packagedir = File::Spec->catdir($builddir,$pragmatic_dir);
4169 $self->debug("packagedir[$packagedir]") if $CPAN::DEBUG;
4170 File::Path::mkpath($packagedir);
4172 for $f (@readdir) { # is already without "." and ".."
4173 my $to = File::Spec->catdir($packagedir,$f);
4174 File::Copy::move($f,$to) or Carp::confess("Couldn't move $f to $to: $!");
4178 $self->safe_chdir($sub_wd);
4182 $self->{'build_dir'} = $packagedir;
4183 $self->safe_chdir($builddir);
4184 File::Path::rmtree("tmp");
4186 $self->safe_chdir($packagedir);
4187 if ($CPAN::META->has_inst("Module::Signature")) {
4188 if (-f "SIGNATURE") {
4189 $self->debug("Module::Signature is installed, verifying") if $CPAN::DEBUG;
4190 my $rv = Module::Signature::verify();
4191 if ($rv != Module::Signature::SIGNATURE_OK() and
4192 $rv != Module::Signature::SIGNATURE_MISSING()) {
4193 $CPAN::Frontend->myprint(
4194 qq{\nSignature invalid for }.
4195 qq{distribution file. }.
4196 qq{Please investigate.\n\n}.
4198 $CPAN::META->instance(
4204 my $wrap = qq{I\'d recommend removing $self->{localfile}. Its signature
4205 is invalid. Maybe you have configured your 'urllist' with
4206 a bad URL. Please check this array with 'o conf urllist', and
4208 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
4211 $CPAN::Frontend->myprint(qq{Package came without SIGNATURE\n\n});
4214 $self->debug("Module::Signature is NOT installed") if $CPAN::DEBUG;
4216 $self->safe_chdir($builddir);
4217 return if $CPAN::Signal;
4221 my($mpl) = File::Spec->catfile($packagedir,"Makefile.PL");
4222 my($mpl_exists) = -f $mpl;
4223 unless ($mpl_exists) {
4224 # NFS has been reported to have racing problems after the
4225 # renaming of a directory in some environments.
4228 my $mpldh = DirHandle->new($packagedir)
4229 or Carp::croak("Couldn't opendir $packagedir: $!");
4230 $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read;
4233 unless ($mpl_exists) {
4234 $self->debug(sprintf("makefilepl[%s]anycwd[%s]",
4238 my($configure) = File::Spec->catfile($packagedir,"Configure");
4239 if (-f $configure) {
4240 # do we have anything to do?
4241 $self->{'configure'} = $configure;
4242 } elsif (-f File::Spec->catfile($packagedir,"Makefile")) {
4243 $CPAN::Frontend->myprint(qq{
4244 Package comes with a Makefile and without a Makefile.PL.
4245 We\'ll try to build it with that Makefile then.
4247 $self->{writemakefile} = "YES";
4250 my $cf = $self->called_for || "unknown";
4255 $cf =~ s|[/\\:]||g; # risk of filesystem damage
4256 $cf = "unknown" unless length($cf);
4257 $CPAN::Frontend->myprint(qq{Package seems to come without Makefile.PL.
4258 (The test -f "$mpl" returned false.)
4259 Writing one on our own (setting NAME to $cf)\a\n});
4260 $self->{had_no_makefile_pl}++;
4263 # Writing our own Makefile.PL
4265 my $fh = FileHandle->new;
4267 or Carp::croak("Could not open >$mpl: $!");
4269 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
4270 # because there was no Makefile.PL supplied.
4271 # Autogenerated on: }.scalar localtime().qq{
4273 use ExtUtils::MakeMaker;
4274 WriteMakefile(NAME => q[$cf]);
4284 # CPAN::Distribution::untar_me ;
4286 my($self,$local_file) = @_;
4287 $self->{archived} = "tar";
4288 if (CPAN::Tarzip->untar($local_file)) {
4289 $self->{unwrapped} = "YES";
4291 $self->{unwrapped} = "NO";
4295 # CPAN::Distribution::unzip_me ;
4297 my($self,$local_file) = @_;
4298 $self->{archived} = "zip";
4299 if (CPAN::Tarzip->unzip($local_file)) {
4300 $self->{unwrapped} = "YES";
4302 $self->{unwrapped} = "NO";
4308 my($self,$local_file) = @_;
4309 $self->{archived} = "pm";
4310 my $to = File::Basename::basename($local_file);
4311 if ($to =~ s/\.(gz|Z)(?!\n)\Z//) {
4312 if (CPAN::Tarzip->gunzip($local_file,$to)) {
4313 $self->{unwrapped} = "YES";
4315 $self->{unwrapped} = "NO";
4318 File::Copy::cp($local_file,".");
4319 $self->{unwrapped} = "YES";
4323 #-> sub CPAN::Distribution::new ;
4325 my($class,%att) = @_;
4327 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
4329 my $this = { %att };
4330 return bless $this, $class;
4333 #-> sub CPAN::Distribution::look ;
4337 if ($^O eq 'MacOS') {
4338 $self->Mac::BuildTools::look;
4342 if ( $CPAN::Config->{'shell'} ) {
4343 $CPAN::Frontend->myprint(qq{
4344 Trying to open a subshell in the build directory...
4347 $CPAN::Frontend->myprint(qq{
4348 Your configuration does not define a value for subshells.
4349 Please define it with "o conf shell <your shell>"
4353 my $dist = $self->id;
4355 unless ($dir = $self->dir) {
4358 unless ($dir ||= $self->dir) {
4359 $CPAN::Frontend->mywarn(qq{
4360 Could not determine which directory to use for looking at $dist.
4364 my $pwd = CPAN::anycwd();
4365 $self->safe_chdir($dir);
4366 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
4367 unless (system($CPAN::Config->{'shell'}) == 0) {
4369 $CPAN::Frontend->mywarn("Subprocess shell exit code $code\n");
4371 $self->safe_chdir($pwd);
4374 # CPAN::Distribution::cvs_import ;
4378 my $dir = $self->dir;
4380 my $package = $self->called_for;
4381 my $module = $CPAN::META->instance('CPAN::Module', $package);
4382 my $version = $module->cpan_version;
4384 my $userid = $self->cpan_userid;
4386 my $cvs_dir = (split /\//, $dir)[-1];
4387 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
4389 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
4391 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
4392 if ($cvs_site_perl) {
4393 $cvs_dir = "$cvs_site_perl/$cvs_dir";
4395 my $cvs_log = qq{"imported $package $version sources"};
4396 $version =~ s/\./_/g;
4397 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
4398 "$cvs_dir", $userid, "v$version");
4400 my $pwd = CPAN::anycwd();
4401 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
4403 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
4405 $CPAN::Frontend->myprint(qq{@cmd\n});
4406 system(@cmd) == 0 or
4407 $CPAN::Frontend->mydie("cvs import failed");
4408 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
4411 #-> sub CPAN::Distribution::readme ;
4414 my($dist) = $self->id;
4415 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
4416 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
4419 File::Spec->catfile(
4420 $CPAN::Config->{keep_source_where},
4423 split(/\//,"$sans.readme"),
4425 $self->debug("Doing localize") if $CPAN::DEBUG;
4426 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
4428 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
4430 if ($^O eq 'MacOS') {
4431 Mac::BuildTools::launch_file($local_file);
4435 my $fh_pager = FileHandle->new;
4436 local($SIG{PIPE}) = "IGNORE";
4437 $fh_pager->open("|$CPAN::Config->{'pager'}")
4438 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
4439 my $fh_readme = FileHandle->new;
4440 $fh_readme->open($local_file)
4441 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
4442 $CPAN::Frontend->myprint(qq{
4445 with pager "$CPAN::Config->{'pager'}"
4448 $fh_pager->print(<$fh_readme>);
4452 #-> sub CPAN::Distribution::verifyMD5 ;
4457 $self->{MD5_STATUS} ||= "";
4458 $self->{MD5_STATUS} eq "OK" and push @e, "MD5 Checksum was ok";
4459 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4461 my($lc_want,$lc_file,@local,$basename);
4462 @local = split(/\//,$self->id);
4464 push @local, "CHECKSUMS";
4466 File::Spec->catfile($CPAN::Config->{keep_source_where},
4467 "authors", "id", @local);
4472 $self->MD5_check_file($lc_want)
4474 return $self->{MD5_STATUS} = "OK";
4476 $lc_file = CPAN::FTP->localize("authors/id/@local",
4479 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
4480 $local[-1] .= ".gz";
4481 $lc_file = CPAN::FTP->localize("authors/id/@local",
4484 $lc_file =~ s/\.gz(?!\n)\Z//;
4485 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
4490 $self->MD5_check_file($lc_file);
4493 sub SIG_check_file {
4494 my($self,$chk_file) = @_;
4495 my $rv = eval { Module::Signature::_verify($chk_file) };
4497 if ($rv == Module::Signature::SIGNATURE_OK()) {
4498 $CPAN::Frontend->myprint("Signature for $chk_file ok\n");
4499 return $self->{SIG_STATUS} = "OK";
4501 $CPAN::Frontend->myprint(qq{\nSignature invalid for }.
4502 qq{distribution file. }.
4503 qq{Please investigate.\n\n}.
4505 $CPAN::META->instance(
4510 my $wrap = qq{I\'d recommend removing $chk_file. Its signature
4511 is invalid. Maybe you have configured your 'urllist' with
4512 a bad URL. Please check this array with 'o conf urllist', and
4515 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
4519 #-> sub CPAN::Distribution::MD5_check_file ;
4520 sub MD5_check_file {
4521 my($self,$chk_file) = @_;
4522 my($cksum,$file,$basename);
4524 if ($CPAN::META->has_inst("Module::Signature") and Module::Signature->VERSION >= 0.26) {
4525 $self->debug("Module::Signature is installed, verifying");
4526 $self->SIG_check_file($chk_file);
4528 $self->debug("Module::Signature is NOT installed");
4531 $file = $self->{localfile};
4532 $basename = File::Basename::basename($file);
4533 my $fh = FileHandle->new;
4534 if (open $fh, $chk_file){
4537 $eval =~ s/\015?\012/\n/g;
4539 my($comp) = Safe->new();
4540 $cksum = $comp->reval($eval);
4542 rename $chk_file, "$chk_file.bad";
4543 Carp::confess($@) if $@;
4546 Carp::carp "Could not open $chk_file for reading";
4549 if (exists $cksum->{$basename}{md5}) {
4550 $self->debug("Found checksum for $basename:" .
4551 "$cksum->{$basename}{md5}\n") if $CPAN::DEBUG;
4555 my $eq = $self->eq_MD5($fh,$cksum->{$basename}{'md5'});
4557 $fh = CPAN::Tarzip->TIEHANDLE($file);
4560 # had to inline it, when I tied it, the tiedness got lost on
4561 # the call to eq_MD5. (Jan 1998)
4562 my $md5 = Digest::MD5->new;
4565 while ($fh->READ($ref, 4096) > 0){
4568 my $hexdigest = $md5->hexdigest;
4569 $eq += $hexdigest eq $cksum->{$basename}{'md5-ungz'};
4573 $CPAN::Frontend->myprint("Checksum for $file ok\n");
4574 return $self->{MD5_STATUS} = "OK";
4576 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
4577 qq{distribution file. }.
4578 qq{Please investigate.\n\n}.
4580 $CPAN::META->instance(
4585 my $wrap = qq{I\'d recommend removing $file. Its MD5
4586 checksum is incorrect. Maybe you have configured your 'urllist' with
4587 a bad URL. Please check this array with 'o conf urllist', and
4590 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
4592 # former versions just returned here but this seems a
4593 # serious threat that deserves a die
4595 # $CPAN::Frontend->myprint("\n\n");
4599 # close $fh if fileno($fh);
4601 $self->{MD5_STATUS} ||= "";
4602 if ($self->{MD5_STATUS} eq "NIL") {
4603 $CPAN::Frontend->mywarn(qq{
4604 Warning: No md5 checksum for $basename in $chk_file.
4606 The cause for this may be that the file is very new and the checksum
4607 has not yet been calculated, but it may also be that something is
4608 going awry right now.
4610 my $answer = ExtUtils::MakeMaker::prompt("Proceed?", "yes");
4611 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.");
4613 $self->{MD5_STATUS} = "NIL";
4618 #-> sub CPAN::Distribution::eq_MD5 ;
4620 my($self,$fh,$expectMD5) = @_;
4621 my $md5 = Digest::MD5->new;
4623 while (read($fh, $data, 4096)){
4626 # $md5->addfile($fh);
4627 my $hexdigest = $md5->hexdigest;
4628 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
4629 $hexdigest eq $expectMD5;
4632 #-> sub CPAN::Distribution::force ;
4634 # Both modules and distributions know if "force" is in effect by
4635 # autoinspection, not by inspecting a global variable. One of the
4636 # reason why this was chosen to work that way was the treatment of
4637 # dependencies. They should not autpomatically inherit the force
4638 # status. But this has the downside that ^C and die() will return to
4639 # the prompt but will not be able to reset the force_update
4640 # attributes. We try to correct for it currently in the read_metadata
4641 # routine, and immediately before we check for a Signal. I hope this
4642 # works out in one of v1.57_53ff
4645 my($self, $method) = @_;
4647 MD5_STATUS archived build_dir localfile make install unwrapped
4650 delete $self->{$att};
4652 if ($method && $method eq "install") {
4653 $self->{"force_update"}++; # name should probably have been force_install
4658 my($self, $method) = @_;
4659 # warn "XDEBUG: set notest for $self $method";
4660 $self->{"notest"}++; # name should probably have been force_install
4665 # warn "XDEBUG: deleting notest";
4666 delete $self->{'notest'};
4669 #-> sub CPAN::Distribution::unforce ;
4672 delete $self->{'force_update'};
4675 #-> sub CPAN::Distribution::isa_perl ;
4678 my $file = File::Basename::basename($self->id);
4679 if ($file =~ m{ ^ perl
4692 } elsif ($self->cpan_comment
4694 $self->cpan_comment =~ /isa_perl\(.+?\)/){
4700 #-> sub CPAN::Distribution::perl ;
4706 #-> sub CPAN::Distribution::make ;
4709 $CPAN::Frontend->myprint(sprintf "Running make for %s\n", $self->id);
4710 # Emergency brake if they said install Pippi and get newest perl
4711 if ($self->isa_perl) {
4713 $self->called_for ne $self->id &&
4714 ! $self->{force_update}
4716 # if we die here, we break bundles
4717 $CPAN::Frontend->mywarn(sprintf qq{
4718 The most recent version "%s" of the module "%s"
4719 comes with the current version of perl (%s).
4720 I\'ll build that only if you ask for something like
4725 $CPAN::META->instance(
4739 $self->{archived} eq "NO" and push @e,
4740 "Is neither a tar nor a zip archive.";
4742 $self->{unwrapped} eq "NO" and push @e,
4743 "had problems unarchiving. Please build manually";
4745 exists $self->{writemakefile} &&
4746 $self->{writemakefile} =~ m/ ^ NO\s* ( .* ) /sx and push @e,
4747 $1 || "Had some problem writing Makefile";
4749 defined $self->{'make'} and push @e,
4750 "Has already been processed within this session";
4752 exists $self->{later} and length($self->{later}) and
4753 push @e, $self->{later};
4755 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4757 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
4758 my $builddir = $self->dir;
4759 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
4760 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
4762 if ($^O eq 'MacOS') {
4763 Mac::BuildTools::make($self);
4768 if ($self->{'configure'}) {
4769 $system = $self->{'configure'};
4771 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
4773 # This needs a handler that can be turned on or off:
4774 # $switch = "-MExtUtils::MakeMaker ".
4775 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
4777 $system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}";
4779 unless (exists $self->{writemakefile}) {
4780 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
4783 if ($CPAN::Config->{inactivity_timeout}) {
4785 alarm $CPAN::Config->{inactivity_timeout};
4786 local $SIG{CHLD}; # = sub { wait };
4787 if (defined($pid = fork)) {
4792 # note, this exec isn't necessary if
4793 # inactivity_timeout is 0. On the Mac I'd
4794 # suggest, we set it always to 0.
4798 $CPAN::Frontend->myprint("Cannot fork: $!");
4806 $CPAN::Frontend->myprint($@);
4807 $self->{writemakefile} = "NO $@";
4812 $ret = system($system);
4814 $self->{writemakefile} = "NO Makefile.PL returned status $ret";
4818 if (-f "Makefile") {
4819 $self->{writemakefile} = "YES";
4820 delete $self->{make_clean}; # if cleaned before, enable next
4822 $self->{writemakefile} =
4823 qq{NO Makefile.PL refused to write a Makefile.};
4824 # It's probably worth it to record the reason, so let's retry
4826 # my $fh = IO::File->new("$system |"); # STDERR? STDIN?
4827 # $self->{writemakefile} .= <$fh>;
4831 delete $self->{force_update};
4834 if (my @prereq = $self->unsat_prereq){
4835 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4837 $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
4838 if (system($system) == 0) {
4839 $CPAN::Frontend->myprint(" $system -- OK\n");
4840 $self->{'make'} = "YES";
4842 $self->{writemakefile} ||= "YES";
4843 $self->{'make'} = "NO";
4844 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4848 sub follow_prereqs {
4852 $CPAN::Frontend->myprint("---- Unsatisfied dependencies detected ".
4853 "during [$id] -----\n");
4855 for my $p (@prereq) {
4856 $CPAN::Frontend->myprint(" $p\n");
4859 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
4861 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
4862 require ExtUtils::MakeMaker;
4863 my $answer = ExtUtils::MakeMaker::prompt(
4864 "Shall I follow them and prepend them to the queue
4865 of modules we are processing right now?", "yes");
4866 $follow = $answer =~ /^\s*y/i;
4870 myprint(" Ignoring dependencies on modules @prereq\n");
4873 # color them as dirty
4874 for my $p (@prereq) {
4875 # warn "calling color_cmd_tmps(0,1)";
4876 CPAN::Shell->expandany($p)->color_cmd_tmps(0,1);
4878 CPAN::Queue->jumpqueue(@prereq,$id); # queue them and requeue yourself
4879 $self->{later} = "Delayed until after prerequisites";
4880 return 1; # signal success to the queuerunner
4884 #-> sub CPAN::Distribution::unsat_prereq ;
4887 my $prereq_pm = $self->prereq_pm or return;
4889 NEED: while (my($need_module, $need_version) = each %$prereq_pm) {
4890 my $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
4891 # we were too demanding:
4892 next if $nmo->uptodate;
4894 # if they have not specified a version, we accept any installed one
4895 if (not defined $need_version or
4896 $need_version == 0 or
4897 $need_version eq "undef") {
4898 next if defined $nmo->inst_file;
4901 # We only want to install prereqs if either they're not installed
4902 # or if the installed version is too old. We cannot omit this
4903 # check, because if 'force' is in effect, nobody else will check.
4907 defined $nmo->inst_file &&
4908 ! CPAN::Version->vgt($need_version, $nmo->inst_version)
4910 CPAN->debug(sprintf "id[%s]inst_file[%s]inst_version[%s]need_version[%s]",
4914 CPAN::Version->readable($need_version)
4920 if ($self->{sponsored_mods}{$need_module}++){
4921 # We have already sponsored it and for some reason it's still
4922 # not available. So we do nothing. Or what should we do?
4923 # if we push it again, we have a potential infinite loop
4926 push @need, $need_module;
4931 #-> sub CPAN::Distribution::prereq_pm ;
4934 return $self->{prereq_pm} if
4935 exists $self->{prereq_pm_detected} && $self->{prereq_pm_detected};
4936 return unless $self->{writemakefile}; # no need to have succeeded
4937 # but we must have run it
4938 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
4939 my $makefile = File::Spec->catfile($build_dir,"Makefile");
4944 $fh = FileHandle->new("<$makefile\0")) {
4948 # A.Speer @p -> %p, where %p is $p{Module::Name}=Required_Version
4950 last if /MakeMaker post_initialize section/;
4952 \s+PREREQ_PM\s+=>\s+(.+)
4955 # warn "Found prereq expr[$p]";
4957 # Regexp modified by A.Speer to remember actual version of file
4958 # PREREQ_PM hash key wants, then add to
4959 while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
4960 # In case a prereq is mentioned twice, complain.
4961 if ( defined $p{$1} ) {
4962 warn "Warning: PREREQ_PM mentions $1 more than once, last mention wins";
4969 $self->{prereq_pm_detected}++;
4970 return $self->{prereq_pm} = \%p;
4973 #-> sub CPAN::Distribution::test ;
4978 delete $self->{force_update};
4981 # warn "XDEBUG: checking for notest: $self->{notest} $self";
4982 if ($self->{notest}) {
4983 $CPAN::Frontend->myprint("Skipping test because of notest pragma\n");
4987 $CPAN::Frontend->myprint("Running make test\n");
4988 if (my @prereq = $self->unsat_prereq){
4989 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4993 exists $self->{make} or exists $self->{later} or push @e,
4994 "Make had some problems, maybe interrupted? Won't test";
4996 exists $self->{'make'} and
4997 $self->{'make'} eq 'NO' and
4998 push @e, "Can't test without successful make";
5000 exists $self->{build_dir} or push @e, "Has no own directory";
5001 $self->{badtestcnt} ||= 0;
5002 $self->{badtestcnt} > 0 and
5003 push @e, "Won't repeat unsuccessful test during this command";
5005 exists $self->{later} and length($self->{later}) and
5006 push @e, $self->{later};
5008 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5010 chdir $self->{'build_dir'} or
5011 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
5012 $self->debug("Changed directory to $self->{'build_dir'}")
5015 if ($^O eq 'MacOS') {
5016 Mac::BuildTools::make_test($self);
5020 local $ENV{PERL5LIB} = defined($ENV{PERL5LIB})
5022 : ($ENV{PERLLIB} || "");
5024 $CPAN::META->set_perl5lib;
5025 my $system = join " ", $CPAN::Config->{'make'}, "test";
5026 if (system($system) == 0) {
5027 $CPAN::Frontend->myprint(" $system -- OK\n");
5028 $CPAN::META->is_tested($self->{'build_dir'});
5029 $self->{make_test} = "YES";
5031 $self->{make_test} = "NO";
5032 $self->{badtestcnt}++;
5033 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
5037 #-> sub CPAN::Distribution::clean ;
5040 $CPAN::Frontend->myprint("Running make clean\n");
5043 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
5044 push @e, "make clean already called once";
5045 exists $self->{build_dir} or push @e, "Has no own directory";
5046 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5048 chdir $self->{'build_dir'} or
5049 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
5050 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
5052 if ($^O eq 'MacOS') {
5053 Mac::BuildTools::make_clean($self);
5057 my $system = join " ", $CPAN::Config->{'make'}, "clean";
5058 if (system($system) == 0) {
5059 $CPAN::Frontend->myprint(" $system -- OK\n");
5063 # Jost Krieger pointed out that this "force" was wrong because
5064 # it has the effect that the next "install" on this distribution
5065 # will untar everything again. Instead we should bring the
5066 # object's state back to where it is after untarring.
5068 delete $self->{force_update};
5069 delete $self->{install};
5070 delete $self->{writemakefile};
5071 delete $self->{make};
5072 delete $self->{make_test}; # no matter if yes or no, tests must be redone
5073 $self->{make_clean} = "YES";
5076 # Hmmm, what to do if make clean failed?
5078 $CPAN::Frontend->myprint(qq{ $system -- NOT OK
5080 make clean did not succeed, marking directory as unusable for further work.
5082 $self->force("make"); # so that this directory won't be used again
5087 #-> sub CPAN::Distribution::install ;
5092 delete $self->{force_update};
5095 $CPAN::Frontend->myprint("Running make install\n");
5098 exists $self->{build_dir} or push @e, "Has no own directory";
5100 exists $self->{make} or exists $self->{later} or push @e,
5101 "Make had some problems, maybe interrupted? Won't install";
5103 exists $self->{'make'} and
5104 $self->{'make'} eq 'NO' and
5105 push @e, "make had returned bad status, install seems impossible";
5107 push @e, "make test had returned bad status, ".
5108 "won't install without force"
5109 if exists $self->{'make_test'} and
5110 $self->{'make_test'} eq 'NO' and
5111 ! $self->{'force_update'};
5113 exists $self->{'install'} and push @e,
5114 $self->{'install'} eq "YES" ?
5115 "Already done" : "Already tried without success";
5117 exists $self->{later} and length($self->{later}) and
5118 push @e, $self->{later};
5120 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
5122 chdir $self->{'build_dir'} or
5123 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
5124 $self->debug("Changed directory to $self->{'build_dir'}")
5127 if ($^O eq 'MacOS') {
5128 Mac::BuildTools::make_install($self);
5132 my($make_install_make_command) = $CPAN::Config->{'make_install_make_command'} ||
5133 $CPAN::Config->{'make'};
5135 my($system) = join(" ",
5136 $make_install_make_command,
5138 $CPAN::Config->{make_install_arg},
5140 my($stderr) = $^O =~ /Win/i ? "" : " 2>&1 ";
5141 my($pipe) = FileHandle->new("$system $stderr |");
5144 $CPAN::Frontend->myprint($_);
5149 $CPAN::Frontend->myprint(" $system -- OK\n");
5150 $CPAN::META->is_installed($self->{'build_dir'});
5151 return $self->{'install'} = "YES";
5153 $self->{'install'} = "NO";
5154 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
5156 $makeout =~ /permission/s
5159 ! $CPAN::Config->{make_install_make_command}
5160 || $CPAN::Config->{make_install_make_command} eq $CPAN::Config->{make}
5163 $CPAN::Frontend->myprint(
5165 qq{ You may have to su }.
5166 qq{to root to install the package\n}.
5167 qq{ (Or you may want to run something like\n}.
5168 qq{ o conf make_install_make_command 'sudo make'\n}.
5169 qq{ to raise your permissions.}
5173 delete $self->{force_update};
5176 #-> sub CPAN::Distribution::dir ;
5178 shift->{'build_dir'};
5181 #-> sub CPAN::Distribution::perldoc ;
5185 my($dist) = $self->id;
5186 my $package = $self->called_for;
5188 $self->_display_url( $CPAN::Defaultdocs . $package );
5191 #-> sub CPAN::Distribution::_check_binary ;
5193 my ($dist,$shell,$binary) = @_;
5194 my ($pid,$readme,$out);
5196 $CPAN::Frontend->myprint(qq{ + _check_binary($binary)\n})
5199 $pid = open $readme, "which $binary|"
5200 or $CPAN::Frontend->mydie(qq{Could not fork 'which $binary': $!});
5204 close $readme or die "Could not run 'which $binary': $!";
5206 $CPAN::Frontend->myprint(qq{ + $out \n})
5207 if $CPAN::DEBUG && $out;
5212 #-> sub CPAN::Distribution::_display_url ;
5214 my($self,$url) = @_;
5215 my($res,$saved_file,$pid,$readme,$out);
5217 $CPAN::Frontend->myprint(qq{ + _display_url($url)\n})
5220 # should we define it in the config instead?
5221 my $html_converter = "html2text";
5223 my $web_browser = $CPAN::Config->{'lynx'} || undef;
5224 my $web_browser_out = $web_browser
5225 ? CPAN::Distribution->_check_binary($self,$web_browser)
5228 my ($tmpout,$tmperr);
5229 if (not $web_browser_out) {
5230 # web browser not found, let's try text only
5231 my $html_converter_out =
5232 CPAN::Distribution->_check_binary($self,$html_converter);
5234 if ($html_converter_out ) {
5235 # html2text found, run it
5236 $saved_file = CPAN::Distribution->_getsave_url( $self, $url );
5237 $CPAN::Frontend->myprint(qq{ERROR: problems while getting $url, $!\n})
5238 unless defined($saved_file);
5240 $pid = open $readme, "$html_converter $saved_file |"
5241 or $CPAN::Frontend->mydie(qq{
5242 Could not fork '$html_converter $saved_file': $!});
5243 my $fh = File::Temp->new(
5244 template => 'cpan_htmlconvert_XXXX',
5252 or $CPAN::Frontend->mydie(qq{Could not run '$html_converter $saved_file': $!});
5253 my $tmpin = $fh->filename;
5254 $CPAN::Frontend->myprint(sprintf(qq{
5256 saved output to %s\n},
5261 close $fh; undef $fh;
5263 or $CPAN::Frontend->mydie(qq{Could not open "$tmpin": $!});
5264 my $fh_pager = FileHandle->new;
5265 local($SIG{PIPE}) = "IGNORE";
5266 $fh_pager->open("|$CPAN::Config->{'pager'}")
5267 or $CPAN::Frontend->mydie(qq{
5268 Could not open pager $CPAN::Config->{'pager'}: $!});
5269 $CPAN::Frontend->myprint(qq{
5272 with pager "$CPAN::Config->{'pager'}"
5275 $fh_pager->print(<$fh>);
5278 # coldn't find the web browser or html converter
5279 $CPAN::Frontend->myprint(qq{
5280 You need to install lynx or $html_converter to use this feature.});
5283 # web browser found, run the action
5284 my $browser = $CPAN::Config->{'lynx'};
5285 $CPAN::Frontend->myprint(qq{system[$browser $url]})
5287 $CPAN::Frontend->myprint(qq{
5290 with browser $browser
5293 system("$browser $url");
5294 if ($saved_file) { 1 while unlink($saved_file) }
5298 #-> sub CPAN::Distribution::_getsave_url ;
5300 my($dist, $shell, $url) = @_;
5302 $CPAN::Frontend->myprint(qq{ + _getsave_url($url)\n})
5305 my $fh = File::Temp->new(
5306 template => "cpan_getsave_url_XXXX",
5310 my $tmpin = $fh->filename;
5311 if ($CPAN::META->has_usable('LWP')) {
5312 $CPAN::Frontend->myprint("Fetching with LWP:
5316 CPAN::LWP::UserAgent->config;
5317 eval { $Ua = CPAN::LWP::UserAgent->new; };
5319 $CPAN::Frontend->mywarn("ERROR: CPAN::LWP::UserAgent->new dies with $@\n");
5323 $Ua->proxy('http', $var)
5324 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
5326 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
5329 my $req = HTTP::Request->new(GET => $url);
5330 $req->header('Accept' => 'text/html');
5331 my $res = $Ua->request($req);
5332 if ($res->is_success) {
5333 $CPAN::Frontend->myprint(" + request successful.\n")
5335 print $fh $res->content;
5337 $CPAN::Frontend->myprint(qq{ + saved content to $tmpin \n})
5341 $CPAN::Frontend->myprint(sprintf(
5342 "LWP failed with code[%s], message[%s]\n",
5349 $CPAN::Frontend->myprint("LWP not available\n");
5354 package CPAN::Bundle;
5358 $CPAN::Frontend->myprint($self->as_string);
5363 delete $self->{later};
5364 for my $c ( $self->contains ) {
5365 my $obj = CPAN::Shell->expandany($c) or next;
5370 #-> sub CPAN::Bundle::color_cmd_tmps ;
5371 sub color_cmd_tmps {
5373 my($depth) = shift || 0;
5374 my($color) = shift || 0;
5375 my($ancestors) = shift || [];
5376 # a module needs to recurse to its cpan_file, a distribution needs
5377 # to recurse into its prereq_pms, a bundle needs to recurse into its modules
5379 return if exists $self->{incommandcolor}
5380 && $self->{incommandcolor}==$color;
5382 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
5384 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
5386 for my $c ( $self->contains ) {
5387 my $obj = CPAN::Shell->expandany($c) or next;
5388 CPAN->debug("c[$c]obj[$obj]") if $CPAN::DEBUG;
5389 $obj->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
5392 delete $self->{badtestcnt};
5394 $self->{incommandcolor} = $color;
5397 #-> sub CPAN::Bundle::as_string ;
5401 # following line must be "=", not "||=" because we have a moving target
5402 $self->{INST_VERSION} = $self->inst_version;
5403 return $self->SUPER::as_string;
5406 #-> sub CPAN::Bundle::contains ;
5409 my($inst_file) = $self->inst_file || "";
5410 my($id) = $self->id;
5411 $self->debug("inst_file[$inst_file]id[$id]") if $CPAN::DEBUG;
5412 unless ($inst_file) {
5413 # Try to get at it in the cpan directory
5414 $self->debug("no inst_file") if $CPAN::DEBUG;
5416 $CPAN::Frontend->mydie("I don't know a bundle with ID $id\n") unless
5417 $cpan_file = $self->cpan_file;
5418 if ($cpan_file eq "N/A") {
5419 $CPAN::Frontend->mydie("Bundle $id not found on disk and not on CPAN.
5420 Maybe stale symlink? Maybe removed during session? Giving up.\n");
5422 my $dist = $CPAN::META->instance('CPAN::Distribution',
5425 $self->debug($dist->as_string) if $CPAN::DEBUG;
5426 my($todir) = $CPAN::Config->{'cpan_home'};
5427 my(@me,$from,$to,$me);
5428 @me = split /::/, $self->id;
5430 $me = File::Spec->catfile(@me);
5431 $from = $self->find_bundle_file($dist->{'build_dir'},$me);
5432 $to = File::Spec->catfile($todir,$me);
5433 File::Path::mkpath(File::Basename::dirname($to));
5434 File::Copy::copy($from, $to)
5435 or Carp::confess("Couldn't copy $from to $to: $!");
5439 my $fh = FileHandle->new;
5441 open($fh,$inst_file) or die "Could not open '$inst_file': $!";
5443 $self->debug("inst_file[$inst_file]") if $CPAN::DEBUG;
5445 $in_cont = m/^=(?!head1\s+CONTENTS)/ ? 0 :
5446 m/^=head1\s+CONTENTS/ ? 1 : $in_cont;
5447 next unless $in_cont;
5452 push @result, (split " ", $_, 2)[0];
5455 delete $self->{STATUS};
5456 $self->{CONTAINS} = \@result;
5457 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
5459 $CPAN::Frontend->mywarn(qq{
5460 The bundle file "$inst_file" may be a broken
5461 bundlefile. It seems not to contain any bundle definition.
5462 Please check the file and if it is bogus, please delete it.
5463 Sorry for the inconvenience.
5469 #-> sub CPAN::Bundle::find_bundle_file
5470 sub find_bundle_file {
5471 my($self,$where,$what) = @_;
5472 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
5473 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
5474 ### my $bu = File::Spec->catfile($where,$what);
5475 ### return $bu if -f $bu;
5476 my $manifest = File::Spec->catfile($where,"MANIFEST");
5477 unless (-f $manifest) {
5478 require ExtUtils::Manifest;
5479 my $cwd = CPAN::anycwd();
5480 chdir $where or $CPAN::Frontend->mydie(qq{Could not chdir to "$where": $!});
5481 ExtUtils::Manifest::mkmanifest();
5482 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
5484 my $fh = FileHandle->new($manifest)
5485 or Carp::croak("Couldn't open $manifest: $!");
5488 if ($^O eq 'MacOS') {
5491 $what2 =~ s/:Bundle://;
5494 $what2 =~ s|Bundle[/\\]||;
5499 my($file) = /(\S+)/;
5500 if ($file =~ m|\Q$what\E$|) {
5502 # return File::Spec->catfile($where,$bu); # bad
5505 # retry if she managed to
5506 # have no Bundle directory
5507 $bu = $file if $file =~ m|\Q$what2\E$|;
5509 $bu =~ tr|/|:| if $^O eq 'MacOS';
5510 return File::Spec->catfile($where, $bu) if $bu;
5511 Carp::croak("Couldn't find a Bundle file in $where");
5514 # needs to work quite differently from Module::inst_file because of
5515 # cpan_home/Bundle/ directory and the possibility that we have
5516 # shadowing effect. As it makes no sense to take the first in @INC for
5517 # Bundles, we parse them all for $VERSION and take the newest.
5519 #-> sub CPAN::Bundle::inst_file ;
5524 @me = split /::/, $self->id;
5527 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
5528 my $bfile = File::Spec->catfile($incdir, @me);
5529 CPAN->debug("bfile[$bfile]") if $CPAN::DEBUG;
5530 next unless -f $bfile;
5531 my $foundv = MM->parse_version($bfile);
5532 if (!$bestv || CPAN::Version->vgt($foundv,$bestv)) {
5533 $self->{INST_FILE} = $bfile;
5534 $self->{INST_VERSION} = $bestv = $foundv;
5540 #-> sub CPAN::Bundle::inst_version ;
5543 $self->inst_file; # finds INST_VERSION as side effect
5544 $self->{INST_VERSION};
5547 #-> sub CPAN::Bundle::rematein ;
5549 my($self,$meth) = @_;
5550 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
5551 my($id) = $self->id;
5552 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
5553 unless $self->inst_file || $self->cpan_file;
5555 for $s ($self->contains) {
5556 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
5557 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
5558 if ($type eq 'CPAN::Distribution') {
5559 $CPAN::Frontend->mywarn(qq{
5560 The Bundle }.$self->id.qq{ contains
5561 explicitly a file $s.
5565 # possibly noisy action:
5566 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
5567 my $obj = $CPAN::META->instance($type,$s);
5569 if ($obj->isa('CPAN::Bundle')
5571 exists $obj->{install_failed}
5573 ref($obj->{install_failed}) eq "HASH"
5575 for (keys %{$obj->{install_failed}}) {
5576 $self->{install_failed}{$_} = undef; # propagate faiure up
5579 $fail{$s} = 1; # the bundle itself may have succeeded but
5584 $success = $obj->can("uptodate") ? $obj->uptodate : 0;
5585 $success ||= $obj->{'install'} && $obj->{'install'} eq "YES";
5587 delete $self->{install_failed}{$s};
5594 # recap with less noise
5595 if ( $meth eq "install" ) {
5598 my $raw = sprintf(qq{Bundle summary:
5599 The following items in bundle %s had installation problems:},
5602 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
5603 $CPAN::Frontend->myprint("\n");
5606 for $s ($self->contains) {
5608 $paragraph .= "$s ";
5609 $self->{install_failed}{$s} = undef;
5610 $reported{$s} = undef;
5613 my $report_propagated;
5614 for $s (sort keys %{$self->{install_failed}}) {
5615 next if exists $reported{$s};
5616 $paragraph .= "and the following items had problems
5617 during recursive bundle calls: " unless $report_propagated++;
5618 $paragraph .= "$s ";
5620 $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
5621 $CPAN::Frontend->myprint("\n");
5623 $self->{'install'} = 'YES';
5628 #sub CPAN::Bundle::xs_file
5630 # If a bundle contains another that contains an xs_file we have
5631 # here, we just don't bother I suppose
5635 #-> sub CPAN::Bundle::force ;
5636 sub force { shift->rematein('force',@_); }
5637 #-> sub CPAN::Bundle::notest ;
5638 sub notest { shift->rematein('notest',@_); }
5639 #-> sub CPAN::Bundle::get ;
5640 sub get { shift->rematein('get',@_); }
5641 #-> sub CPAN::Bundle::make ;
5642 sub make { shift->rematein('make',@_); }
5643 #-> sub CPAN::Bundle::test ;
5646 $self->{badtestcnt} ||= 0;
5647 $self->rematein('test',@_);
5649 #-> sub CPAN::Bundle::install ;
5652 $self->rematein('install',@_);
5654 #-> sub CPAN::Bundle::clean ;
5655 sub clean { shift->rematein('clean',@_); }
5657 #-> sub CPAN::Bundle::uptodate ;
5660 return 0 unless $self->SUPER::uptodate; # we mut have the current Bundle def
5662 foreach $c ($self->contains) {
5663 my $obj = CPAN::Shell->expandany($c);
5664 return 0 unless $obj->uptodate;
5669 #-> sub CPAN::Bundle::readme ;
5672 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
5673 No File found for bundle } . $self->id . qq{\n}), return;
5674 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
5675 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
5678 package CPAN::Module;
5681 # sub CPAN::Module::userid
5684 return unless exists $self->{RO}; # should never happen
5685 return $self->{RO}{userid} || $self->{RO}{CPAN_USERID};
5687 # sub CPAN::Module::description
5688 sub description { shift->{RO}{description} }
5692 delete $self->{later};
5693 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
5698 #-> sub CPAN::Module::color_cmd_tmps ;
5699 sub color_cmd_tmps {
5701 my($depth) = shift || 0;
5702 my($color) = shift || 0;
5703 my($ancestors) = shift || [];
5704 # a module needs to recurse to its cpan_file
5706 return if exists $self->{incommandcolor}
5707 && $self->{incommandcolor}==$color;
5709 $CPAN::Frontend->mydie(CPAN::Exception::RecursiveDependency->new($ancestors));
5711 # warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
5713 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
5714 $dist->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
5717 delete $self->{badtestcnt};
5719 $self->{incommandcolor} = $color;
5722 #-> sub CPAN::Module::as_glimpse ;
5726 my $class = ref($self);
5727 $class =~ s/^CPAN:://;
5731 $CPAN::Shell::COLOR_REGISTERED
5733 $CPAN::META->has_inst("Term::ANSIColor")
5735 $self->{RO}{description}
5737 $color_on = Term::ANSIColor::color("green");
5738 $color_off = Term::ANSIColor::color("reset");
5740 push @m, sprintf("%-15s %s%-15s%s (%s)\n",
5749 #-> sub CPAN::Module::as_string ;
5753 CPAN->debug("$self entering as_string") if $CPAN::DEBUG;
5754 my $class = ref($self);
5755 $class =~ s/^CPAN:://;
5757 push @m, $class, " id = $self->{ID}\n";
5758 my $sprintf = " %-12s %s\n";
5759 push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
5760 if $self->description;
5761 my $sprintf2 = " %-12s %s (%s)\n";
5763 $userid = $self->userid;
5766 if ($author = CPAN::Shell->expand('Author',$userid)) {
5769 if ($m = $author->email) {
5776 $author->fullname . $email
5780 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
5781 if $self->cpan_version;
5782 if (my $cpan_file = $self->cpan_file){
5783 push @m, sprintf($sprintf, 'CPAN_FILE', $cpan_file);
5784 if (my $dist = CPAN::Shell->expand("Distribution",$cpan_file)) {
5785 my $upload_date = $dist->upload_date;
5787 push @m, sprintf($sprintf, 'UPLOAD_DATE', $upload_date);
5791 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
5792 my(%statd,%stats,%statl,%stati);
5793 @statd{qw,? i c a b R M S,} = qw,unknown idea
5794 pre-alpha alpha beta released mature standard,;
5795 @stats{qw,? m d u n a,} = qw,unknown mailing-list
5796 developer comp.lang.perl.* none abandoned,;
5797 @statl{qw,? p c + o h,} = qw,unknown perl C C++ other hybrid,;
5798 @stati{qw,? f r O h,} = qw,unknown functions
5799 references+ties object-oriented hybrid,;
5800 $statd{' '} = 'unknown';
5801 $stats{' '} = 'unknown';
5802 $statl{' '} = 'unknown';
5803 $stati{' '} = 'unknown';
5811 $statd{$self->{RO}{statd}},
5812 $stats{$self->{RO}{stats}},
5813 $statl{$self->{RO}{statl}},
5814 $stati{$self->{RO}{stati}}
5815 ) if $self->{RO}{statd};
5816 my $local_file = $self->inst_file;
5817 unless ($self->{MANPAGE}) {
5819 $self->{MANPAGE} = $self->manpage_headline($local_file);
5821 # If we have already untarred it, we should look there
5822 my $dist = $CPAN::META->instance('CPAN::Distribution',
5824 # warn "dist[$dist]";
5825 # mff=manifest file; mfh=manifest handle
5830 (-f ($mff = File::Spec->catfile($dist->{build_dir}, "MANIFEST")))
5832 $mfh = FileHandle->new($mff)
5834 CPAN->debug("mff[$mff]") if $CPAN::DEBUG;
5835 my $lfre = $self->id; # local file RE
5838 my($lfl); # local file file
5840 my(@mflines) = <$mfh>;
5845 while (length($lfre)>5 and !$lfl) {
5846 ($lfl) = grep /$lfre/, @mflines;
5847 CPAN->debug("lfl[$lfl]lfre[$lfre]") if $CPAN::DEBUG;
5850 $lfl =~ s/\s.*//; # remove comments
5851 $lfl =~ s/\s+//g; # chomp would maybe be too system-specific
5852 my $lfl_abs = File::Spec->catfile($dist->{build_dir},$lfl);
5853 # warn "lfl_abs[$lfl_abs]";
5855 $self->{MANPAGE} = $self->manpage_headline($lfl_abs);
5861 for $item (qw/MANPAGE/) {
5862 push @m, sprintf($sprintf, $item, $self->{$item})
5863 if exists $self->{$item};
5865 for $item (qw/CONTAINS/) {
5866 push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
5867 if exists $self->{$item} && @{$self->{$item}};
5869 push @m, sprintf($sprintf, 'INST_FILE',
5870 $local_file || "(not installed)");
5871 push @m, sprintf($sprintf, 'INST_VERSION',
5872 $self->inst_version) if $local_file;
5876 sub manpage_headline {
5877 my($self,$local_file) = @_;
5878 my(@local_file) = $local_file;
5879 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
5880 push @local_file, $local_file;
5882 for $locf (@local_file) {
5883 next unless -f $locf;
5884 my $fh = FileHandle->new($locf)
5885 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
5889 $inpod = m/^=(?!head1\s+NAME\s*$)/ ? 0 :
5890 m/^=head1\s+NAME\s*$/ ? 1 : $inpod;
5903 #-> sub CPAN::Module::cpan_file ;
5904 # Note: also inherited by CPAN::Bundle
5907 CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
5908 unless (defined $self->{RO}{CPAN_FILE}) {
5909 CPAN::Index->reload;
5911 if (exists $self->{RO}{CPAN_FILE} && defined $self->{RO}{CPAN_FILE}){
5912 return $self->{RO}{CPAN_FILE};
5914 my $userid = $self->userid;
5916 if ($CPAN::META->exists("CPAN::Author",$userid)) {
5917 my $author = $CPAN::META->instance("CPAN::Author",
5919 my $fullname = $author->fullname;
5920 my $email = $author->email;
5921 unless (defined $fullname && defined $email) {
5922 return sprintf("Contact Author %s",
5926 return "Contact Author $fullname <$email>";
5928 return "Contact Author $userid (Email address not available)";
5936 #-> sub CPAN::Module::cpan_version ;
5940 $self->{RO}{CPAN_VERSION} = 'undef'
5941 unless defined $self->{RO}{CPAN_VERSION};
5942 # I believe this is always a bug in the index and should be reported
5943 # as such, but usually I find out such an error and do not want to
5944 # provoke too many bugreports
5946 $self->{RO}{CPAN_VERSION};
5949 #-> sub CPAN::Module::force ;
5952 $self->{'force_update'}++;
5957 # warn "XDEBUG: set notest for Module";
5958 $self->{'notest'}++;
5961 #-> sub CPAN::Module::rematein ;
5963 my($self,$meth) = @_;
5964 $CPAN::Frontend->myprint(sprintf("Running %s for module %s\n",
5967 my $cpan_file = $self->cpan_file;
5968 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
5969 $CPAN::Frontend->mywarn(sprintf qq{
5970 The module %s isn\'t available on CPAN.
5972 Either the module has not yet been uploaded to CPAN, or it is
5973 temporary unavailable. Please contact the author to find out
5974 more about the status. Try 'i %s'.
5981 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
5982 $pack->called_for($self->id);
5983 $pack->force($meth) if exists $self->{'force_update'};
5984 $pack->notest($meth) if exists $self->{'notest'};
5989 $pack->unforce if $pack->can("unforce") && exists $self->{'force_update'};
5990 $pack->unnotest if $pack->can("unnotest") && exists $self->{'notest'};
5991 delete $self->{'force_update'};
5992 delete $self->{'notest'};
5998 #-> sub CPAN::Module::perldoc ;
5999 sub perldoc { shift->rematein('perldoc') }
6000 #-> sub CPAN::Module::readme ;
6001 sub readme { shift->rematein('readme') }
6002 #-> sub CPAN::Module::look ;
6003 sub look { shift->rematein('look') }
6004 #-> sub CPAN::Module::cvs_import ;
6005 sub cvs_import { shift->rematein('cvs_import') }
6006 #-> sub CPAN::Module::get ;
6007 sub get { shift->rematein('get',@_) }
6008 #-> sub CPAN::Module::make ;
6009 sub make { shift->rematein('make') }
6010 #-> sub CPAN::Module::test ;
6013 $self->{badtestcnt} ||= 0;
6014 $self->rematein('test',@_);
6016 #-> sub CPAN::Module::uptodate ;
6019 my($latest) = $self->cpan_version;
6021 my($inst_file) = $self->inst_file;
6023 if (defined $inst_file) {
6024 $have = $self->inst_version;
6029 ! CPAN::Version->vgt($latest, $have)
6031 CPAN->debug("returning uptodate. inst_file[$inst_file] ".
6032 "latest[$latest] have[$have]") if $CPAN::DEBUG;
6037 #-> sub CPAN::Module::install ;
6043 not exists $self->{'force_update'}
6045 $CPAN::Frontend->myprint( $self->id. " is up to date.\n");
6049 if ($self->{RO}{stats} && $self->{RO}{stats} eq "a") {
6050 $CPAN::Frontend->mywarn(qq{
6051 \n\n\n ***WARNING***
6052 The module $self->{ID} has no active maintainer.\n\n\n
6056 $self->rematein('install') if $doit;
6058 #-> sub CPAN::Module::clean ;
6059 sub clean { shift->rematein('clean') }
6061 #-> sub CPAN::Module::inst_file ;
6065 @packpath = split /::/, $self->{ID};
6066 $packpath[-1] .= ".pm";
6067 foreach $dir (@INC) {
6068 my $pmfile = File::Spec->catfile($dir,@packpath);
6076 #-> sub CPAN::Module::xs_file ;
6080 @packpath = split /::/, $self->{ID};
6081 push @packpath, $packpath[-1];
6082 $packpath[-1] .= "." . $Config::Config{'dlext'};
6083 foreach $dir (@INC) {
6084 my $xsfile = File::Spec->catfile($dir,'auto',@packpath);
6092 #-> sub CPAN::Module::inst_version ;
6095 my $parsefile = $self->inst_file or return;
6096 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
6099 # there was a bug in 5.6.0 that let lots of unini warnings out of
6100 # parse_version. Fixed shortly after 5.6.0 by PMQS. We can remove
6101 # the following workaround after 5.6.1 is out.
6102 local($SIG{__WARN__}) = sub { my $w = shift;
6103 return if $w =~ /uninitialized/i;
6107 $have = MM->parse_version($parsefile) || "undef";
6108 $have =~ s/^ //; # since the %vd hack these two lines here are needed
6109 $have =~ s/ $//; # trailing whitespace happens all the time
6111 # My thoughts about why %vd processing should happen here
6113 # Alt1 maintain it as string with leading v:
6114 # read index files do nothing
6115 # compare it use utility for compare
6116 # print it do nothing
6118 # Alt2 maintain it as what it is
6119 # read index files convert
6120 # compare it use utility because there's still a ">" vs "gt" issue
6121 # print it use CPAN::Version for print
6123 # Seems cleaner to hold it in memory as a string starting with a "v"
6125 # If the author of this module made a mistake and wrote a quoted
6126 # "v1.13" instead of v1.13, we simply leave it at that with the
6127 # effect that *we* will treat it like a v-tring while the rest of
6128 # perl won't. Seems sensible when we consider that any action we
6129 # could take now would just add complexity.
6131 $have = CPAN::Version->readable($have);
6133 $have =~ s/\s*//g; # stringify to float around floating point issues
6134 $have; # no stringify needed, \s* above matches always
6137 package CPAN::Tarzip;
6139 # CPAN::Tarzip::gzip
6141 my($class,$read,$write) = @_;
6142 if ($CPAN::META->has_inst("Compress::Zlib")) {
6144 $fhw = FileHandle->new($read)
6145 or $CPAN::Frontend->mydie("Could not open $read: $!");
6147 my $gz = Compress::Zlib::gzopen($write, "wb")
6148 or $CPAN::Frontend->mydie("Cannot gzopen $write: $! (pwd is $cwd)\n");
6149 $gz->gzwrite($buffer)
6150 while read($fhw,$buffer,4096) > 0 ;
6155 system("$CPAN::Config->{gzip} -c $read > $write")==0;
6160 # CPAN::Tarzip::gunzip
6162 my($class,$read,$write) = @_;
6163 if ($CPAN::META->has_inst("Compress::Zlib")) {
6165 $fhw = FileHandle->new(">$write")
6166 or $CPAN::Frontend->mydie("Could not open >$write: $!");
6167 my $gz = Compress::Zlib::gzopen($read, "rb")
6168 or $CPAN::Frontend->mydie("Cannot gzopen $read: $!\n");
6169 $fhw->print($buffer)
6170 while $gz->gzread($buffer) > 0 ;
6171 $CPAN::Frontend->mydie("Error reading from $read: $!\n")
6172 if $gz->gzerror != Compress::Zlib::Z_STREAM_END();
6177 system("$CPAN::Config->{gzip} -dc $read > $write")==0;
6182 # CPAN::Tarzip::gtest
6184 my($class,$read) = @_;
6185 # After I had reread the documentation in zlib.h, I discovered that
6186 # uncompressed files do not lead to an gzerror (anymore?).
6187 if ( $CPAN::META->has_inst("Compress::Zlib") ) {
6190 my $gz = Compress::Zlib::gzopen($read, "rb")
6191 or $CPAN::Frontend->mydie(sprintf("Cannot gzopen %s: %s\n",
6193 $Compress::Zlib::gzerrno));
6194 while ($gz->gzread($buffer) > 0 ){
6195 $len += length($buffer);
6198 my $err = $gz->gzerror;
6199 my $success = ! $err || $err == Compress::Zlib::Z_STREAM_END();
6200 if ($len == -s $read){
6202 CPAN->debug("hit an uncompressed file") if $CPAN::DEBUG;
6205 CPAN->debug("err[$err]success[$success]") if $CPAN::DEBUG;
6208 return system("$CPAN::Config->{gzip} -dt $read")==0;
6213 # CPAN::Tarzip::TIEHANDLE
6215 my($class,$file) = @_;
6217 $class->debug("file[$file]");
6218 if ($CPAN::META->has_inst("Compress::Zlib")) {
6219 my $gz = Compress::Zlib::gzopen($file,"rb") or
6220 die "Could not gzopen $file";
6221 $ret = bless {GZ => $gz}, $class;
6223 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $file |";
6224 my $fh = FileHandle->new($pipe) or die "Could not pipe[$pipe]: $!";
6226 $ret = bless {FH => $fh}, $class;
6232 # CPAN::Tarzip::READLINE
6235 if (exists $self->{GZ}) {
6236 my $gz = $self->{GZ};
6237 my($line,$bytesread);
6238 $bytesread = $gz->gzreadline($line);
6239 return undef if $bytesread <= 0;
6242 my $fh = $self->{FH};
6243 return scalar <$fh>;
6248 # CPAN::Tarzip::READ
6250 my($self,$ref,$length,$offset) = @_;
6251 die "read with offset not implemented" if defined $offset;
6252 if (exists $self->{GZ}) {
6253 my $gz = $self->{GZ};
6254 my $byteread = $gz->gzread($$ref,$length);# 30eaf79e8b446ef52464b5422da328a8
6257 my $fh = $self->{FH};
6258 return read($fh,$$ref,$length);
6263 # CPAN::Tarzip::DESTROY
6266 if (exists $self->{GZ}) {
6267 my $gz = $self->{GZ};
6268 $gz->gzclose() if defined $gz; # hard to say if it is allowed
6269 # to be undef ever. AK, 2000-09
6271 my $fh = $self->{FH};
6272 $fh->close if defined $fh;
6278 # CPAN::Tarzip::untar
6280 my($class,$file) = @_;
6283 if (0) { # makes changing order easier
6284 } elsif ($BUGHUNTING){
6286 } elsif (MM->maybe_command($CPAN::Config->{gzip})
6288 MM->maybe_command($CPAN::Config->{'tar'})) {
6289 # should be default until Archive::Tar is fixed
6292 $CPAN::META->has_inst("Archive::Tar")
6294 $CPAN::META->has_inst("Compress::Zlib") ) {
6297 $CPAN::Frontend->mydie(qq{
6298 CPAN.pm needs either both external programs tar and gzip installed or
6299 both the modules Archive::Tar and Compress::Zlib. Neither prerequisite
6300 is available. Can\'t continue.
6303 if ($prefer==1) { # 1 => external gzip+tar
6305 my $is_compressed = $class->gtest($file);
6306 if ($is_compressed) {
6307 $system = "$CPAN::Config->{gzip} --decompress --stdout " .
6308 "< $file | $CPAN::Config->{tar} xvf -";
6310 $system = "$CPAN::Config->{tar} xvf $file";
6312 if (system($system) != 0) {
6313 # people find the most curious tar binaries that cannot handle
6315 if ($is_compressed) {
6316 (my $ungzf = $file) =~ s/\.gz(?!\n)\Z//;
6317 if (CPAN::Tarzip->gunzip($file, $ungzf)) {
6318 $CPAN::Frontend->myprint(qq{Uncompressed $file successfully\n});
6320 $CPAN::Frontend->mydie(qq{Couldn\'t uncompress $file\n});
6324 $system = "$CPAN::Config->{tar} xvf $file";
6325 $CPAN::Frontend->myprint(qq{Using Tar:$system:\n});
6326 if (system($system)==0) {
6327 $CPAN::Frontend->myprint(qq{Untarred $file successfully\n});
6329 $CPAN::Frontend->mydie(qq{Couldn\'t untar $file\n});
6335 } elsif ($prefer==2) { # 2 => modules
6336 my $tar = Archive::Tar->new($file,1);
6337 my $af; # archive file
6340 # RCS 1.337 had this code, it turned out unacceptable slow but
6341 # it revealed a bug in Archive::Tar. Code is only here to hunt
6342 # the bug again. It should never be enabled in published code.
6343 # GDGraph3d-0.53 was an interesting case according to Larry
6345 warn(">>>Bughunting code enabled<<< " x 20);
6346 for $af ($tar->list_files) {
6347 if ($af =~ m!^(/|\.\./)!) {
6348 $CPAN::Frontend->mydie("ALERT: Archive contains ".
6349 "illegal member [$af]");
6351 $CPAN::Frontend->myprint("$af\n");
6352 $tar->extract($af); # slow but effective for finding the bug
6353 return if $CPAN::Signal;
6356 for $af ($tar->list_files) {
6357 if ($af =~ m!^(/|\.\./)!) {
6358 $CPAN::Frontend->mydie("ALERT: Archive contains ".
6359 "illegal member [$af]");
6361 $CPAN::Frontend->myprint("$af\n");
6363 return if $CPAN::Signal;
6368 Mac::BuildTools::convert_files([$tar->list_files], 1)
6369 if ($^O eq 'MacOS');
6376 my($class,$file) = @_;
6377 if ($CPAN::META->has_inst("Archive::Zip")) {
6378 # blueprint of the code from Archive::Zip::Tree::extractTree();
6379 my $zip = Archive::Zip->new();
6381 $status = $zip->read($file);
6382 die "Read of file[$file] failed\n" if $status != Archive::Zip::AZ_OK();
6383 $CPAN::META->debug("Successfully read file[$file]") if $CPAN::DEBUG;
6384 my @members = $zip->members();
6385 for my $member ( @members ) {
6386 my $af = $member->fileName();
6387 if ($af =~ m!^(/|\.\./)!) {
6388 $CPAN::Frontend->mydie("ALERT: Archive contains ".
6389 "illegal member [$af]");
6391 my $status = $member->extractToFileNamed( $af );
6392 $CPAN::META->debug("af[$af]status[$status]") if $CPAN::DEBUG;
6393 die "Extracting of file[$af] from zipfile[$file] failed\n" if
6394 $status != Archive::Zip::AZ_OK();
6395 return if $CPAN::Signal;
6399 my $unzip = $CPAN::Config->{unzip} or
6400 $CPAN::Frontend->mydie("Cannot unzip, no unzip program available");
6401 my @system = ($unzip, $file);
6402 return system(@system) == 0;
6414 CPAN - query, download and build perl modules from CPAN sites
6420 perl -MCPAN -e shell;
6426 autobundle, clean, install, make, recompile, test
6430 This module will eventually be replaced by CPANPLUS. CPANPLUS is kind
6431 of a modern rewrite from ground up with greater extensibility and more
6432 features but no full compatibility. If you're new to CPAN.pm, you
6433 probably should investigate if CPANPLUS is the better choice for you.
6434 If you're already used to CPAN.pm you're welcome to continue using it,
6435 if you accept that its development is mostly (though not completely)
6440 The CPAN module is designed to automate the make and install of perl
6441 modules and extensions. It includes some primitive searching capabilities and
6442 knows how to use Net::FTP or LWP (or lynx or an external ftp client)
6443 to fetch the raw data from the net.
6445 Modules are fetched from one or more of the mirrored CPAN
6446 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
6449 The CPAN module also supports the concept of named and versioned
6450 I<bundles> of modules. Bundles simplify the handling of sets of
6451 related modules. See Bundles below.
6453 The package contains a session manager and a cache manager. There is
6454 no status retained between sessions. The session manager keeps track
6455 of what has been fetched, built and installed in the current
6456 session. The cache manager keeps track of the disk space occupied by
6457 the make processes and deletes excess space according to a simple FIFO
6460 For extended searching capabilities there's a plugin for CPAN available,
6461 L<C<CPAN::WAIT>|CPAN::WAIT>. C<CPAN::WAIT> is a full-text search engine
6462 that indexes all documents available in CPAN authors directories. If
6463 C<CPAN::WAIT> is installed on your system, the interactive shell of
6464 CPAN.pm will enable the C<wq>, C<wr>, C<wd>, C<wl>, and C<wh> commands
6465 which send queries to the WAIT server that has been configured for your
6468 All other methods provided are accessible in a programmer style and in an
6469 interactive shell style.
6471 =head2 Interactive Mode
6473 The interactive mode is entered by running
6475 perl -MCPAN -e shell
6477 which puts you into a readline interface. You will have the most fun if
6478 you install Term::ReadKey and Term::ReadLine to enjoy both history and
6481 Once you are on the command line, type 'h' and the rest should be
6484 The function call C<shell> takes two optional arguments, one is the
6485 prompt, the second is the default initial command line (the latter
6486 only works if a real ReadLine interface module is installed).
6488 The most common uses of the interactive modes are
6492 =item Searching for authors, bundles, distribution files and modules
6494 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
6495 for each of the four categories and another, C<i> for any of the
6496 mentioned four. Each of the four entities is implemented as a class
6497 with slightly differing methods for displaying an object.
6499 Arguments you pass to these commands are either strings exactly matching
6500 the identification string of an object or regular expressions that are
6501 then matched case-insensitively against various attributes of the
6502 objects. The parser recognizes a regular expression only if you
6503 enclose it between two slashes.
6505 The principle is that the number of found objects influences how an
6506 item is displayed. If the search finds one item, the result is
6507 displayed with the rather verbose method C<as_string>, but if we find
6508 more than one, we display each object with the terse method
6511 =item make, test, install, clean modules or distributions
6513 These commands take any number of arguments and investigate what is
6514 necessary to perform the action. If the argument is a distribution
6515 file name (recognized by embedded slashes), it is processed. If it is
6516 a module, CPAN determines the distribution file in which this module
6517 is included and processes that, following any dependencies named in
6518 the module's Makefile.PL (this behavior is controlled by
6519 I<prerequisites_policy>.)
6521 Any C<make> or C<test> are run unconditionally. An
6523 install <distribution_file>
6525 also is run unconditionally. But for
6529 CPAN checks if an install is actually needed for it and prints
6530 I<module up to date> in the case that the distribution file containing
6531 the module doesn't need to be updated.
6533 CPAN also keeps track of what it has done within the current session
6534 and doesn't try to build a package a second time regardless if it
6535 succeeded or not. The C<force> pragma may precede another command
6536 (currently: C<make>, C<test>, or C<install>) and executes the
6537 command from scratch.
6541 cpan> install OpenGL
6542 OpenGL is up to date.
6543 cpan> force install OpenGL
6546 OpenGL-0.4/COPYRIGHT
6549 The C<notest> pragma may be set to skip the test part in the build
6554 cpan> notest install Tk
6556 A C<clean> command results in a
6560 being executed within the distribution file's working directory.
6562 =item get, readme, perldoc, look module or distribution
6564 C<get> downloads a distribution file without further action. C<readme>
6565 displays the README file of the associated distribution. C<Look> gets
6566 and untars (if not yet done) the distribution file, changes to the
6567 appropriate directory and opens a subshell process in that directory.
6568 C<perldoc> displays the pod documentation of the module in html or
6573 C<ls> lists all distribution files in and below an author's CPAN
6574 directory. Only those files that contain modules are listed and if
6575 there is more than one for any given module, only the most recent one
6580 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
6581 in the cpan-shell it is intended that you can press C<^C> anytime and
6582 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
6583 to clean up and leave the shell loop. You can emulate the effect of a
6584 SIGTERM by sending two consecutive SIGINTs, which usually means by
6585 pressing C<^C> twice.
6587 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
6588 SIGALRM is used during the run of the C<perl Makefile.PL> subprocess.
6594 The commands that are available in the shell interface are methods in
6595 the package CPAN::Shell. If you enter the shell command, all your
6596 input is split by the Text::ParseWords::shellwords() routine which
6597 acts like most shells do. The first word is being interpreted as the
6598 method to be called and the rest of the words are treated as arguments
6599 to this method. Continuation lines are supported if a line ends with a
6604 C<autobundle> writes a bundle file into the
6605 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
6606 a list of all modules that are both available from CPAN and currently
6607 installed within @INC. The name of the bundle file is based on the
6608 current date and a counter.
6612 recompile() is a very special command in that it takes no argument and
6613 runs the make/test/install cycle with brute force over all installed
6614 dynamically loadable extensions (aka XS modules) with 'force' in
6615 effect. The primary purpose of this command is to finish a network
6616 installation. Imagine, you have a common source tree for two different
6617 architectures. You decide to do a completely independent fresh
6618 installation. You start on one architecture with the help of a Bundle
6619 file produced earlier. CPAN installs the whole Bundle for you, but
6620 when you try to repeat the job on the second architecture, CPAN
6621 responds with a C<"Foo up to date"> message for all modules. So you
6622 invoke CPAN's recompile on the second architecture and you're done.
6624 Another popular use for C<recompile> is to act as a rescue in case your
6625 perl breaks binary compatibility. If one of the modules that CPAN uses
6626 is in turn depending on binary compatibility (so you cannot run CPAN
6627 commands), then you should try the CPAN::Nox module for recovery.
6629 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
6631 Although it may be considered internal, the class hierarchy does matter
6632 for both users and programmer. CPAN.pm deals with above mentioned four
6633 classes, and all those classes share a set of methods. A classical
6634 single polymorphism is in effect. A metaclass object registers all
6635 objects of all kinds and indexes them with a string. The strings
6636 referencing objects have a separated namespace (well, not completely
6641 words containing a "/" (slash) Distribution
6642 words starting with Bundle:: Bundle
6643 everything else Module or Author
6645 Modules know their associated Distribution objects. They always refer
6646 to the most recent official release. Developers may mark their releases
6647 as unstable development versions (by inserting an underbar into the
6648 module version number which will also be reflected in the distribution
6649 name when you run 'make dist'), so the really hottest and newest
6650 distribution is not always the default. If a module Foo circulates
6651 on CPAN in both version 1.23 and 1.23_90, CPAN.pm offers a convenient
6652 way to install version 1.23 by saying
6656 This would install the complete distribution file (say
6657 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
6658 like to install version 1.23_90, you need to know where the
6659 distribution file resides on CPAN relative to the authors/id/
6660 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
6661 so you would have to say
6663 install BAR/Foo-1.23_90.tar.gz
6665 The first example will be driven by an object of the class
6666 CPAN::Module, the second by an object of class CPAN::Distribution.
6668 =head2 Programmer's interface
6670 If you do not enter the shell, the available shell commands are both
6671 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
6672 functions in the calling package (C<install(...)>).
6674 There's currently only one class that has a stable interface -
6675 CPAN::Shell. All commands that are available in the CPAN shell are
6676 methods of the class CPAN::Shell. Each of the commands that produce
6677 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
6678 the IDs of all modules within the list.
6682 =item expand($type,@things)
6684 The IDs of all objects available within a program are strings that can
6685 be expanded to the corresponding real objects with the
6686 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
6687 list of CPAN::Module objects according to the C<@things> arguments
6688 given. In scalar context it only returns the first element of the
6691 =item expandany(@things)
6693 Like expand, but returns objects of the appropriate type, i.e.
6694 CPAN::Bundle objects for bundles, CPAN::Module objects for modules and
6695 CPAN::Distribution objects fro distributions.
6697 =item Programming Examples
6699 This enables the programmer to do operations that combine
6700 functionalities that are available in the shell.
6702 # install everything that is outdated on my disk:
6703 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
6705 # install my favorite programs if necessary:
6706 for $mod (qw(Net::FTP Digest::MD5 Data::Dumper)){
6707 my $obj = CPAN::Shell->expand('Module',$mod);
6711 # list all modules on my disk that have no VERSION number
6712 for $mod (CPAN::Shell->expand("Module","/./")){
6713 next unless $mod->inst_file;
6714 # MakeMaker convention for undefined $VERSION:
6715 next unless $mod->inst_version eq "undef";
6716 print "No VERSION in ", $mod->id, "\n";
6719 # find out which distribution on CPAN contains a module:
6720 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
6722 Or if you want to write a cronjob to watch The CPAN, you could list
6723 all modules that need updating. First a quick and dirty way:
6725 perl -e 'use CPAN; CPAN::Shell->r;'
6727 If you don't want to get any output in the case that all modules are
6728 up to date, you can parse the output of above command for the regular
6729 expression //modules are up to date// and decide to mail the output
6730 only if it doesn't match. Ick?
6732 If you prefer to do it more in a programmer style in one single
6733 process, maybe something like this suits you better:
6735 # list all modules on my disk that have newer versions on CPAN
6736 for $mod (CPAN::Shell->expand("Module","/./")){
6737 next unless $mod->inst_file;
6738 next if $mod->uptodate;
6739 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
6740 $mod->id, $mod->inst_version, $mod->cpan_version;
6743 If that gives you too much output every day, you maybe only want to
6744 watch for three modules. You can write
6746 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")){
6748 as the first line instead. Or you can combine some of the above
6751 # watch only for a new mod_perl module
6752 $mod = CPAN::Shell->expand("Module","mod_perl");
6753 exit if $mod->uptodate;
6754 # new mod_perl arrived, let me know all update recommendations
6759 =head2 Methods in the other Classes
6761 The programming interface for the classes CPAN::Module,
6762 CPAN::Distribution, CPAN::Bundle, and CPAN::Author is still considered
6763 beta and partially even alpha. In the following paragraphs only those
6764 methods are documented that have proven useful over a longer time and
6765 thus are unlikely to change.
6769 =item CPAN::Author::as_glimpse()
6771 Returns a one-line description of the author
6773 =item CPAN::Author::as_string()
6775 Returns a multi-line description of the author
6777 =item CPAN::Author::email()
6779 Returns the author's email address
6781 =item CPAN::Author::fullname()
6783 Returns the author's name
6785 =item CPAN::Author::name()
6787 An alias for fullname
6789 =item CPAN::Bundle::as_glimpse()
6791 Returns a one-line description of the bundle
6793 =item CPAN::Bundle::as_string()
6795 Returns a multi-line description of the bundle
6797 =item CPAN::Bundle::clean()
6799 Recursively runs the C<clean> method on all items contained in the bundle.
6801 =item CPAN::Bundle::contains()
6803 Returns a list of objects' IDs contained in a bundle. The associated
6804 objects may be bundles, modules or distributions.
6806 =item CPAN::Bundle::force($method,@args)
6808 Forces CPAN to perform a task that normally would have failed. Force
6809 takes as arguments a method name to be called and any number of
6810 additional arguments that should be passed to the called method. The
6811 internals of the object get the needed changes so that CPAN.pm does
6812 not refuse to take the action. The C<force> is passed recursively to
6813 all contained objects.
6815 =item CPAN::Bundle::get()
6817 Recursively runs the C<get> method on all items contained in the bundle
6819 =item CPAN::Bundle::inst_file()
6821 Returns the highest installed version of the bundle in either @INC or
6822 C<$CPAN::Config->{cpan_home}>. Note that this is different from
6823 CPAN::Module::inst_file.
6825 =item CPAN::Bundle::inst_version()
6827 Like CPAN::Bundle::inst_file, but returns the $VERSION
6829 =item CPAN::Bundle::uptodate()
6831 Returns 1 if the bundle itself and all its members are uptodate.
6833 =item CPAN::Bundle::install()
6835 Recursively runs the C<install> method on all items contained in the bundle
6837 =item CPAN::Bundle::make()
6839 Recursively runs the C<make> method on all items contained in the bundle
6841 =item CPAN::Bundle::readme()
6843 Recursively runs the C<readme> method on all items contained in the bundle
6845 =item CPAN::Bundle::test()
6847 Recursively runs the C<test> method on all items contained in the bundle
6849 =item CPAN::Distribution::as_glimpse()
6851 Returns a one-line description of the distribution
6853 =item CPAN::Distribution::as_string()
6855 Returns a multi-line description of the distribution
6857 =item CPAN::Distribution::clean()
6859 Changes to the directory where the distribution has been unpacked and
6860 runs C<make clean> there.
6862 =item CPAN::Distribution::containsmods()
6864 Returns a list of IDs of modules contained in a distribution file.
6865 Only works for distributions listed in the 02packages.details.txt.gz
6866 file. This typically means that only the most recent version of a
6867 distribution is covered.
6869 =item CPAN::Distribution::cvs_import()
6871 Changes to the directory where the distribution has been unpacked and
6874 cvs -d $cvs_root import -m $cvs_log $cvs_dir $userid v$version
6878 =item CPAN::Distribution::dir()
6880 Returns the directory into which this distribution has been unpacked.
6882 =item CPAN::Distribution::force($method,@args)
6884 Forces CPAN to perform a task that normally would have failed. Force
6885 takes as arguments a method name to be called and any number of
6886 additional arguments that should be passed to the called method. The
6887 internals of the object get the needed changes so that CPAN.pm does
6888 not refuse to take the action.
6890 =item CPAN::Distribution::get()
6892 Downloads the distribution from CPAN and unpacks it. Does nothing if
6893 the distribution has already been downloaded and unpacked within the
6896 =item CPAN::Distribution::install()
6898 Changes to the directory where the distribution has been unpacked and
6899 runs the external command C<make install> there. If C<make> has not
6900 yet been run, it will be run first. A C<make test> will be issued in
6901 any case and if this fails, the install will be canceled. The
6902 cancellation can be avoided by letting C<force> run the C<install> for
6905 =item CPAN::Distribution::isa_perl()
6907 Returns 1 if this distribution file seems to be a perl distribution.
6908 Normally this is derived from the file name only, but the index from
6909 CPAN can contain a hint to achieve a return value of true for other
6912 =item CPAN::Distribution::look()
6914 Changes to the directory where the distribution has been unpacked and
6915 opens a subshell there. Exiting the subshell returns.
6917 =item CPAN::Distribution::make()
6919 First runs the C<get> method to make sure the distribution is
6920 downloaded and unpacked. Changes to the directory where the
6921 distribution has been unpacked and runs the external commands C<perl
6922 Makefile.PL> and C<make> there.
6924 =item CPAN::Distribution::prereq_pm()
6926 Returns the hash reference that has been announced by a distribution
6927 as the PREREQ_PM hash in the Makefile.PL. Note: works only after an
6928 attempt has been made to C<make> the distribution. Returns undef
6931 =item CPAN::Distribution::readme()
6933 Downloads the README file associated with a distribution and runs it
6934 through the pager specified in C<$CPAN::Config->{pager}>.
6936 =item CPAN::Distribution::perldoc()
6938 Downloads the pod documentation of the file associated with a
6939 distribution (in html format) and runs it through the external
6940 command lynx specified in C<$CPAN::Config->{lynx}>. If lynx
6941 isn't available, it converts it to plain text with external
6942 command html2text and runs it through the pager specified
6943 in C<$CPAN::Config->{pager}>
6945 =item CPAN::Distribution::test()
6947 Changes to the directory where the distribution has been unpacked and
6948 runs C<make test> there.
6950 =item CPAN::Distribution::uptodate()
6952 Returns 1 if all the modules contained in the distribution are
6953 uptodate. Relies on containsmods.
6955 =item CPAN::Index::force_reload()
6957 Forces a reload of all indices.
6959 =item CPAN::Index::reload()
6961 Reloads all indices if they have been read more than
6962 C<$CPAN::Config->{index_expire}> days.
6964 =item CPAN::InfoObj::dump()
6966 CPAN::Author, CPAN::Bundle, CPAN::Module, and CPAN::Distribution
6967 inherit this method. It prints the data structure associated with an
6968 object. Useful for debugging. Note: the data structure is considered
6969 internal and thus subject to change without notice.
6971 =item CPAN::Module::as_glimpse()
6973 Returns a one-line description of the module
6975 =item CPAN::Module::as_string()
6977 Returns a multi-line description of the module
6979 =item CPAN::Module::clean()
6981 Runs a clean on the distribution associated with this module.
6983 =item CPAN::Module::cpan_file()
6985 Returns the filename on CPAN that is associated with the module.
6987 =item CPAN::Module::cpan_version()
6989 Returns the latest version of this module available on CPAN.
6991 =item CPAN::Module::cvs_import()
6993 Runs a cvs_import on the distribution associated with this module.
6995 =item CPAN::Module::description()
6997 Returns a 44 character description of this module. Only available for
6998 modules listed in The Module List (CPAN/modules/00modlist.long.html
6999 or 00modlist.long.txt.gz)
7001 =item CPAN::Module::force($method,@args)
7003 Forces CPAN to perform a task that normally would have failed. Force
7004 takes as arguments a method name to be called and any number of
7005 additional arguments that should be passed to the called method. The
7006 internals of the object get the needed changes so that CPAN.pm does
7007 not refuse to take the action.
7009 =item CPAN::Module::get()
7011 Runs a get on the distribution associated with this module.
7013 =item CPAN::Module::inst_file()
7015 Returns the filename of the module found in @INC. The first file found
7016 is reported just like perl itself stops searching @INC when it finds a
7019 =item CPAN::Module::inst_version()
7021 Returns the version number of the module in readable format.
7023 =item CPAN::Module::install()
7025 Runs an C<install> on the distribution associated with this module.
7027 =item CPAN::Module::look()
7029 Changes to the directory where the distribution associated with this
7030 module has been unpacked and opens a subshell there. Exiting the
7033 =item CPAN::Module::make()
7035 Runs a C<make> on the distribution associated with this module.
7037 =item CPAN::Module::manpage_headline()
7039 If module is installed, peeks into the module's manpage, reads the
7040 headline and returns it. Moreover, if the module has been downloaded
7041 within this session, does the equivalent on the downloaded module even
7042 if it is not installed.
7044 =item CPAN::Module::readme()
7046 Runs a C<readme> on the distribution associated with this module.
7048 =item CPAN::Module::perldoc()
7050 Runs a C<perldoc> on this module.
7052 =item CPAN::Module::test()
7054 Runs a C<test> on the distribution associated with this module.
7056 =item CPAN::Module::uptodate()
7058 Returns 1 if the module is installed and up-to-date.
7060 =item CPAN::Module::userid()
7062 Returns the author's ID of the module.
7066 =head2 Cache Manager
7068 Currently the cache manager only keeps track of the build directory
7069 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
7070 deletes complete directories below C<build_dir> as soon as the size of
7071 all directories there gets bigger than $CPAN::Config->{build_cache}
7072 (in MB). The contents of this cache may be used for later
7073 re-installations that you intend to do manually, but will never be
7074 trusted by CPAN itself. This is due to the fact that the user might
7075 use these directories for building modules on different architectures.
7077 There is another directory ($CPAN::Config->{keep_source_where}) where
7078 the original distribution files are kept. This directory is not
7079 covered by the cache manager and must be controlled by the user. If
7080 you choose to have the same directory as build_dir and as
7081 keep_source_where directory, then your sources will be deleted with
7082 the same fifo mechanism.
7086 A bundle is just a perl module in the namespace Bundle:: that does not
7087 define any functions or methods. It usually only contains documentation.
7089 It starts like a perl module with a package declaration and a $VERSION
7090 variable. After that the pod section looks like any other pod with the
7091 only difference being that I<one special pod section> exists starting with
7096 In this pod section each line obeys the format
7098 Module_Name [Version_String] [- optional text]
7100 The only required part is the first field, the name of a module
7101 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
7102 of the line is optional. The comment part is delimited by a dash just
7103 as in the man page header.
7105 The distribution of a bundle should follow the same convention as
7106 other distributions.
7108 Bundles are treated specially in the CPAN package. If you say 'install
7109 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
7110 the modules in the CONTENTS section of the pod. You can install your
7111 own Bundles locally by placing a conformant Bundle file somewhere into
7112 your @INC path. The autobundle() command which is available in the
7113 shell interface does that for you by including all currently installed
7114 modules in a snapshot bundle file.
7116 =head2 Prerequisites
7118 If you have a local mirror of CPAN and can access all files with
7119 "file:" URLs, then you only need a perl better than perl5.003 to run
7120 this module. Otherwise Net::FTP is strongly recommended. LWP may be
7121 required for non-UNIX systems or if your nearest CPAN site is
7122 associated with a URL that is not C<ftp:>.
7124 If you have neither Net::FTP nor LWP, there is a fallback mechanism
7125 implemented for an external ftp command or for an external lynx
7128 =head2 Finding packages and VERSION
7130 This module presumes that all packages on CPAN
7136 declare their $VERSION variable in an easy to parse manner. This
7137 prerequisite can hardly be relaxed because it consumes far too much
7138 memory to load all packages into the running program just to determine
7139 the $VERSION variable. Currently all programs that are dealing with
7140 version use something like this
7142 perl -MExtUtils::MakeMaker -le \
7143 'print MM->parse_version(shift)' filename
7145 If you are author of a package and wonder if your $VERSION can be
7146 parsed, please try the above method.
7150 come as compressed or gzipped tarfiles or as zip files and contain a
7151 Makefile.PL (well, we try to handle a bit more, but without much
7158 The debugging of this module is a bit complex, because we have
7159 interferences of the software producing the indices on CPAN, of the
7160 mirroring process on CPAN, of packaging, of configuration, of
7161 synchronicity, and of bugs within CPAN.pm.
7163 For code debugging in interactive mode you can try "o debug" which
7164 will list options for debugging the various parts of the code. You
7165 should know that "o debug" has built-in completion support.
7167 For data debugging there is the C<dump> command which takes the same
7168 arguments as make/test/install and outputs the object's Data::Dumper
7171 =head2 Floppy, Zip, Offline Mode
7173 CPAN.pm works nicely without network too. If you maintain machines
7174 that are not networked at all, you should consider working with file:
7175 URLs. Of course, you have to collect your modules somewhere first. So
7176 you might use CPAN.pm to put together all you need on a networked
7177 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
7178 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
7179 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
7180 with this floppy. See also below the paragraph about CD-ROM support.
7182 =head1 CONFIGURATION
7184 When the CPAN module is used for the first time, a configuration
7185 dialog tries to determine a couple of site specific options. The
7186 result of the dialog is stored in a hash reference C< $CPAN::Config >
7187 in a file CPAN/Config.pm.
7189 The default values defined in the CPAN/Config.pm file can be
7190 overridden in a user specific file: CPAN/MyConfig.pm. Such a file is
7191 best placed in $HOME/.cpan/CPAN/MyConfig.pm, because $HOME/.cpan is
7192 added to the search path of the CPAN module before the use() or
7193 require() statements.
7195 The configuration dialog can be started any time later again by
7196 issuing the command C< o conf init > in the CPAN shell.
7198 Currently the following keys in the hash reference $CPAN::Config are
7201 build_cache size of cache for directories to build modules
7202 build_dir locally accessible directory to build modules
7203 index_expire after this many days refetch index files
7204 cache_metadata use serializer to cache metadata
7205 cpan_home local directory reserved for this package
7206 dontload_hash anonymous hash: modules in the keys will not be
7207 loaded by the CPAN::has_inst() routine
7208 gzip location of external program gzip
7209 histfile file to maintain history between sessions
7210 histsize maximum number of lines to keep in histfile
7211 inactivity_timeout breaks interactive Makefile.PLs after this
7212 many seconds inactivity. Set to 0 to never break.
7213 inhibit_startup_message
7214 if true, does not print the startup message
7215 keep_source_where directory in which to keep the source (if we do)
7216 make location of external make program
7217 make_arg arguments that should always be passed to 'make'
7218 make_install_make_command
7219 the make command for running 'make install', for
7221 make_install_arg same as make_arg for 'make install'
7222 makepl_arg arguments passed to 'perl Makefile.PL'
7223 pager location of external program more (or any pager)
7224 prerequisites_policy
7225 what to do if you are missing module prerequisites
7226 ('follow' automatically, 'ask' me, or 'ignore')
7227 proxy_user username for accessing an authenticating proxy
7228 proxy_pass password for accessing an authenticating proxy
7229 scan_cache controls scanning of cache ('atstart' or 'never')
7230 tar location of external program tar
7231 term_is_latin if true internal UTF-8 is translated to ISO-8859-1
7232 (and nonsense for characters outside latin range)
7233 unzip location of external program unzip
7234 urllist arrayref to nearby CPAN sites (or equivalent locations)
7235 wait_list arrayref to a wait server to try (See CPAN::WAIT)
7236 ftp_proxy, } the three usual variables for configuring
7237 http_proxy, } proxy requests. Both as CPAN::Config variables
7238 no_proxy } and as environment variables configurable.
7240 You can set and query each of these options interactively in the cpan
7241 shell with the command set defined within the C<o conf> command:
7245 =item C<o conf E<lt>scalar optionE<gt>>
7247 prints the current value of the I<scalar option>
7249 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
7251 Sets the value of the I<scalar option> to I<value>
7253 =item C<o conf E<lt>list optionE<gt>>
7255 prints the current value of the I<list option> in MakeMaker's
7258 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
7260 shifts or pops the array in the I<list option> variable
7262 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
7264 works like the corresponding perl commands.
7268 =head2 Note on urllist parameter's format
7270 urllist parameters are URLs according to RFC 1738. We do a little
7271 guessing if your URL is not compliant, but if you have problems with
7272 file URLs, please try the correct format. Either:
7274 file://localhost/whatever/ftp/pub/CPAN/
7278 file:///home/ftp/pub/CPAN/
7280 =head2 urllist parameter has CD-ROM support
7282 The C<urllist> parameter of the configuration table contains a list of
7283 URLs that are to be used for downloading. If the list contains any
7284 C<file> URLs, CPAN always tries to get files from there first. This
7285 feature is disabled for index files. So the recommendation for the
7286 owner of a CD-ROM with CPAN contents is: include your local, possibly
7287 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
7289 o conf urllist push file://localhost/CDROM/CPAN
7291 CPAN.pm will then fetch the index files from one of the CPAN sites
7292 that come at the beginning of urllist. It will later check for each
7293 module if there is a local copy of the most recent version.
7295 Another peculiarity of urllist is that the site that we could
7296 successfully fetch the last file from automatically gets a preference
7297 token and is tried as the first site for the next request. So if you
7298 add a new site at runtime it may happen that the previously preferred
7299 site will be tried another time. This means that if you want to disallow
7300 a site for the next transfer, it must be explicitly removed from
7305 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
7306 install foreign, unmasked, unsigned code on your machine. We compare
7307 to a checksum that comes from the net just as the distribution file
7308 itself. If somebody has managed to tamper with the distribution file,
7309 they may have as well tampered with the CHECKSUMS file. Future
7310 development will go towards strong authentication.
7314 Most functions in package CPAN are exported per default. The reason
7315 for this is that the primary use is intended for the cpan shell or for
7318 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
7320 Populating a freshly installed perl with my favorite modules is pretty
7321 easy if you maintain a private bundle definition file. To get a useful
7322 blueprint of a bundle definition file, the command autobundle can be used
7323 on the CPAN shell command line. This command writes a bundle definition
7324 file for all modules that are installed for the currently running perl
7325 interpreter. It's recommended to run this command only once and from then
7326 on maintain the file manually under a private name, say
7327 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
7329 cpan> install Bundle::my_bundle
7331 then answer a few questions and then go out for a coffee.
7333 Maintaining a bundle definition file means keeping track of two
7334 things: dependencies and interactivity. CPAN.pm sometimes fails on
7335 calculating dependencies because not all modules define all MakeMaker
7336 attributes correctly, so a bundle definition file should specify
7337 prerequisites as early as possible. On the other hand, it's a bit
7338 annoying that many distributions need some interactive configuring. So
7339 what I try to accomplish in my private bundle file is to have the
7340 packages that need to be configured early in the file and the gentle
7341 ones later, so I can go out after a few minutes and leave CPAN.pm
7344 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
7346 Thanks to Graham Barr for contributing the following paragraphs about
7347 the interaction between perl, and various firewall configurations. For
7348 further information on firewalls, it is recommended to consult the
7349 documentation that comes with the ncftp program. If you are unable to
7350 go through the firewall with a simple Perl setup, it is very likely
7351 that you can configure ncftp so that it works for your firewall.
7353 =head2 Three basic types of firewalls
7355 Firewalls can be categorized into three basic types.
7361 This is where the firewall machine runs a web server and to access the
7362 outside world you must do it via the web server. If you set environment
7363 variables like http_proxy or ftp_proxy to a values beginning with http://
7364 or in your web browser you have to set proxy information then you know
7365 you are running an http firewall.
7367 To access servers outside these types of firewalls with perl (even for
7368 ftp) you will need to use LWP.
7372 This where the firewall machine runs an ftp server. This kind of
7373 firewall will only let you access ftp servers outside the firewall.
7374 This is usually done by connecting to the firewall with ftp, then
7375 entering a username like "user@outside.host.com"
7377 To access servers outside these type of firewalls with perl you
7378 will need to use Net::FTP.
7380 =item One way visibility
7382 I say one way visibility as these firewalls try to make themselves look
7383 invisible to the users inside the firewall. An FTP data connection is
7384 normally created by sending the remote server your IP address and then
7385 listening for the connection. But the remote server will not be able to
7386 connect to you because of the firewall. So for these types of firewall
7387 FTP connections need to be done in a passive mode.
7389 There are two that I can think off.
7395 If you are using a SOCKS firewall you will need to compile perl and link
7396 it with the SOCKS library, this is what is normally called a 'socksified'
7397 perl. With this executable you will be able to connect to servers outside
7398 the firewall as if it is not there.
7402 This is the firewall implemented in the Linux kernel, it allows you to
7403 hide a complete network behind one IP address. With this firewall no
7404 special compiling is needed as you can access hosts directly.
7406 For accessing ftp servers behind such firewalls you may need to set
7407 the environment variable C<FTP_PASSIVE> to a true value, e.g.
7409 env FTP_PASSIVE=1 perl -MCPAN -eshell
7413 perl -MCPAN -e '$ENV{FTP_PASSIVE} = 1; shell'
7420 =head2 Configuring lynx or ncftp for going through a firewall
7422 If you can go through your firewall with e.g. lynx, presumably with a
7425 /usr/local/bin/lynx -pscott:tiger
7427 then you would configure CPAN.pm with the command
7429 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
7431 That's all. Similarly for ncftp or ftp, you would configure something
7434 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
7436 Your mileage may vary...
7438 =head1 Cryptographically signed modules
7440 Since release 1.77 CPAN.pm has been able to verify cryptographically
7441 signed module distributions using Module::Signature. The CPAN modules
7442 can be signed by their authors, thus giving more security. The simple
7443 unsigned MD5 checksums that were used before by CPAN protect mainly
7444 against accidental file corruption.
7446 You will need to have Module::Signature installed, which in turn
7447 requires that you have at least one of Crypt::OpenPGP module or the
7448 command-line F<gpg> tool installed.
7450 You will also need to be able to connect over the Internet to the public
7451 keyservers, like pgp.mit.edu, and their port 11731 (the HKP protocol).
7459 I installed a new version of module X but CPAN keeps saying,
7460 I have the old version installed
7462 Most probably you B<do> have the old version installed. This can
7463 happen if a module installs itself into a different directory in the
7464 @INC path than it was previously installed. This is not really a
7465 CPAN.pm problem, you would have the same problem when installing the
7466 module manually. The easiest way to prevent this behaviour is to add
7467 the argument C<UNINST=1> to the C<make install> call, and that is why
7468 many people add this argument permanently by configuring
7470 o conf make_install_arg UNINST=1
7474 So why is UNINST=1 not the default?
7476 Because there are people who have their precise expectations about who
7477 may install where in the @INC path and who uses which @INC array. In
7478 fine tuned environments C<UNINST=1> can cause damage.
7482 I want to clean up my mess, and install a new perl along with
7483 all modules I have. How do I go about it?
7485 Run the autobundle command for your old perl and optionally rename the
7486 resulting bundle file (e.g. Bundle/mybundle.pm), install the new perl
7487 with the Configure option prefix, e.g.
7489 ./Configure -Dprefix=/usr/local/perl-5.6.78.9
7491 Install the bundle file you produced in the first step with something like
7493 cpan> install Bundle::mybundle
7499 When I install bundles or multiple modules with one command
7500 there is too much output to keep track of.
7502 You may want to configure something like
7504 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
7505 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
7507 so that STDOUT is captured in a file for later inspection.
7512 I am not root, how can I install a module in a personal directory?
7514 First of all, you will want to use your own configuration, not the one
7515 that your root user installed. The following command sequence is a
7518 % mkdir -p $HOME/.cpan/CPAN
7519 % echo '$CPAN::Config={ };' > $HOME/.cpan/CPAN/MyConfig.pm
7521 [...answer all questions...]
7523 You will most probably like something like this:
7525 o conf makepl_arg "LIB=~/myperl/lib \
7526 INSTALLMAN1DIR=~/myperl/man/man1 \
7527 INSTALLMAN3DIR=~/myperl/man/man3"
7529 You can make this setting permanent like all C<o conf> settings with
7532 You will have to add ~/myperl/man to the MANPATH environment variable
7533 and also tell your perl programs to look into ~/myperl/lib, e.g. by
7536 use lib "$ENV{HOME}/myperl/lib";
7538 or setting the PERL5LIB environment variable.
7540 Another thing you should bear in mind is that the UNINST parameter
7541 should never be set if you are not root.
7545 How to get a package, unwrap it, and make a change before building it?
7547 look Sybase::Sybperl
7551 I installed a Bundle and had a couple of fails. When I
7552 retried, everything resolved nicely. Can this be fixed to work
7555 The reason for this is that CPAN does not know the dependencies of all
7556 modules when it starts out. To decide about the additional items to
7557 install, it just uses data found in the generated Makefile. An
7558 undetected missing piece breaks the process. But it may well be that
7559 your Bundle installs some prerequisite later than some depending item
7560 and thus your second try is able to resolve everything. Please note,
7561 CPAN.pm does not know the dependency tree in advance and cannot sort
7562 the queue of things to install in a topologically correct order. It
7563 resolves perfectly well IFF all modules declare the prerequisites
7564 correctly with the PREREQ_PM attribute to MakeMaker. For bundles which
7565 fail and you need to install often, it is recommended to sort the Bundle
7566 definition file manually. It is planned to improve the metadata
7567 situation for dependencies on CPAN in general, but this will still
7572 In our intranet we have many modules for internal use. How
7573 can I integrate these modules with CPAN.pm but without uploading
7574 the modules to CPAN?
7576 Have a look at the CPAN::Site module.
7580 When I run CPAN's shell, I get error msg about line 1 to 4,
7581 setting meta input/output via the /etc/inputrc file.
7583 Some versions of readline are picky about capitalization in the
7584 /etc/inputrc file and specifically RedHat 6.2 comes with a
7585 /etc/inputrc that contains the word C<on> in lowercase. Change the
7586 occurrences of C<on> to C<On> and the bug should disappear.
7590 Some authors have strange characters in their names.
7592 Internally CPAN.pm uses the UTF-8 charset. If your terminal is
7593 expecting ISO-8859-1 charset, a converter can be activated by setting
7594 term_is_latin to a true value in your config file. One way of doing so
7597 cpan> ! $CPAN::Config->{term_is_latin}=1
7599 Extended support for converters will be made available as soon as perl
7600 becomes stable with regard to charset issues.
7604 When an install fails for some reason and then I correct the error
7605 condition and retry, CPAN.pm refuses to install the module, saying
7606 C<Already tried without success>.
7608 Use the force pragma like so
7610 force install Foo::Bar
7612 This does a bit more than really needed because it untars the
7613 distribution again and runs make and test and only then install.
7619 and then 'make install' directly in the subshell.
7621 Or you leave the CPAN shell and start it again.
7623 Or, if you're not really sure and just want to run some make, test or
7624 install command without this pesky error message, say C<force get
7625 Foo::Bar> first and then continue as always. C<Force get> I<forgets>
7626 previous error conditions.
7628 For the really curious, by accessing internals directly, you I<could>
7630 ! delete CPAN::Shell->expand("Distribution", \
7631 CPAN::Shell->expand("Module","Foo::Bar") \
7632 ->{RO}{CPAN_FILE})->{install}
7634 but this is neither guaranteed to work in the future nor is it a
7641 We should give coverage for B<all> of the CPAN and not just the PAUSE
7642 part, right? In this discussion CPAN and PAUSE have become equal --
7643 but they are not. PAUSE is authors/, modules/ and scripts/. CPAN is
7644 PAUSE plus the clpa/, doc/, misc/, ports/, and src/.
7646 Future development should be directed towards a better integration of
7649 If a Makefile.PL requires special customization of libraries, prompts
7650 the user for special input, etc. then you may find CPAN is not able to
7651 build the distribution. In that case, you should attempt the
7652 traditional method of building a Perl module package from a shell.
7656 Andreas Koenig E<lt>andreas.koenig@anima.deE<gt>
7660 Kawai,Takanori provides a Japanese translation of this manpage at
7661 http://member.nifty.ne.jp/hippo2000/perltips/CPAN.htm
7665 perl(1), CPAN::Nox(3)