1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
4 # $Id: CPAN.pm,v 1.390 2002/05/07 10:04:58 k Exp $
6 # only used during development:
8 # $Revision = "[".substr(q$Revision: 1.390 $, 10)."]";
15 use ExtUtils::MakeMaker (); # $SelfLoader::DEBUG=1;
16 use File::Basename ();
22 use Text::ParseWords ();
26 no lib "."; # we need to run chdir all over and we would get at wrong
29 require Mac::BuildTools if $^O eq 'MacOS';
31 END { $End++; &cleanup; }
54 $CPAN::Frontend ||= "CPAN::Shell";
55 $CPAN::Defaultsite ||= "ftp://ftp.perl.org/pub/CPAN";
60 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $HAS_USABLE $term
61 $Revision $Signal $End $Suppress_readline $Frontend
62 $Defaultsite $Have_warned);
64 @CPAN::ISA = qw(CPAN::Debug Exporter);
67 autobundle bundle expand force get cvs_import
68 install make readme recompile shell test clean
71 #-> sub CPAN::AUTOLOAD ;
76 @EXPORT{@EXPORT} = '';
77 CPAN::Config->load unless $CPAN::Config_loaded++;
78 if (exists $EXPORT{$l}){
81 $CPAN::Frontend->mywarn(qq{Unknown command "$AUTOLOAD". }.
90 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
91 CPAN::Config->load unless $CPAN::Config_loaded++;
93 my $oprompt = shift || "cpan> ";
94 my $prompt = $oprompt;
95 my $commandline = shift || "";
98 unless ($Suppress_readline) {
99 require Term::ReadLine;
102 $term->ReadLine eq "Term::ReadLine::Stub"
104 $term = Term::ReadLine->new('CPAN Monitor');
106 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
107 my $attribs = $term->Attribs;
108 $attribs->{attempted_completion_function} = sub {
109 &CPAN::Complete::gnu_cpl;
112 $readline::rl_completion_function =
113 $readline::rl_completion_function = 'CPAN::Complete::cpl';
115 # $term->OUT is autoflushed anyway
116 my $odef = select STDERR;
123 # no strict; # I do not recall why no strict was here (2000-09-03)
125 my $cwd = CPAN::anycwd();
126 my $try_detect_readline;
127 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
128 my $rl_avail = $Suppress_readline ? "suppressed" :
129 ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
130 "available (try 'install Bundle::CPAN')";
132 $CPAN::Frontend->myprint(
134 cpan shell -- CPAN exploration and modules installation (v%s%s)
142 unless $CPAN::Config->{'inhibit_startup_message'} ;
143 my($continuation) = "";
144 SHELLCOMMAND: while () {
145 if ($Suppress_readline) {
147 last SHELLCOMMAND unless defined ($_ = <> );
150 last SHELLCOMMAND unless
151 defined ($_ = $term->readline($prompt, $commandline));
153 $_ = "$continuation$_" if $continuation;
155 next SHELLCOMMAND if /^$/;
156 $_ = 'h' if /^\s*\?/;
157 if (/^(?:q(?:uit)?|bye|exit)$/i) {
167 use vars qw($import_done);
168 CPAN->import(':DEFAULT') unless $import_done++;
169 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
176 if ($] < 5.00322) { # parsewords had a bug until recently
179 eval { @line = Text::ParseWords::shellwords($_) };
180 warn($@), next SHELLCOMMAND if $@;
181 warn("Text::Parsewords could not parse the line [$_]"),
182 next SHELLCOMMAND unless @line;
184 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
185 my $command = shift @line;
186 eval { CPAN::Shell->$command(@line) };
188 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
189 $CPAN::Frontend->myprint("\n");
194 $commandline = ""; # I do want to be able to pass a default to
195 # shell, but on the second command I see no
198 CPAN::Queue->nullify_queue;
199 if ($try_detect_readline) {
200 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
202 $CPAN::META->has_inst("Term::ReadLine::Perl")
204 delete $INC{"Term/ReadLine.pm"};
206 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
207 require Term::ReadLine;
208 $CPAN::Frontend->myprint("\n$redef subroutines in ".
209 "Term::ReadLine redefined\n");
215 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
218 package CPAN::CacheMgr;
219 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
222 package CPAN::Config;
223 use vars qw(%can $dot_cpan);
226 'commit' => "Commit changes to disk",
227 'defaults' => "Reload defaults from disk",
228 'init' => "Interactive setting of all options",
232 use vars qw($Ua $Thesite $Themethod);
233 @CPAN::FTP::ISA = qw(CPAN::Debug);
235 package CPAN::LWP::UserAgent;
236 use vars qw(@ISA $USER $PASSWD $SETUPDONE);
237 # we delay requiring LWP::UserAgent and setting up inheritence until we need it
239 package CPAN::Complete;
240 @CPAN::Complete::ISA = qw(CPAN::Debug);
241 @CPAN::Complete::COMMANDS = sort qw(
242 ! a b d h i m o q r u autobundle clean dump
243 make test install force readme reload look
245 ) unless @CPAN::Complete::COMMANDS;
248 use vars qw($LAST_TIME $DATE_OF_02 $DATE_OF_03);
249 @CPAN::Index::ISA = qw(CPAN::Debug);
252 # use constant PROTOCOL => "2.0"; # outcommented to avoid warning on upgrade from 1.57
255 package CPAN::InfoObj;
256 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
258 package CPAN::Author;
259 @CPAN::Author::ISA = qw(CPAN::InfoObj);
261 package CPAN::Distribution;
262 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
264 package CPAN::Bundle;
265 @CPAN::Bundle::ISA = qw(CPAN::Module);
267 package CPAN::Module;
268 @CPAN::Module::ISA = qw(CPAN::InfoObj);
271 use vars qw($AUTOLOAD @ISA $COLOR_REGISTERED $ADVANCED_QUERY $PRINT_ORNAMENTING);
272 @CPAN::Shell::ISA = qw(CPAN::Debug);
273 $COLOR_REGISTERED ||= 0;
274 $PRINT_ORNAMENTING ||= 0;
276 #-> sub CPAN::Shell::AUTOLOAD ;
278 my($autoload) = $AUTOLOAD;
279 my $class = shift(@_);
280 # warn "autoload[$autoload] class[$class]";
281 $autoload =~ s/.*:://;
282 if ($autoload =~ /^w/) {
283 if ($CPAN::META->has_inst('CPAN::WAIT')) {
284 CPAN::WAIT->$autoload(@_);
286 $CPAN::Frontend->mywarn(qq{
287 Commands starting with "w" require CPAN::WAIT to be installed.
288 Please consider installing CPAN::WAIT to use the fulltext index.
289 For this you just need to type
294 $CPAN::Frontend->mywarn(qq{Unknown command '$autoload'. }.
300 package CPAN::Tarzip;
301 use vars qw($AUTOLOAD @ISA $BUGHUNTING);
302 @CPAN::Tarzip::ISA = qw(CPAN::Debug);
303 $BUGHUNTING = 0; # released code must have turned off
307 # One use of the queue is to determine if we should or shouldn't
308 # announce the availability of a new CPAN module
310 # Now we try to use it for dependency tracking. For that to happen
311 # we need to draw a dependency tree and do the leaves first. This can
312 # easily be reached by running CPAN.pm recursively, but we don't want
313 # to waste memory and run into deep recursion. So what we can do is
316 # CPAN::Queue is the package where the queue is maintained. Dependencies
317 # often have high priority and must be brought to the head of the queue,
318 # possibly by jumping the queue if they are already there. My first code
319 # attempt tried to be extremely correct. Whenever a module needed
320 # immediate treatment, I either unshifted it to the front of the queue,
321 # or, if it was already in the queue, I spliced and let it bypass the
322 # others. This became a too correct model that made it impossible to put
323 # an item more than once into the queue. Why would you need that? Well,
324 # you need temporary duplicates as the manager of the queue is a loop
327 # (1) looks at the first item in the queue without shifting it off
329 # (2) cares for the item
331 # (3) removes the item from the queue, *even if its agenda failed and
332 # even if the item isn't the first in the queue anymore* (that way
333 # protecting against never ending queues)
335 # So if an item has prerequisites, the installation fails now, but we
336 # want to retry later. That's easy if we have it twice in the queue.
338 # I also expect insane dependency situations where an item gets more
339 # than two lives in the queue. Simplest example is triggered by 'install
340 # Foo Foo Foo'. People make this kind of mistakes and I don't want to
341 # get in the way. I wanted the queue manager to be a dumb servant, not
342 # one that knows everything.
344 # Who would I tell in this model that the user wants to be asked before
345 # processing? I can't attach that information to the module object,
346 # because not modules are installed but distributions. So I'd have to
347 # tell the distribution object that it should ask the user before
348 # processing. Where would the question be triggered then? Most probably
349 # in CPAN::Distribution::rematein.
350 # Hope that makes sense, my head is a bit off:-) -- AK
357 my $self = bless { qmod => $s }, $class;
362 # CPAN::Queue::first ;
368 # CPAN::Queue::delete_first ;
370 my($class,$what) = @_;
372 for my $i (0..$#All) {
373 if ( $All[$i]->{qmod} eq $what ) {
380 # CPAN::Queue::jumpqueue ;
384 CPAN->debug(sprintf("before jumpqueue All[%s] what[%s]",
385 join(",",map {$_->{qmod}} @All),
388 WHAT: for my $what (reverse @what) {
390 for (my $i=0; $i<$#All;$i++) { #prevent deep recursion
391 CPAN->debug("i[$All[$i]]what[$what]") if $CPAN::DEBUG;
392 if ($All[$i]->{qmod} eq $what){
394 if ($jumped > 100) { # one's OK if e.g. just
395 # processing now; more are OK if
396 # user typed it several times
397 $CPAN::Frontend->mywarn(
398 qq{Object [$what] queued more than 100 times, ignoring}
404 my $obj = bless { qmod => $what }, $class;
407 CPAN->debug(sprintf("after jumpqueue All[%s] what[%s]",
408 join(",",map {$_->{qmod}} @All),
413 # CPAN::Queue::exists ;
415 my($self,$what) = @_;
416 my @all = map { $_->{qmod} } @All;
417 my $exists = grep { $_->{qmod} eq $what } @All;
418 # warn "in exists what[$what] all[@all] exists[$exists]";
422 # CPAN::Queue::delete ;
425 @All = grep { $_->{qmod} ne $mod } @All;
428 # CPAN::Queue::nullify_queue ;
437 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
439 # from here on only subs.
440 ################################################################################
442 #-> sub CPAN::all_objects ;
444 my($mgr,$class) = @_;
445 CPAN::Config->load unless $CPAN::Config_loaded++;
446 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
448 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
450 *all = \&all_objects;
452 # Called by shell, not in batch mode. In batch mode I see no risk in
453 # having many processes updating something as installations are
454 # continually checked at runtime. In shell mode I suspect it is
455 # unintentional to open more than one shell at a time
457 #-> sub CPAN::checklock ;
460 my $lockfile = File::Spec->catfile($CPAN::Config->{cpan_home},".lock");
461 if (-f $lockfile && -M _ > 0) {
462 my $fh = FileHandle->new($lockfile) or
463 $CPAN::Frontend->mydie("Could not open $lockfile: $!");
464 my $otherpid = <$fh>;
465 my $otherhost = <$fh>;
467 if (defined $otherpid && $otherpid) {
470 if (defined $otherhost && $otherhost) {
473 my $thishost = hostname();
474 if (defined $otherhost && defined $thishost &&
475 $otherhost ne '' && $thishost ne '' &&
476 $otherhost ne $thishost) {
477 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile $lockfile\n".
478 "reports other host $otherhost and other process $otherpid.\n".
479 "Cannot proceed.\n"));
481 elsif (defined $otherpid && $otherpid) {
482 return if $$ == $otherpid; # should never happen
483 $CPAN::Frontend->mywarn(
485 There seems to be running another CPAN process (pid $otherpid). Contacting...
487 if (kill 0, $otherpid) {
488 $CPAN::Frontend->mydie(qq{Other job is running.
489 You may want to kill it and delete the lockfile, maybe. On UNIX try:
493 } elsif (-w $lockfile) {
495 ExtUtils::MakeMaker::prompt
496 (qq{Other job not responding. Shall I overwrite }.
497 qq{the lockfile? (Y/N)},"y");
498 $CPAN::Frontend->myexit("Ok, bye\n")
499 unless $ans =~ /^y/i;
502 qq{Lockfile $lockfile not writeable by you. }.
503 qq{Cannot proceed.\n}.
506 qq{ and then rerun us.\n}
510 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile $lockfile\n".
511 "reports other process with ID ".
512 "$otherpid. Cannot proceed.\n"));
515 my $dotcpan = $CPAN::Config->{cpan_home};
516 eval { File::Path::mkpath($dotcpan);};
518 # A special case at least for Jarkko.
523 $symlinkcpan = readlink $dotcpan;
524 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
525 eval { File::Path::mkpath($symlinkcpan); };
529 $CPAN::Frontend->mywarn(qq{
530 Working directory $symlinkcpan created.
534 unless (-d $dotcpan) {
536 Your configuration suggests "$dotcpan" as your
537 CPAN.pm working directory. I could not create this directory due
538 to this error: $firsterror\n};
540 As "$dotcpan" is a symlink to "$symlinkcpan",
541 I tried to create that, but I failed with this error: $seconderror
544 Please make sure the directory exists and is writable.
546 $CPAN::Frontend->mydie($diemess);
550 unless ($fh = FileHandle->new(">$lockfile")) {
551 if ($! =~ /Permission/) {
552 my $incc = $INC{'CPAN/Config.pm'};
553 my $myincc = File::Spec->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
554 $CPAN::Frontend->myprint(qq{
556 Your configuration suggests that CPAN.pm should use a working
558 $CPAN::Config->{cpan_home}
559 Unfortunately we could not create the lock file
561 due to permission problems.
563 Please make sure that the configuration variable
564 \$CPAN::Config->{cpan_home}
565 points to a directory where you can write a .lock file. You can set
566 this variable in either
573 $CPAN::Frontend->mydie("Could not open >$lockfile: $!");
575 $fh->print($$, "\n");
576 $fh->print(hostname(), "\n");
577 $self->{LOCK} = $lockfile;
581 $CPAN::Frontend->mydie("Got SIGTERM, leaving");
586 $CPAN::Frontend->mydie("Got another SIGINT") if $Signal;
587 print "Caught SIGINT\n";
591 # From: Larry Wall <larry@wall.org>
592 # Subject: Re: deprecating SIGDIE
593 # To: perl5-porters@perl.org
594 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
596 # The original intent of __DIE__ was only to allow you to substitute one
597 # kind of death for another on an application-wide basis without respect
598 # to whether you were in an eval or not. As a global backstop, it should
599 # not be used any more lightly (or any more heavily :-) than class
600 # UNIVERSAL. Any attempt to build a general exception model on it should
601 # be politely squashed. Any bug that causes every eval {} to have to be
602 # modified should be not so politely squashed.
604 # Those are my current opinions. It is also my optinion that polite
605 # arguments degenerate to personal arguments far too frequently, and that
606 # when they do, it's because both people wanted it to, or at least didn't
607 # sufficiently want it not to.
611 # global backstop to cleanup if we should really die
612 $SIG{__DIE__} = \&cleanup;
613 $self->debug("Signal handler set.") if $CPAN::DEBUG;
616 #-> sub CPAN::DESTROY ;
618 &cleanup; # need an eval?
621 #-> sub CPAN::anycwd ;
624 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
629 sub cwd {Cwd::cwd();}
631 #-> sub CPAN::getcwd ;
632 sub getcwd {Cwd::getcwd();}
634 #-> sub CPAN::exists ;
636 my($mgr,$class,$id) = @_;
637 CPAN::Config->load unless $CPAN::Config_loaded++;
639 ### Carp::croak "exists called without class argument" unless $class;
641 exists $META->{readonly}{$class}{$id} or
642 exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
645 #-> sub CPAN::delete ;
647 my($mgr,$class,$id) = @_;
648 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
649 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
652 #-> sub CPAN::has_usable
653 # has_inst is sometimes too optimistic, we should replace it with this
654 # has_usable whenever a case is given
656 my($self,$mod,$message) = @_;
657 return 1 if $HAS_USABLE->{$mod};
658 my $has_inst = $self->has_inst($mod,$message);
659 return unless $has_inst;
662 LWP => [ # we frequently had "Can't locate object
663 # method "new" via package "LWP::UserAgent" at
664 # (eval 69) line 2006
666 sub {require LWP::UserAgent},
667 sub {require HTTP::Request},
668 sub {require URI::URL},
671 sub {require Net::FTP},
672 sub {require Net::Config},
675 if ($usable->{$mod}) {
676 for my $c (0..$#{$usable->{$mod}}) {
677 my $code = $usable->{$mod}[$c];
678 my $ret = eval { &$code() };
680 warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
685 return $HAS_USABLE->{$mod} = 1;
688 #-> sub CPAN::has_inst
690 my($self,$mod,$message) = @_;
691 Carp::croak("CPAN->has_inst() called without an argument")
693 if (defined $message && $message eq "no"
695 exists $CPAN::META->{dontload_hash}{$mod} # unsafe meta access, ok
697 exists $CPAN::Config->{dontload_hash}{$mod}
699 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
705 $file =~ s|/|\\|g if $^O eq 'MSWin32';
708 # checking %INC is wrong, because $INC{LWP} may be true
709 # although $INC{"URI/URL.pm"} may have failed. But as
710 # I really want to say "bla loaded OK", I have to somehow
712 ### warn "$file in %INC"; #debug
714 } elsif (eval { require $file }) {
715 # eval is good: if we haven't yet read the database it's
716 # perfect and if we have installed the module in the meantime,
717 # it tries again. The second require is only a NOOP returning
718 # 1 if we had success, otherwise it's retrying
720 $CPAN::Frontend->myprint("CPAN: $mod loaded ok\n");
721 if ($mod eq "CPAN::WAIT") {
722 push @CPAN::Shell::ISA, CPAN::WAIT;
725 } elsif ($mod eq "Net::FTP") {
726 $CPAN::Frontend->mywarn(qq{
727 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
729 install Bundle::libnet
731 }) unless $Have_warned->{"Net::FTP"}++;
733 } elsif ($mod eq "Digest::MD5"){
734 $CPAN::Frontend->myprint(qq{
735 CPAN: MD5 security checks disabled because Digest::MD5 not installed.
736 Please consider installing the Digest::MD5 module.
741 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
746 #-> sub CPAN::instance ;
748 my($mgr,$class,$id) = @_;
751 # unsafe meta access, ok?
752 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
753 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
761 #-> sub CPAN::cleanup ;
763 # warn "cleanup called with arg[@_] End[$End] Signal[$Signal]";
764 local $SIG{__DIE__} = '';
769 0 && # disabled, try reload cpan with it
770 $] > 5.004_60 # thereabouts
775 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
777 $subroutine eq '(eval)';
780 return if $ineval && !$End;
781 return unless defined $META->{LOCK}; # unsafe meta access, ok
782 return unless -f $META->{LOCK}; # unsafe meta access, ok
783 unlink $META->{LOCK}; # unsafe meta access, ok
785 # Carp::cluck("DEBUGGING");
786 $CPAN::Frontend->mywarn("Lockfile removed.\n");
790 my($self,$what) = @_;
791 $self->{is_tested}{$what} = 1;
795 my($self,$what) = @_;
796 delete $self->{is_tested}{$what};
801 $self->{is_tested} ||= {};
802 return unless %{$self->{is_tested}};
803 my $env = $ENV{PERL5LIB};
804 $env = $ENV{PERLLIB} unless defined $env;
806 push @env, $env if defined $env and length $env;
807 my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}};
808 $CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
809 $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
812 package CPAN::CacheMgr;
814 #-> sub CPAN::CacheMgr::as_string ;
816 eval { require Data::Dumper };
818 return shift->SUPER::as_string;
820 return Data::Dumper::Dumper(shift);
824 #-> sub CPAN::CacheMgr::cachesize ;
829 #-> sub CPAN::CacheMgr::tidyup ;
832 return unless -d $self->{ID};
833 while ($self->{DU} > $self->{'MAX'} ) {
834 my($toremove) = shift @{$self->{FIFO}};
835 $CPAN::Frontend->myprint(sprintf(
836 "Deleting from cache".
837 ": $toremove (%.1f>%.1f MB)\n",
838 $self->{DU}, $self->{'MAX'})
840 return if $CPAN::Signal;
841 $self->force_clean_cache($toremove);
842 return if $CPAN::Signal;
846 #-> sub CPAN::CacheMgr::dir ;
851 #-> sub CPAN::CacheMgr::entries ;
854 return unless defined $dir;
855 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
856 $dir ||= $self->{ID};
857 my($cwd) = CPAN::anycwd();
858 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
859 my $dh = DirHandle->new(File::Spec->curdir)
860 or Carp::croak("Couldn't opendir $dir: $!");
863 next if $_ eq "." || $_ eq "..";
865 push @entries, File::Spec->catfile($dir,$_);
867 push @entries, File::Spec->catdir($dir,$_);
869 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
872 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
873 sort { -M $b <=> -M $a} @entries;
876 #-> sub CPAN::CacheMgr::disk_usage ;
879 return if exists $self->{SIZE}{$dir};
880 return if $CPAN::Signal;
884 $File::Find::prune++ if $CPAN::Signal;
886 if ($^O eq 'MacOS') {
888 my $cat = Mac::Files::FSpGetCatInfo($_);
889 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
896 return if $CPAN::Signal;
897 $self->{SIZE}{$dir} = $Du/1024/1024;
898 push @{$self->{FIFO}}, $dir;
899 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
900 $self->{DU} += $Du/1024/1024;
904 #-> sub CPAN::CacheMgr::force_clean_cache ;
905 sub force_clean_cache {
907 return unless -e $dir;
908 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
910 File::Path::rmtree($dir);
911 $self->{DU} -= $self->{SIZE}{$dir};
912 delete $self->{SIZE}{$dir};
915 #-> sub CPAN::CacheMgr::new ;
922 ID => $CPAN::Config->{'build_dir'},
923 MAX => $CPAN::Config->{'build_cache'},
924 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
927 File::Path::mkpath($self->{ID});
928 my $dh = DirHandle->new($self->{ID});
932 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
934 CPAN->debug($debug) if $CPAN::DEBUG;
938 #-> sub CPAN::CacheMgr::scan_cache ;
941 return if $self->{SCAN} eq 'never';
942 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
943 unless $self->{SCAN} eq 'atstart';
944 $CPAN::Frontend->myprint(
945 sprintf("Scanning cache %s for sizes\n",
948 for $e ($self->entries($self->{ID})) {
949 next if $e eq ".." || $e eq ".";
950 $self->disk_usage($e);
951 return if $CPAN::Signal;
958 #-> sub CPAN::Debug::debug ;
961 my($caller,$func,$line,@rest) = caller(1); # caller(0) eg
962 # Complete, caller(1)
964 ($caller) = caller(0);
966 $arg = "" unless defined $arg;
967 my $rest = join "|", map { defined $_ ? $_ : "UNDEF" } @rest;
968 if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
969 if ($arg and ref $arg) {
970 eval { require Data::Dumper };
972 $CPAN::Frontend->myprint($arg->as_string);
974 $CPAN::Frontend->myprint(Data::Dumper::Dumper($arg));
977 $CPAN::Frontend->myprint("Debug($caller:$func,$line,[$rest]): $arg\n");
982 package CPAN::Config;
984 #-> sub CPAN::Config::edit ;
985 # returns true on successful action
987 my($self,@args) = @_;
989 CPAN->debug("self[$self]args[".join(" | ",@args)."]");
990 my($o,$str,$func,$args,$key_exists);
996 CPAN->debug("o[$o]") if $CPAN::DEBUG;
1000 CPAN->debug("func[$func]") if $CPAN::DEBUG;
1002 # Let's avoid eval, it's easier to comprehend without.
1003 if ($func eq "push") {
1004 push @{$CPAN::Config->{$o}}, @args;
1006 } elsif ($func eq "pop") {
1007 pop @{$CPAN::Config->{$o}};
1009 } elsif ($func eq "shift") {
1010 shift @{$CPAN::Config->{$o}};
1012 } elsif ($func eq "unshift") {
1013 unshift @{$CPAN::Config->{$o}}, @args;
1015 } elsif ($func eq "splice") {
1016 splice @{$CPAN::Config->{$o}}, @args;
1019 $CPAN::Config->{$o} = [@args];
1022 $self->prettyprint($o);
1024 if ($o eq "urllist" && $changed) {
1025 # reset the cached values
1026 undef $CPAN::FTP::Thesite;
1027 undef $CPAN::FTP::Themethod;
1031 $CPAN::Config->{$o} = $args[0] if defined $args[0];
1032 $self->prettyprint($o);
1039 my $v = $CPAN::Config->{$k};
1041 my(@report) = ref $v eq "ARRAY" ?
1043 map { sprintf(" %-18s => %s\n",
1045 defined $v->{$_} ? $v->{$_} : "UNDEFINED"
1047 $CPAN::Frontend->myprint(
1054 map {"\t$_\n"} @report
1057 } elsif (defined $v) {
1058 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1060 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, "UNDEFINED");
1064 #-> sub CPAN::Config::commit ;
1066 my($self,$configpm) = @_;
1067 unless (defined $configpm){
1068 $configpm ||= $INC{"CPAN/MyConfig.pm"};
1069 $configpm ||= $INC{"CPAN/Config.pm"};
1070 $configpm || Carp::confess(q{
1071 CPAN::Config::commit called without an argument.
1072 Please specify a filename where to save the configuration or try
1073 "o conf init" to have an interactive course through configing.
1078 $mode = (stat $configpm)[2];
1079 if ($mode && ! -w _) {
1080 Carp::confess("$configpm is not writable");
1085 $msg = <<EOF unless $configpm =~ /MyConfig/;
1087 # This is CPAN.pm's systemwide configuration file. This file provides
1088 # defaults for users, and the values can be changed in a per-user
1089 # configuration file. The user-config file is being looked for as
1090 # ~/.cpan/CPAN/MyConfig.pm.
1094 my($fh) = FileHandle->new;
1095 rename $configpm, "$configpm~" if -f $configpm;
1096 open $fh, ">$configpm" or
1097 $CPAN::Frontend->mydie("Couldn't open >$configpm: $!");
1098 $fh->print(qq[$msg\$CPAN::Config = \{\n]);
1099 foreach (sort keys %$CPAN::Config) {
1102 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}),
1107 $fh->print("};\n1;\n__END__\n");
1110 #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
1111 #chmod $mode, $configpm;
1112 ###why was that so? $self->defaults;
1113 $CPAN::Frontend->myprint("commit: wrote $configpm\n");
1117 *default = \&defaults;
1118 #-> sub CPAN::Config::defaults ;
1128 undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
1137 # This is a piece of repeated code that is abstracted here for
1138 # maintainability. RMB
1141 my($configpmdir, $configpmtest) = @_;
1142 if (-w $configpmtest) {
1143 return $configpmtest;
1144 } elsif (-w $configpmdir) {
1145 #_#_# following code dumped core on me with 5.003_11, a.k.
1146 my $configpm_bak = "$configpmtest.bak";
1147 unlink $configpm_bak if -f $configpm_bak;
1148 if( -f $configpmtest ) {
1149 if( rename $configpmtest, $configpm_bak ) {
1150 $CPAN::Frontend->mywarn(<<END)
1151 Old configuration file $configpmtest
1152 moved to $configpm_bak
1156 my $fh = FileHandle->new;
1157 if ($fh->open(">$configpmtest")) {
1159 return $configpmtest;
1161 # Should never happen
1162 Carp::confess("Cannot open >$configpmtest");
1167 #-> sub CPAN::Config::load ;
1172 eval {require CPAN::Config;}; # We eval because of some
1173 # MakeMaker problems
1174 unless ($dot_cpan++){
1175 unshift @INC, File::Spec->catdir($ENV{HOME},".cpan");
1176 eval {require CPAN::MyConfig;}; # where you can override
1177 # system wide settings
1180 return unless @miss = $self->missing_config_data;
1182 require CPAN::FirstTime;
1183 my($configpm,$fh,$redo,$theycalled);
1185 $theycalled++ if @miss==1 && $miss[0] eq 'inhibit_startup_message';
1186 if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
1187 $configpm = $INC{"CPAN/Config.pm"};
1189 } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
1190 $configpm = $INC{"CPAN/MyConfig.pm"};
1193 my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
1194 my($configpmdir) = File::Spec->catdir($path_to_cpan,"CPAN");
1195 my($configpmtest) = File::Spec->catfile($configpmdir,"Config.pm");
1196 if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
1197 $configpm = _configpmtest($configpmdir,$configpmtest);
1199 unless ($configpm) {
1200 $configpmdir = File::Spec->catdir($ENV{HOME},".cpan","CPAN");
1201 File::Path::mkpath($configpmdir);
1202 $configpmtest = File::Spec->catfile($configpmdir,"MyConfig.pm");
1203 $configpm = _configpmtest($configpmdir,$configpmtest);
1204 unless ($configpm) {
1205 Carp::confess(qq{WARNING: CPAN.pm is unable to }.
1206 qq{create a configuration file.});
1211 $CPAN::Frontend->myprint(<<END) if $redo && ! $theycalled;
1212 We have to reconfigure CPAN.pm due to following uninitialized parameters:
1216 $CPAN::Frontend->myprint(qq{
1217 $configpm initialized.
1220 CPAN::FirstTime::init($configpm);
1223 #-> sub CPAN::Config::missing_config_data ;
1224 sub missing_config_data {
1227 "cpan_home", "keep_source_where", "build_dir", "build_cache",
1228 "scan_cache", "index_expire", "gzip", "tar", "unzip", "make",
1230 "makepl_arg", "make_arg", "make_install_arg", "urllist",
1231 "inhibit_startup_message", "ftp_proxy", "http_proxy", "no_proxy",
1232 "prerequisites_policy",
1235 push @miss, $_ unless defined $CPAN::Config->{$_};
1240 #-> sub CPAN::Config::unload ;
1242 delete $INC{'CPAN/MyConfig.pm'};
1243 delete $INC{'CPAN/Config.pm'};
1246 #-> sub CPAN::Config::help ;
1248 $CPAN::Frontend->myprint(q[
1250 defaults reload default config values from disk
1251 commit commit session changes to disk
1252 init go through a dialog to set all parameters
1254 You may edit key values in the follow fashion (the "o" is a literal
1257 o conf build_cache 15
1259 o conf build_dir "/foo/bar"
1261 o conf urllist shift
1263 o conf urllist unshift ftp://ftp.foo.bar/
1266 undef; #don't reprint CPAN::Config
1269 #-> sub CPAN::Config::cpl ;
1271 my($word,$line,$pos) = @_;
1273 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1274 my(@words) = split " ", substr($line,0,$pos+1);
1279 $words[2] =~ /list$/ && @words == 3
1281 $words[2] =~ /list$/ && @words == 4 && length($word)
1284 return grep /^\Q$word\E/, qw(splice shift unshift pop push);
1285 } elsif (@words >= 4) {
1288 my(@o_conf) = (keys %CPAN::Config::can, keys %$CPAN::Config);
1289 return grep /^\Q$word\E/, @o_conf;
1292 package CPAN::Shell;
1294 #-> sub CPAN::Shell::h ;
1296 my($class,$about) = @_;
1297 if (defined $about) {
1298 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
1300 $CPAN::Frontend->myprint(q{
1302 command argument description
1303 a,b,d,m WORD or /REGEXP/ about authors, bundles, distributions, modules
1304 i WORD or /REGEXP/ about anything of above
1305 r NONE reinstall recommendations
1306 ls AUTHOR about files in the author's directory
1308 Download, Test, Make, Install...
1310 make make (implies get)
1311 test MODULES, make test (implies make)
1312 install DISTS, BUNDLES make install (implies test)
1314 look open subshell in these dists' directories
1315 readme display these dists' README files
1318 h,? display this menu ! perl-code eval a perl command
1319 o conf [opt] set and query options q quit the cpan shell
1320 reload cpan load CPAN.pm again reload index load newer indices
1321 autobundle Snapshot force cmd unconditionally do cmd});
1327 #-> sub CPAN::Shell::a ;
1329 my($self,@arg) = @_;
1330 # authors are always UPPERCASE
1332 $_ = uc $_ unless /=/;
1334 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1337 #-> sub CPAN::Shell::ls ;
1339 my($self,@arg) = @_;
1342 unless (/^[A-Z\-]+$/i) {
1343 $CPAN::Frontend->mywarn("ls command rejects argument $_: not an author");
1346 push @accept, uc $_;
1348 for my $a (@accept){
1349 my $author = $self->expand('Author',$a) or die "No author found for $a";
1354 #-> sub CPAN::Shell::local_bundles ;
1356 my($self,@which) = @_;
1357 my($incdir,$bdir,$dh);
1358 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1359 my @bbase = "Bundle";
1360 while (my $bbase = shift @bbase) {
1361 $bdir = File::Spec->catdir($incdir,split /::/, $bbase);
1362 CPAN->debug("bdir[$bdir]\@bbase[@bbase]") if $CPAN::DEBUG;
1363 if ($dh = DirHandle->new($bdir)) { # may fail
1365 for $entry ($dh->read) {
1366 next if $entry =~ /^\./;
1367 if (-d File::Spec->catdir($bdir,$entry)){
1368 push @bbase, "$bbase\::$entry";
1370 next unless $entry =~ s/\.pm(?!\n)\Z//;
1371 $CPAN::META->instance('CPAN::Bundle',"$bbase\::$entry");
1379 #-> sub CPAN::Shell::b ;
1381 my($self,@which) = @_;
1382 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1383 $self->local_bundles;
1384 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1387 #-> sub CPAN::Shell::d ;
1388 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1390 #-> sub CPAN::Shell::m ;
1391 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
1392 $CPAN::Frontend->myprint(shift->format_result('Module',@_));
1395 #-> sub CPAN::Shell::i ;
1400 @type = qw/Author Bundle Distribution Module/;
1401 @args = '/./' unless @args;
1404 push @result, $self->expand($type,@args);
1406 my $result = @result == 1 ?
1407 $result[0]->as_string :
1409 "No objects found of any type for argument @args\n" :
1411 (map {$_->as_glimpse} @result),
1412 scalar @result, " items found\n",
1414 $CPAN::Frontend->myprint($result);
1417 #-> sub CPAN::Shell::o ;
1419 # CPAN::Shell::o and CPAN::Config::edit are closely related. 'o conf'
1420 # should have been called set and 'o debug' maybe 'set debug'
1422 my($self,$o_type,@o_what) = @_;
1424 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1425 if ($o_type eq 'conf') {
1426 shift @o_what if @o_what && $o_what[0] eq 'help';
1427 if (!@o_what) { # print all things, "o conf"
1429 $CPAN::Frontend->myprint("CPAN::Config options");
1430 if (exists $INC{'CPAN/Config.pm'}) {
1431 $CPAN::Frontend->myprint(" from $INC{'CPAN/Config.pm'}");
1433 if (exists $INC{'CPAN/MyConfig.pm'}) {
1434 $CPAN::Frontend->myprint(" and $INC{'CPAN/MyConfig.pm'}");
1436 $CPAN::Frontend->myprint(":\n");
1437 for $k (sort keys %CPAN::Config::can) {
1438 $v = $CPAN::Config::can{$k};
1439 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1441 $CPAN::Frontend->myprint("\n");
1442 for $k (sort keys %$CPAN::Config) {
1443 CPAN::Config->prettyprint($k);
1445 $CPAN::Frontend->myprint("\n");
1446 } elsif (!CPAN::Config->edit(@o_what)) {
1447 $CPAN::Frontend->myprint(qq{Type 'o conf' to view configuration }.
1448 qq{edit options\n\n});
1450 } elsif ($o_type eq 'debug') {
1452 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1455 my($what) = shift @o_what;
1456 if ($what =~ s/^-// && exists $CPAN::DEBUG{$what}) {
1457 $CPAN::DEBUG &= $CPAN::DEBUG ^ $CPAN::DEBUG{$what};
1460 if ( exists $CPAN::DEBUG{$what} ) {
1461 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1462 } elsif ($what =~ /^\d/) {
1463 $CPAN::DEBUG = $what;
1464 } elsif (lc $what eq 'all') {
1466 for (values %CPAN::DEBUG) {
1469 $CPAN::DEBUG = $max;
1472 for (keys %CPAN::DEBUG) {
1473 next unless lc($_) eq lc($what);
1474 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1477 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1482 my $raw = "Valid options for debug are ".
1483 join(", ",sort(keys %CPAN::DEBUG), 'all').
1484 qq{ or a number. Completion works on the options. }.
1485 qq{Case is ignored.};
1487 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
1488 $CPAN::Frontend->myprint("\n\n");
1491 $CPAN::Frontend->myprint("Options set for debugging:\n");
1493 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1494 $v = $CPAN::DEBUG{$k};
1495 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
1496 if $v & $CPAN::DEBUG;
1499 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1502 $CPAN::Frontend->myprint(qq{
1504 conf set or get configuration variables
1505 debug set or get debugging options
1510 sub paintdots_onreload {
1513 if ( $_[0] =~ /[Ss]ubroutine (\w+) redefined/ ) {
1517 # $CPAN::Frontend->myprint(".($subr)");
1518 $CPAN::Frontend->myprint(".");
1525 #-> sub CPAN::Shell::reload ;
1527 my($self,$command,@arg) = @_;
1529 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1530 if ($command =~ /cpan/i) {
1531 CPAN->debug("reloading the whole CPAN.pm") if $CPAN::DEBUG;
1532 my $fh = FileHandle->new($INC{'CPAN.pm'});
1535 local($SIG{__WARN__}) = paintdots_onreload(\$redef);
1538 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1539 } elsif ($command =~ /index/) {
1540 CPAN::Index->force_reload;
1542 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN.pm file
1543 index re-reads the index files\n});
1547 #-> sub CPAN::Shell::_binary_extensions ;
1548 sub _binary_extensions {
1549 my($self) = shift @_;
1550 my(@result,$module,%seen,%need,$headerdone);
1551 for $module ($self->expand('Module','/./')) {
1552 my $file = $module->cpan_file;
1553 next if $file eq "N/A";
1554 next if $file =~ /^Contact Author/;
1555 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
1556 next if $dist->isa_perl;
1557 next unless $module->xs_file;
1559 $CPAN::Frontend->myprint(".");
1560 push @result, $module;
1562 # print join " | ", @result;
1563 $CPAN::Frontend->myprint("\n");
1567 #-> sub CPAN::Shell::recompile ;
1569 my($self) = shift @_;
1570 my($module,@module,$cpan_file,%dist);
1571 @module = $self->_binary_extensions();
1572 for $module (@module){ # we force now and compile later, so we
1574 $cpan_file = $module->cpan_file;
1575 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1577 $dist{$cpan_file}++;
1579 for $cpan_file (sort keys %dist) {
1580 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1581 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1583 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1584 # stop a package from recompiling,
1585 # e.g. IO-1.12 when we have perl5.003_10
1589 #-> sub CPAN::Shell::_u_r_common ;
1591 my($self) = shift @_;
1592 my($what) = shift @_;
1593 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1594 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
1595 $what && $what =~ /^[aru]$/;
1597 @args = '/./' unless @args;
1598 my(@result,$module,%seen,%need,$headerdone,
1599 $version_undefs,$version_zeroes);
1600 $version_undefs = $version_zeroes = 0;
1601 my $sprintf = "%s%-25s%s %9s %9s %s\n";
1602 my @expand = $self->expand('Module',@args);
1603 my $expand = scalar @expand;
1604 if (0) { # Looks like noise to me, was very useful for debugging
1605 # for metadata cache
1606 $CPAN::Frontend->myprint(sprintf "%d matches in the database\n", $expand);
1608 for $module (@expand) {
1609 my $file = $module->cpan_file;
1610 next unless defined $file; # ??
1611 my($latest) = $module->cpan_version;
1612 my($inst_file) = $module->inst_file;
1614 return if $CPAN::Signal;
1617 $have = $module->inst_version;
1618 } elsif ($what eq "r") {
1619 $have = $module->inst_version;
1621 if ($have eq "undef"){
1623 } elsif ($have == 0){
1626 next unless CPAN::Version->vgt($latest, $have);
1627 # to be pedantic we should probably say:
1628 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1629 # to catch the case where CPAN has a version 0 and we have a version undef
1630 } elsif ($what eq "u") {
1636 } elsif ($what eq "r") {
1638 } elsif ($what eq "u") {
1642 return if $CPAN::Signal; # this is sometimes lengthy
1645 push @result, sprintf "%s %s\n", $module->id, $have;
1646 } elsif ($what eq "r") {
1647 push @result, $module->id;
1648 next if $seen{$file}++;
1649 } elsif ($what eq "u") {
1650 push @result, $module->id;
1651 next if $seen{$file}++;
1652 next if $file =~ /^Contact/;
1654 unless ($headerdone++){
1655 $CPAN::Frontend->myprint("\n");
1656 $CPAN::Frontend->myprint(sprintf(
1659 "Package namespace",
1671 $CPAN::META->has_inst("Term::ANSIColor")
1673 $module->{RO}{description}
1675 $color_on = Term::ANSIColor::color("green");
1676 $color_off = Term::ANSIColor::color("reset");
1678 $CPAN::Frontend->myprint(sprintf $sprintf,
1685 $need{$module->id}++;
1689 $CPAN::Frontend->myprint("No modules found for @args\n");
1690 } elsif ($what eq "r") {
1691 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1695 if ($version_zeroes) {
1696 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1697 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1698 qq{a version number of 0\n});
1700 if ($version_undefs) {
1701 my $s_has = $version_undefs > 1 ? "s have" : " has";
1702 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1703 qq{parseable version number\n});
1709 #-> sub CPAN::Shell::r ;
1711 shift->_u_r_common("r",@_);
1714 #-> sub CPAN::Shell::u ;
1716 shift->_u_r_common("u",@_);
1719 #-> sub CPAN::Shell::autobundle ;
1722 CPAN::Config->load unless $CPAN::Config_loaded++;
1723 my(@bundle) = $self->_u_r_common("a",@_);
1724 my($todir) = File::Spec->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1725 File::Path::mkpath($todir);
1726 unless (-d $todir) {
1727 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
1730 my($y,$m,$d) = (localtime)[5,4,3];
1734 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1735 my($to) = File::Spec->catfile($todir,"$me.pm");
1737 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1738 $to = File::Spec->catfile($todir,"$me.pm");
1740 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1742 "package Bundle::$me;\n\n",
1743 "\$VERSION = '0.01';\n\n",
1747 "Bundle::$me - Snapshot of installation on ",
1748 $Config::Config{'myhostname'},
1751 "\n\n=head1 SYNOPSIS\n\n",
1752 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1753 "=head1 CONTENTS\n\n",
1754 join("\n", @bundle),
1755 "\n\n=head1 CONFIGURATION\n\n",
1757 "\n\n=head1 AUTHOR\n\n",
1758 "This Bundle has been generated automatically ",
1759 "by the autobundle routine in CPAN.pm.\n",
1762 $CPAN::Frontend->myprint("\nWrote bundle file
1766 #-> sub CPAN::Shell::expandany ;
1769 CPAN->debug("s[$s]") if $CPAN::DEBUG;
1770 if ($s =~ m|/|) { # looks like a file
1771 $s = CPAN::Distribution->normalize($s);
1772 return $CPAN::META->instance('CPAN::Distribution',$s);
1773 # Distributions spring into existence, not expand
1774 } elsif ($s =~ m|^Bundle::|) {
1775 $self->local_bundles; # scanning so late for bundles seems
1776 # both attractive and crumpy: always
1777 # current state but easy to forget
1779 return $self->expand('Bundle',$s);
1781 return $self->expand('Module',$s)
1782 if $CPAN::META->exists('CPAN::Module',$s);
1787 #-> sub CPAN::Shell::expand ;
1790 my($type,@args) = @_;
1792 CPAN->debug("type[$type]args[@args]") if $CPAN::DEBUG;
1794 my($regex,$command);
1795 if ($arg =~ m|^/(.*)/$|) {
1797 } elsif ($arg =~ m/=/) {
1800 my $class = "CPAN::$type";
1802 CPAN->debug(sprintf "class[%s]regex[%s]command[%s]",
1804 defined $regex ? $regex : "UNDEFINED",
1805 $command || "UNDEFINED",
1807 if (defined $regex) {
1811 $CPAN::META->all_objects($class)
1814 # BUG, we got an empty object somewhere
1815 require Data::Dumper;
1816 CPAN->debug(sprintf(
1817 "Bug in CPAN: Empty id on obj[%s][%s]",
1819 Data::Dumper::Dumper($obj)
1824 if $obj->id =~ /$regex/i
1828 $] < 5.00303 ### provide sort of
1829 ### compatibility with 5.003
1834 $obj->name =~ /$regex/i
1837 } elsif ($command) {
1838 die "equal sign in command disabled (immature interface), ".
1840 ! \$CPAN::Shell::ADVANCED_QUERY=1
1841 to enable it. But please note, this is HIGHLY EXPERIMENTAL code
1842 that may go away anytime.\n"
1843 unless $ADVANCED_QUERY;
1844 my($method,$criterion) = $arg =~ /(.+?)=(.+)/;
1845 my($matchcrit) = $criterion =~ m/^~(.+)/;
1849 $CPAN::META->all_objects($class)
1851 my $lhs = $self->$method() or next; # () for 5.00503
1853 push @m, $self if $lhs =~ m/$matchcrit/;
1855 push @m, $self if $lhs eq $criterion;
1860 if ( $type eq 'Bundle' ) {
1861 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
1862 } elsif ($type eq "Distribution") {
1863 $xarg = CPAN::Distribution->normalize($arg);
1865 if ($CPAN::META->exists($class,$xarg)) {
1866 $obj = $CPAN::META->instance($class,$xarg);
1867 } elsif ($CPAN::META->exists($class,$arg)) {
1868 $obj = $CPAN::META->instance($class,$arg);
1875 return wantarray ? @m : $m[0];
1878 #-> sub CPAN::Shell::format_result ;
1881 my($type,@args) = @_;
1882 @args = '/./' unless @args;
1883 my(@result) = $self->expand($type,@args);
1884 my $result = @result == 1 ?
1885 $result[0]->as_string :
1887 "No objects of type $type found for argument @args\n" :
1889 (map {$_->as_glimpse} @result),
1890 scalar @result, " items found\n",
1895 # The only reason for this method is currently to have a reliable
1896 # debugging utility that reveals which output is going through which
1897 # channel. No, I don't like the colors ;-)
1899 #-> sub CPAN::Shell::print_ornameted ;
1900 sub print_ornamented {
1901 my($self,$what,$ornament) = @_;
1903 return unless defined $what;
1905 if ($CPAN::Config->{term_is_latin}){
1908 =~ s{([\xC0-\xDF])([\x80-\xBF])}{chr(ord($1)<<6&0xC0|ord($2)&0x3F)}eg; #};
1910 if ($PRINT_ORNAMENTING) {
1911 unless (defined &color) {
1912 if ($CPAN::META->has_inst("Term::ANSIColor")) {
1913 import Term::ANSIColor "color";
1915 *color = sub { return "" };
1919 for $line (split /\n/, $what) {
1920 $longest = length($line) if length($line) > $longest;
1922 my $sprintf = "%-" . $longest . "s";
1924 $what =~ s/(.*\n?)//m;
1927 my($nl) = chomp $line ? "\n" : "";
1928 # print "line[$line]ornament[$ornament]sprintf[$sprintf]\n";
1929 print color($ornament), sprintf($sprintf,$line), color("reset"), $nl;
1937 my($self,$what) = @_;
1939 $self->print_ornamented($what, 'bold blue on_yellow');
1943 my($self,$what) = @_;
1944 $self->myprint($what);
1949 my($self,$what) = @_;
1950 $self->print_ornamented($what, 'bold red on_yellow');
1954 my($self,$what) = @_;
1955 $self->print_ornamented($what, 'bold red on_white');
1956 Carp::confess "died";
1960 my($self,$what) = @_;
1961 $self->print_ornamented($what, 'bold red on_white');
1966 return if -t STDOUT;
1967 my $odef = select STDERR;
1974 #-> sub CPAN::Shell::rematein ;
1975 # RE-adme||MA-ke||TE-st||IN-stall
1978 my($meth,@some) = @_;
1980 if ($meth eq 'force') {
1982 $meth = shift @some;
1985 CPAN->debug("pragma[$pragma]meth[$meth] some[@some]") if $CPAN::DEBUG;
1987 # Here is the place to set "test_count" on all involved parties to
1988 # 0. We then can pass this counter on to the involved
1989 # distributions and those can refuse to test if test_count > X. In
1990 # the first stab at it we could use a 1 for "X".
1992 # But when do I reset the distributions to start with 0 again?
1993 # Jost suggested to have a random or cycling interaction ID that
1994 # we pass through. But the ID is something that is just left lying
1995 # around in addition to the counter, so I'd prefer to set the
1996 # counter to 0 now, and repeat at the end of the loop. But what
1997 # about dependencies? They appear later and are not reset, they
1998 # enter the queue but not its copy. How do they get a sensible
2001 # construct the queue
2003 foreach $s (@some) {
2006 CPAN->debug("s is an object[$s]") if $CPAN::DEBUG;
2008 } elsif ($s =~ m|^/|) { # looks like a regexp
2009 $CPAN::Frontend->mywarn("Sorry, $meth with a regular expression is ".
2014 CPAN->debug("calling expandany [$s]") if $CPAN::DEBUG;
2015 $obj = CPAN::Shell->expandany($s);
2018 $obj->color_cmd_tmps(0,1);
2019 CPAN::Queue->new($obj->id);
2021 } elsif ($CPAN::META->exists('CPAN::Author',$s)) {
2022 $obj = $CPAN::META->instance('CPAN::Author',$s);
2023 if ($meth eq "dump") {
2026 $CPAN::Frontend->myprint(
2028 "Don't be silly, you can't $meth ",
2036 ->myprint(qq{Warning: Cannot $meth $s, }.
2037 qq{don\'t know what it is.
2042 to find objects with matching identifiers.
2048 # queuerunner (please be warned: when I started to change the
2049 # queue to hold objects instead of names, I made one or two
2050 # mistakes and never found which. I reverted back instead)
2051 while ($s = CPAN::Queue->first) {
2054 $obj = $s; # I do not believe, we would survive if this happened
2056 $obj = CPAN::Shell->expandany($s);
2060 ($] < 5.00303 || $obj->can($pragma))){
2061 ### compatibility with 5.003
2062 $obj->$pragma($meth); # the pragma "force" in
2063 # "CPAN::Distribution" must know
2064 # what we are intending
2066 if ($]>=5.00303 && $obj->can('called_for')) {
2067 $obj->called_for($s);
2070 qq{pragma[$pragma]meth[$meth]obj[$obj]as_string\[}.
2076 CPAN::Queue->delete($s);
2078 CPAN->debug("failed");
2082 CPAN::Queue->delete_first($s);
2084 for my $obj (@qcopy) {
2085 $obj->color_cmd_tmps(0,0);
2089 #-> sub CPAN::Shell::dump ;
2090 sub dump { shift->rematein('dump',@_); }
2091 #-> sub CPAN::Shell::force ;
2092 sub force { shift->rematein('force',@_); }
2093 #-> sub CPAN::Shell::get ;
2094 sub get { shift->rematein('get',@_); }
2095 #-> sub CPAN::Shell::readme ;
2096 sub readme { shift->rematein('readme',@_); }
2097 #-> sub CPAN::Shell::make ;
2098 sub make { shift->rematein('make',@_); }
2099 #-> sub CPAN::Shell::test ;
2100 sub test { shift->rematein('test',@_); }
2101 #-> sub CPAN::Shell::install ;
2102 sub install { shift->rematein('install',@_); }
2103 #-> sub CPAN::Shell::clean ;
2104 sub clean { shift->rematein('clean',@_); }
2105 #-> sub CPAN::Shell::look ;
2106 sub look { shift->rematein('look',@_); }
2107 #-> sub CPAN::Shell::cvs_import ;
2108 sub cvs_import { shift->rematein('cvs_import',@_); }
2110 package CPAN::LWP::UserAgent;
2113 return if $SETUPDONE;
2114 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2115 require LWP::UserAgent;
2116 @ISA = qw(Exporter LWP::UserAgent);
2119 $CPAN::Frontend->mywarn("LWP::UserAgent not available\n");
2123 sub get_basic_credentials {
2124 my($self, $realm, $uri, $proxy) = @_;
2125 return unless $proxy;
2126 if ($USER && $PASSWD) {
2127 } elsif (defined $CPAN::Config->{proxy_user} &&
2128 defined $CPAN::Config->{proxy_pass}) {
2129 $USER = $CPAN::Config->{proxy_user};
2130 $PASSWD = $CPAN::Config->{proxy_pass};
2132 require ExtUtils::MakeMaker;
2133 ExtUtils::MakeMaker->import(qw(prompt));
2134 $USER = prompt("Proxy authentication needed!
2135 (Note: to permanently configure username and password run
2136 o conf proxy_user your_username
2137 o conf proxy_pass your_password
2139 if ($CPAN::META->has_inst("Term::ReadKey")) {
2140 Term::ReadKey::ReadMode("noecho");
2142 $CPAN::Frontend->mywarn("Warning: Term::ReadKey seems not to be available, your password will be echoed to the terminal!\n");
2144 $PASSWD = prompt("Password:");
2145 if ($CPAN::META->has_inst("Term::ReadKey")) {
2146 Term::ReadKey::ReadMode("restore");
2148 $CPAN::Frontend->myprint("\n\n");
2150 return($USER,$PASSWD);
2154 my($self,$url,$aslocal) = @_;
2155 my $result = $self->SUPER::mirror($url,$aslocal);
2156 if ($result->code == 407) {
2159 $result = $self->SUPER::mirror($url,$aslocal);
2166 #-> sub CPAN::FTP::ftp_get ;
2168 my($class,$host,$dir,$file,$target) = @_;
2170 qq[Going to fetch file [$file] from dir [$dir]
2171 on host [$host] as local [$target]\n]
2173 my $ftp = Net::FTP->new($host);
2174 return 0 unless defined $ftp;
2175 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
2176 $class->debug(qq[Going to login("anonymous","$Config::Config{cf_email}")]);
2177 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
2178 warn "Couldn't login on $host";
2181 unless ( $ftp->cwd($dir) ){
2182 warn "Couldn't cwd $dir";
2186 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
2187 unless ( $ftp->get($file,$target) ){
2188 warn "Couldn't fetch $file from $host\n";
2191 $ftp->quit; # it's ok if this fails
2195 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
2197 # > *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
2198 # > --- /tmp/cp Wed Sep 24 13:26:40 1997
2200 # > *** 1562,1567 ****
2201 # > --- 1562,1580 ----
2202 # > return 1 if substr($url,0,4) eq "file";
2203 # > return 1 unless $url =~ m|://([^/]+)|;
2205 # > + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
2207 # > + $proxy =~ m|://([^/:]+)|;
2209 # > + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
2210 # > + if ($noproxy) {
2211 # > + if ($host !~ /$noproxy$/) {
2212 # > + $host = $proxy;
2215 # > + $host = $proxy;
2218 # > require Net::Ping;
2219 # > return 1 unless $Net::Ping::VERSION >= 2;
2223 #-> sub CPAN::FTP::localize ;
2225 my($self,$file,$aslocal,$force) = @_;
2227 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
2228 unless defined $aslocal;
2229 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
2232 if ($^O eq 'MacOS') {
2233 # Comment by AK on 2000-09-03: Uniq short filenames would be
2234 # available in CHECKSUMS file
2235 my($name, $path) = File::Basename::fileparse($aslocal, '');
2236 if (length($name) > 31) {
2247 my $size = 31 - length($suf);
2248 while (length($name) > $size) {
2252 $aslocal = File::Spec->catfile($path, $name);
2256 return $aslocal if -f $aslocal && -r _ && !($force & 1);
2259 rename $aslocal, "$aslocal.bak";
2263 my($aslocal_dir) = File::Basename::dirname($aslocal);
2264 File::Path::mkpath($aslocal_dir);
2265 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
2266 qq{directory "$aslocal_dir".
2267 I\'ll continue, but if you encounter problems, they may be due
2268 to insufficient permissions.\n}) unless -w $aslocal_dir;
2270 # Inheritance is not easier to manage than a few if/else branches
2271 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2273 CPAN::LWP::UserAgent->config;
2274 eval {$Ua = CPAN::LWP::UserAgent->new;}; # Why is has_usable still not fit enough?
2276 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@")
2280 $Ua->proxy('ftp', $var)
2281 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
2282 $Ua->proxy('http', $var)
2283 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
2286 # >>>>> On Wed, 13 Dec 2000 09:21:34 -0500, "Robison, Jonathon (J.M.)" <jrobiso2@visteon.com> said:
2288 # > I note that although CPAN.pm can use proxies, it doesn't seem equipped to
2289 # > use ones that require basic autorization.
2291 # > Example of when I use it manually in my own stuff:
2293 # > $ua->proxy(['http','ftp'], http://my.proxy.server:83');
2294 # > $req->proxy_authorization_basic("username","password");
2295 # > $res = $ua->request($req);
2299 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
2303 $ENV{ftp_proxy} = $CPAN::Config->{ftp_proxy} if $CPAN::Config->{ftp_proxy};
2304 $ENV{http_proxy} = $CPAN::Config->{http_proxy}
2305 if $CPAN::Config->{http_proxy};
2306 $ENV{no_proxy} = $CPAN::Config->{no_proxy} if $CPAN::Config->{no_proxy};
2308 # Try the list of urls for each single object. We keep a record
2309 # where we did get a file from
2310 my(@reordered,$last);
2311 $CPAN::Config->{urllist} ||= [];
2312 unless (ref $CPAN::Config->{urllist} eq 'ARRAY') {
2313 warn "Malformed urllist; ignoring. Configuration file corrupt?\n";
2315 $last = $#{$CPAN::Config->{urllist}};
2316 if ($force & 2) { # local cpans probably out of date, don't reorder
2317 @reordered = (0..$last);
2321 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
2323 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
2334 @levels = ($Themethod, grep {$_ ne $Themethod} qw/easy hard hardest/);
2336 @levels = qw/easy hard hardest/;
2338 @levels = qw/easy/ if $^O eq 'MacOS';
2340 for $levelno (0..$#levels) {
2341 my $level = $levels[$levelno];
2342 my $method = "host$level";
2343 my @host_seq = $level eq "easy" ?
2344 @reordered : 0..$last; # reordered has CDROM up front
2345 @host_seq = (0) unless @host_seq;
2346 my $ret = $self->$method(\@host_seq,$file,$aslocal);
2348 $Themethod = $level;
2350 # utime $now, $now, $aslocal; # too bad, if we do that, we
2351 # might alter a local mirror
2352 $self->debug("level[$level]") if $CPAN::DEBUG;
2356 last if $CPAN::Signal; # need to cleanup
2359 unless ($CPAN::Signal) {
2362 qq{Please check, if the URLs I found in your configuration file \(}.
2363 join(", ", @{$CPAN::Config->{urllist}}).
2364 qq{\) are valid. The urllist can be edited.},
2365 qq{E.g. with 'o conf urllist push ftp://myurl/'};
2366 $CPAN::Frontend->myprint(Text::Wrap::wrap("","",@mess). "\n\n");
2368 $CPAN::Frontend->myprint("Could not fetch $file\n");
2371 rename "$aslocal.bak", $aslocal;
2372 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
2373 $self->ls($aslocal));
2380 my($self,$host_seq,$file,$aslocal) = @_;
2382 HOSTEASY: for $i (@$host_seq) {
2383 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2384 $url .= "/" unless substr($url,-1) eq "/";
2386 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
2387 if ($url =~ /^file:/) {
2389 if ($CPAN::META->has_inst('URI::URL')) {
2390 my $u = URI::URL->new($url);
2392 } else { # works only on Unix, is poorly constructed, but
2393 # hopefully better than nothing.
2394 # RFC 1738 says fileurl BNF is
2395 # fileurl = "file://" [ host | "localhost" ] "/" fpath
2396 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
2398 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
2399 $l =~ s|^file:||; # assume they
2402 $l =~ s|^/||s unless -f $l; # e.g. /P:
2403 $self->debug("without URI::URL we try local file $l") if $CPAN::DEBUG;
2405 if ( -f $l && -r _) {
2409 # Maybe mirror has compressed it?
2411 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
2412 CPAN::Tarzip->gunzip("$l.gz", $aslocal);
2419 if ($CPAN::META->has_usable('LWP')) {
2420 $CPAN::Frontend->myprint("Fetching with LWP:
2424 CPAN::LWP::UserAgent->config;
2425 eval { $Ua = CPAN::LWP::UserAgent->new; };
2427 $CPAN::Frontend->mywarn("CPAN::LWP::UserAgent->new dies with $@");
2430 my $res = $Ua->mirror($url, $aslocal);
2431 if ($res->is_success) {
2434 utime $now, $now, $aslocal; # download time is more
2435 # important than upload time
2437 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2438 my $gzurl = "$url.gz";
2439 $CPAN::Frontend->myprint("Fetching with LWP:
2442 $res = $Ua->mirror($gzurl, "$aslocal.gz");
2443 if ($res->is_success &&
2444 CPAN::Tarzip->gunzip("$aslocal.gz",$aslocal)
2450 $CPAN::Frontend->myprint(sprintf(
2451 "LWP failed with code[%s] message[%s]\n",
2455 # Alan Burlison informed me that in firewall environments
2456 # Net::FTP can still succeed where LWP fails. So we do not
2457 # skip Net::FTP anymore when LWP is available.
2460 $CPAN::Frontend->myprint("LWP not available\n");
2462 return if $CPAN::Signal;
2463 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2464 # that's the nice and easy way thanks to Graham
2465 my($host,$dir,$getfile) = ($1,$2,$3);
2466 if ($CPAN::META->has_usable('Net::FTP')) {
2468 $CPAN::Frontend->myprint("Fetching with Net::FTP:
2471 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
2472 "aslocal[$aslocal]") if $CPAN::DEBUG;
2473 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
2477 if ($aslocal !~ /\.gz(?!\n)\Z/) {
2478 my $gz = "$aslocal.gz";
2479 $CPAN::Frontend->myprint("Fetching with Net::FTP
2482 if (CPAN::FTP->ftp_get($host,
2486 CPAN::Tarzip->gunzip($gz,$aslocal)
2495 return if $CPAN::Signal;
2500 my($self,$host_seq,$file,$aslocal) = @_;
2502 # Came back if Net::FTP couldn't establish connection (or
2503 # failed otherwise) Maybe they are behind a firewall, but they
2504 # gave us a socksified (or other) ftp program...
2507 my($devnull) = $CPAN::Config->{devnull} || "";
2509 my($aslocal_dir) = File::Basename::dirname($aslocal);
2510 File::Path::mkpath($aslocal_dir);
2511 HOSTHARD: for $i (@$host_seq) {
2512 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2513 $url .= "/" unless substr($url,-1) eq "/";
2515 my($proto,$host,$dir,$getfile);
2517 # Courtesy Mark Conty mark_conty@cargill.com change from
2518 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2520 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
2521 # proto not yet used
2522 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
2524 next HOSTHARD; # who said, we could ftp anything except ftp?
2526 next HOSTHARD if $proto eq "file"; # file URLs would have had
2527 # success above. Likely a bogus URL
2529 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
2531 for $f ('lynx','ncftpget','ncftp','wget') {
2532 next unless exists $CPAN::Config->{$f};
2533 $funkyftp = $CPAN::Config->{$f};
2534 next unless defined $funkyftp;
2535 next if $funkyftp =~ /^\s*$/;
2536 my($asl_ungz, $asl_gz);
2537 ($asl_ungz = $aslocal) =~ s/\.gz//;
2538 $asl_gz = "$asl_ungz.gz";
2539 my($src_switch) = "";
2541 $src_switch = " -source";
2542 } elsif ($f eq "ncftp"){
2543 $src_switch = " -c";
2544 } elsif ($f eq "wget"){
2545 $src_switch = " -O -";
2548 my($stdout_redir) = " > $asl_ungz";
2549 if ($f eq "ncftpget"){
2550 $chdir = "cd $aslocal_dir && ";
2553 $CPAN::Frontend->myprint(
2555 Trying with "$funkyftp$src_switch" to get
2559 "$chdir$funkyftp$src_switch \"$url\" $devnull$stdout_redir";
2560 $self->debug("system[$system]") if $CPAN::DEBUG;
2562 if (($wstatus = system($system)) == 0
2565 -s $asl_ungz # lynx returns 0 when it fails somewhere
2571 } elsif ($asl_ungz ne $aslocal) {
2572 # test gzip integrity
2573 if (CPAN::Tarzip->gtest($asl_ungz)) {
2574 # e.g. foo.tar is gzipped --> foo.tar.gz
2575 rename $asl_ungz, $aslocal;
2577 CPAN::Tarzip->gzip($asl_ungz,$asl_gz);
2582 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2584 -f $asl_ungz && -s _ == 0;
2585 my $gz = "$aslocal.gz";
2586 my $gzurl = "$url.gz";
2587 $CPAN::Frontend->myprint(
2589 Trying with "$funkyftp$src_switch" to get
2592 my($system) = "$funkyftp$src_switch \"$url.gz\" $devnull > $asl_gz";
2593 $self->debug("system[$system]") if $CPAN::DEBUG;
2595 if (($wstatus = system($system)) == 0
2599 # test gzip integrity
2600 if (CPAN::Tarzip->gtest($asl_gz)) {
2601 CPAN::Tarzip->gunzip($asl_gz,$aslocal);
2603 # somebody uncompressed file for us?
2604 rename $asl_ungz, $aslocal;
2609 unlink $asl_gz if -f $asl_gz;
2612 my $estatus = $wstatus >> 8;
2613 my $size = -f $aslocal ?
2614 ", left\n$aslocal with size ".-s _ :
2615 "\nWarning: expected file [$aslocal] doesn't exist";
2616 $CPAN::Frontend->myprint(qq{
2617 System call "$system"
2618 returned status $estatus (wstat $wstatus)$size
2621 return if $CPAN::Signal;
2622 } # lynx,ncftpget,ncftp
2627 my($self,$host_seq,$file,$aslocal) = @_;
2630 my($aslocal_dir) = File::Basename::dirname($aslocal);
2631 File::Path::mkpath($aslocal_dir);
2632 HOSTHARDEST: for $i (@$host_seq) {
2633 unless (length $CPAN::Config->{'ftp'}) {
2634 $CPAN::Frontend->myprint("No external ftp command available\n\n");
2637 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2638 $url .= "/" unless substr($url,-1) eq "/";
2640 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
2641 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2644 my($host,$dir,$getfile) = ($1,$2,$3);
2646 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
2647 $ctime,$blksize,$blocks) = stat($aslocal);
2648 $timestamp = $mtime ||= 0;
2649 my($netrc) = CPAN::FTP::netrc->new;
2650 my($netrcfile) = $netrc->netrc;
2651 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
2652 my $targetfile = File::Basename::basename($aslocal);
2658 map("cd $_", split "/", $dir), # RFC 1738
2660 "get $getfile $targetfile",
2664 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
2665 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
2666 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
2668 $netrc->contains($host))) if $CPAN::DEBUG;
2669 if ($netrc->protected) {
2670 $CPAN::Frontend->myprint(qq{
2671 Trying with external ftp to get
2673 As this requires some features that are not thoroughly tested, we\'re
2674 not sure, that we get it right....
2678 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose $host",
2680 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2681 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2683 if ($mtime > $timestamp) {
2684 $CPAN::Frontend->myprint("GOT $aslocal\n");
2688 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
2690 return if $CPAN::Signal;
2692 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
2693 qq{correctly protected.\n});
2696 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
2697 nor does it have a default entry\n");
2700 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
2701 # then and login manually to host, using e-mail as
2703 $CPAN::Frontend->myprint(qq{Issuing "$CPAN::Config->{'ftp'}$verbose -n"\n});
2707 "user anonymous $Config::Config{'cf_email'}"
2709 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose -n", @dialog);
2710 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2711 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2713 if ($mtime > $timestamp) {
2714 $CPAN::Frontend->myprint("GOT $aslocal\n");
2718 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
2720 return if $CPAN::Signal;
2721 $CPAN::Frontend->myprint("Can't access URL $url.\n\n");
2727 my($self,$command,@dialog) = @_;
2728 my $fh = FileHandle->new;
2729 $fh->open("|$command") or die "Couldn't open ftp: $!";
2730 foreach (@dialog) { $fh->print("$_\n") }
2731 $fh->close; # Wait for process to complete
2733 my $estatus = $wstatus >> 8;
2734 $CPAN::Frontend->myprint(qq{
2735 Subprocess "|$command"
2736 returned status $estatus (wstat $wstatus)
2740 # find2perl needs modularization, too, all the following is stolen
2744 my($self,$name) = @_;
2745 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
2746 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
2748 my($perms,%user,%group);
2752 $blocks = int(($blocks + 1) / 2);
2755 $blocks = int(($sizemm + 1023) / 1024);
2758 if (-f _) { $perms = '-'; }
2759 elsif (-d _) { $perms = 'd'; }
2760 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
2761 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
2762 elsif (-p _) { $perms = 'p'; }
2763 elsif (-S _) { $perms = 's'; }
2764 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
2766 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
2767 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
2768 my $tmpmode = $mode;
2769 my $tmp = $rwx[$tmpmode & 7];
2771 $tmp = $rwx[$tmpmode & 7] . $tmp;
2773 $tmp = $rwx[$tmpmode & 7] . $tmp;
2774 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
2775 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
2776 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
2779 my $user = $user{$uid} || $uid; # too lazy to implement lookup
2780 my $group = $group{$gid} || $gid;
2782 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
2784 my($moname) = $moname[$mon];
2785 if (-M _ > 365.25 / 2) {
2786 $timeyear = $year + 1900;
2789 $timeyear = sprintf("%02d:%02d", $hour, $min);
2792 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
2806 package CPAN::FTP::netrc;
2810 my $file = File::Spec->catfile($ENV{HOME},".netrc");
2812 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2813 $atime,$mtime,$ctime,$blksize,$blocks)
2818 my($fh,@machines,$hasdefault);
2820 $fh = FileHandle->new or die "Could not create a filehandle";
2822 if($fh->open($file)){
2823 $protected = ($mode & 077) == 0;
2825 NETRC: while (<$fh>) {
2826 my(@tokens) = split " ", $_;
2827 TOKEN: while (@tokens) {
2828 my($t) = shift @tokens;
2829 if ($t eq "default"){
2833 last TOKEN if $t eq "macdef";
2834 if ($t eq "machine") {
2835 push @machines, shift @tokens;
2840 $file = $hasdefault = $protected = "";
2844 'mach' => [@machines],
2846 'hasdefault' => $hasdefault,
2847 'protected' => $protected,
2851 # CPAN::FTP::hasdefault;
2852 sub hasdefault { shift->{'hasdefault'} }
2853 sub netrc { shift->{'netrc'} }
2854 sub protected { shift->{'protected'} }
2856 my($self,$mach) = @_;
2857 for ( @{$self->{'mach'}} ) {
2858 return 1 if $_ eq $mach;
2863 package CPAN::Complete;
2866 my($text, $line, $start, $end) = @_;
2867 my(@perlret) = cpl($text, $line, $start);
2868 # find longest common match. Can anybody show me how to peruse
2869 # T::R::Gnu to have this done automatically? Seems expensive.
2870 return () unless @perlret;
2871 my($newtext) = $text;
2872 for (my $i = length($text)+1;;$i++) {
2873 last unless length($perlret[0]) && length($perlret[0]) >= $i;
2874 my $try = substr($perlret[0],0,$i);
2875 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
2876 # warn "try[$try]tries[@tries]";
2877 if (@tries == @perlret) {
2883 ($newtext,@perlret);
2886 #-> sub CPAN::Complete::cpl ;
2888 my($word,$line,$pos) = @_;
2892 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2894 if ($line =~ s/^(force\s*)//) {
2899 @return = grep /^$word/, @CPAN::Complete::COMMANDS;
2900 } elsif ( $line !~ /^[\!abcdghimorutl]/ ) {
2902 } elsif ($line =~ /^(a|ls)\s/) {
2903 @return = cplx('CPAN::Author',uc($word));
2904 } elsif ($line =~ /^b\s/) {
2905 CPAN::Shell->local_bundles;
2906 @return = cplx('CPAN::Bundle',$word);
2907 } elsif ($line =~ /^d\s/) {
2908 @return = cplx('CPAN::Distribution',$word);
2909 } elsif ($line =~ m/^(
2910 [mru]|make|clean|dump|get|test|install|readme|look|cvs_import
2912 if ($word =~ /^Bundle::/) {
2913 CPAN::Shell->local_bundles;
2915 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
2916 } elsif ($line =~ /^i\s/) {
2917 @return = cpl_any($word);
2918 } elsif ($line =~ /^reload\s/) {
2919 @return = cpl_reload($word,$line,$pos);
2920 } elsif ($line =~ /^o\s/) {
2921 @return = cpl_option($word,$line,$pos);
2922 } elsif ($line =~ m/^\S+\s/ ) {
2923 # fallback for future commands and what we have forgotten above
2924 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
2931 #-> sub CPAN::Complete::cplx ;
2933 my($class, $word) = @_;
2934 # I believed for many years that this was sorted, today I
2935 # realized, it wasn't sorted anymore. Now (rev 1.301 / v 1.55) I
2936 # make it sorted again. Maybe sort was dropped when GNU-readline
2937 # support came in? The RCS file is difficult to read on that:-(
2938 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
2941 #-> sub CPAN::Complete::cpl_any ;
2945 cplx('CPAN::Author',$word),
2946 cplx('CPAN::Bundle',$word),
2947 cplx('CPAN::Distribution',$word),
2948 cplx('CPAN::Module',$word),
2952 #-> sub CPAN::Complete::cpl_reload ;
2954 my($word,$line,$pos) = @_;
2956 my(@words) = split " ", $line;
2957 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2958 my(@ok) = qw(cpan index);
2959 return @ok if @words == 1;
2960 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
2963 #-> sub CPAN::Complete::cpl_option ;
2965 my($word,$line,$pos) = @_;
2967 my(@words) = split " ", $line;
2968 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2969 my(@ok) = qw(conf debug);
2970 return @ok if @words == 1;
2971 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
2973 } elsif ($words[1] eq 'index') {
2975 } elsif ($words[1] eq 'conf') {
2976 return CPAN::Config::cpl(@_);
2977 } elsif ($words[1] eq 'debug') {
2978 return sort grep /^\Q$word\E/, sort keys %CPAN::DEBUG, 'all';
2982 package CPAN::Index;
2984 #-> sub CPAN::Index::force_reload ;
2987 $CPAN::Index::LAST_TIME = 0;
2991 #-> sub CPAN::Index::reload ;
2993 my($cl,$force) = @_;
2996 # XXX check if a newer one is available. (We currently read it
2997 # from time to time)
2998 for ($CPAN::Config->{index_expire}) {
2999 $_ = 0.001 unless $_ && $_ > 0.001;
3001 unless (1 || $CPAN::Have_warned->{readmetadatacache}++) {
3002 # debug here when CPAN doesn't seem to read the Metadata
3004 Carp::cluck("META-PROTOCOL[$CPAN::META->{PROTOCOL}]");
3006 unless ($CPAN::META->{PROTOCOL}) {
3007 $cl->read_metadata_cache;
3008 $CPAN::META->{PROTOCOL} ||= "1.0";
3010 if ( $CPAN::META->{PROTOCOL} < PROTOCOL ) {
3011 # warn "Setting last_time to 0";
3012 $LAST_TIME = 0; # No warning necessary
3014 return if $LAST_TIME + $CPAN::Config->{index_expire}*86400 > $time
3017 # IFF we are developing, it helps to wipe out the memory
3018 # between reloads, otherwise it is not what a user expects.
3019 undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
3020 $CPAN::META = CPAN->new;
3024 local $LAST_TIME = $time;
3025 local $CPAN::META->{PROTOCOL} = PROTOCOL;
3027 my $needshort = $^O eq "dos";
3029 $cl->rd_authindex($cl
3031 "authors/01mailrc.txt.gz",
3033 File::Spec->catfile('authors', '01mailrc.gz') :
3034 File::Spec->catfile('authors', '01mailrc.txt.gz'),
3037 $debug = "timing reading 01[".($t2 - $time)."]";
3039 return if $CPAN::Signal; # this is sometimes lengthy
3040 $cl->rd_modpacks($cl
3042 "modules/02packages.details.txt.gz",
3044 File::Spec->catfile('modules', '02packag.gz') :
3045 File::Spec->catfile('modules', '02packages.details.txt.gz'),
3048 $debug .= "02[".($t2 - $time)."]";
3050 return if $CPAN::Signal; # this is sometimes lengthy
3053 "modules/03modlist.data.gz",
3055 File::Spec->catfile('modules', '03mlist.gz') :
3056 File::Spec->catfile('modules', '03modlist.data.gz'),
3058 $cl->write_metadata_cache;
3060 $debug .= "03[".($t2 - $time)."]";
3062 CPAN->debug($debug) if $CPAN::DEBUG;
3065 $CPAN::META->{PROTOCOL} = PROTOCOL;
3068 #-> sub CPAN::Index::reload_x ;
3070 my($cl,$wanted,$localname,$force) = @_;
3071 $force |= 2; # means we're dealing with an index here
3072 CPAN::Config->load; # we should guarantee loading wherever we rely
3074 $localname ||= $wanted;
3075 my $abs_wanted = File::Spec->catfile($CPAN::Config->{'keep_source_where'},
3079 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
3082 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
3083 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
3084 qq{day$s. I\'ll use that.});
3087 $force |= 1; # means we're quite serious about it.
3089 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
3092 #-> sub CPAN::Index::rd_authindex ;
3094 my($cl, $index_target) = @_;
3096 return unless defined $index_target;
3097 $CPAN::Frontend->myprint("Going to read $index_target\n");
3099 tie *FH, CPAN::Tarzip, $index_target;
3101 push @lines, split /\012/ while <FH>;
3103 my($userid,$fullname,$email) =
3104 m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
3105 next unless $userid && $fullname && $email;
3107 # instantiate an author object
3108 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
3109 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
3110 return if $CPAN::Signal;
3115 my($self,$dist) = @_;
3116 $dist = $self->{'id'} unless defined $dist;
3117 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
3121 #-> sub CPAN::Index::rd_modpacks ;
3123 my($self, $index_target) = @_;
3125 return unless defined $index_target;
3126 $CPAN::Frontend->myprint("Going to read $index_target\n");
3127 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3129 while ($_ = $fh->READLINE) {
3131 my @ls = map {"$_\n"} split /\n/, $_;
3132 unshift @ls, "\n" x length($1) if /^(\n+)/;
3136 my($line_count,$last_updated);
3138 my $shift = shift(@lines);
3139 last if $shift =~ /^\s*$/;
3140 $shift =~ /^Line-Count:\s+(\d+)/ and $line_count = $1;
3141 $shift =~ /^Last-Updated:\s+(.+)/ and $last_updated = $1;
3143 if (not defined $line_count) {
3145 warn qq{Warning: Your $index_target does not contain a Line-Count header.
3146 Please check the validity of the index file by comparing it to more
3147 than one CPAN mirror. I'll continue but problems seem likely to
3152 } elsif ($line_count != scalar @lines) {
3154 warn sprintf qq{Warning: Your %s
3155 contains a Line-Count header of %d but I see %d lines there. Please
3156 check the validity of the index file by comparing it to more than one
3157 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
3158 $index_target, $line_count, scalar(@lines);
3161 if (not defined $last_updated) {
3163 warn qq{Warning: Your $index_target does not contain a Last-Updated header.
3164 Please check the validity of the index file by comparing it to more
3165 than one CPAN mirror. I'll continue but problems seem likely to
3173 ->myprint(sprintf qq{ Database was generated on %s\n},
3175 $DATE_OF_02 = $last_updated;
3177 if ($CPAN::META->has_inst(HTTP::Date)) {
3179 my($age) = (time - HTTP::Date::str2time($last_updated))/3600/24;
3184 qq{Warning: This index file is %d days old.
3185 Please check the host you chose as your CPAN mirror for staleness.
3186 I'll continue but problems seem likely to happen.\a\n},
3191 $CPAN::Frontend->myprint(" HTTP::Date not available\n");
3196 # A necessity since we have metadata_cache: delete what isn't
3198 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
3199 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
3203 # before 1.56 we split into 3 and discarded the rest. From
3204 # 1.57 we assign remaining text to $comment thus allowing to
3205 # influence isa_perl
3206 my($mod,$version,$dist,$comment) = split " ", $_, 4;
3207 my($bundle,$id,$userid);
3209 if ($mod eq 'CPAN' &&
3211 CPAN::Queue->exists('Bundle::CPAN') ||
3212 CPAN::Queue->exists('CPAN')
3216 if ($version > $CPAN::VERSION){
3217 $CPAN::Frontend->myprint(qq{
3218 There's a new CPAN.pm version (v$version) available!
3219 [Current version is v$CPAN::VERSION]
3220 You might want to try
3221 install Bundle::CPAN
3223 without quitting the current session. It should be a seamless upgrade
3224 while we are running...
3227 $CPAN::Frontend->myprint(qq{\n});
3229 last if $CPAN::Signal;
3230 } elsif ($mod =~ /^Bundle::(.*)/) {
3235 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
3236 # Let's make it a module too, because bundles have so much
3237 # in common with modules.
3239 # Changed in 1.57_63: seems like memory bloat now without
3240 # any value, so commented out
3242 # $CPAN::META->instance('CPAN::Module',$mod);
3246 # instantiate a module object
3247 $id = $CPAN::META->instance('CPAN::Module',$mod);
3251 if ($id->cpan_file ne $dist){ # update only if file is
3252 # different. CPAN prohibits same
3253 # name with different version
3254 $userid = $self->userid($dist);
3256 'CPAN_USERID' => $userid,
3257 'CPAN_VERSION' => $version,
3258 'CPAN_FILE' => $dist,
3262 # instantiate a distribution object
3263 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
3264 # we do not need CONTAINSMODS unless we do something with
3265 # this dist, so we better produce it on demand.
3267 ## my $obj = $CPAN::META->instance(
3268 ## 'CPAN::Distribution' => $dist
3270 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
3272 $CPAN::META->instance(
3273 'CPAN::Distribution' => $dist
3275 'CPAN_USERID' => $userid,
3276 'CPAN_COMMENT' => $comment,
3280 for my $name ($mod,$dist) {
3281 CPAN->debug("exists name[$name]") if $CPAN::DEBUG;
3282 $exists{$name} = undef;
3285 return if $CPAN::Signal;
3289 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
3290 for my $o ($CPAN::META->all_objects($class)) {
3291 next if exists $exists{$o->{ID}};
3292 $CPAN::META->delete($class,$o->{ID});
3293 CPAN->debug("deleting ID[$o->{ID}] in class[$class]")
3300 #-> sub CPAN::Index::rd_modlist ;
3302 my($cl,$index_target) = @_;
3303 return unless defined $index_target;
3304 $CPAN::Frontend->myprint("Going to read $index_target\n");
3305 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3308 while ($_ = $fh->READLINE) {
3310 my @ls = map {"$_\n"} split /\n/, $_;
3311 unshift @ls, "\n" x length($1) if /^(\n+)/;
3315 my $shift = shift(@eval);
3316 if ($shift =~ /^Date:\s+(.*)/){
3317 return if $DATE_OF_03 eq $1;
3320 last if $shift =~ /^\s*$/;
3323 push @eval, q{CPAN::Modulelist->data;};
3325 my($comp) = Safe->new("CPAN::Safe1");
3326 my($eval) = join("", @eval);
3327 my $ret = $comp->reval($eval);
3328 Carp::confess($@) if $@;
3329 return if $CPAN::Signal;
3331 my $obj = $CPAN::META->instance("CPAN::Module",$_);
3332 delete $ret->{$_}{modid}; # not needed here, maybe elsewhere
3333 $obj->set(%{$ret->{$_}});
3334 return if $CPAN::Signal;
3338 #-> sub CPAN::Index::write_metadata_cache ;
3339 sub write_metadata_cache {
3341 return unless $CPAN::Config->{'cache_metadata'};
3342 return unless $CPAN::META->has_usable("Storable");
3344 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
3345 CPAN::Distribution)) {
3346 $cache->{$k} = $CPAN::META->{readonly}{$k}; # unsafe meta access, ok
3348 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3349 $cache->{last_time} = $LAST_TIME;
3350 $cache->{DATE_OF_02} = $DATE_OF_02;
3351 $cache->{PROTOCOL} = PROTOCOL;
3352 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
3353 eval { Storable::nstore($cache, $metadata_file) };
3354 $CPAN::Frontend->mywarn($@) if $@;
3357 #-> sub CPAN::Index::read_metadata_cache ;
3358 sub read_metadata_cache {
3360 return unless $CPAN::Config->{'cache_metadata'};
3361 return unless $CPAN::META->has_usable("Storable");
3362 my $metadata_file = File::Spec->catfile($CPAN::Config->{cpan_home},"Metadata");
3363 return unless -r $metadata_file and -f $metadata_file;
3364 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
3366 eval { $cache = Storable::retrieve($metadata_file) };
3367 $CPAN::Frontend->mywarn($@) if $@;
3368 if (!$cache || ref $cache ne 'HASH'){
3372 if (exists $cache->{PROTOCOL}) {
3373 if (PROTOCOL > $cache->{PROTOCOL}) {
3374 $CPAN::Frontend->mywarn(sprintf("Ignoring Metadata cache written ".
3375 "with protocol v%s, requiring v%s",
3382 $CPAN::Frontend->mywarn("Ignoring Metadata cache written ".
3383 "with protocol v1.0");
3388 while(my($class,$v) = each %$cache) {
3389 next unless $class =~ /^CPAN::/;
3390 $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok
3391 while (my($id,$ro) = each %$v) {
3392 $CPAN::META->{readwrite}{$class}{$id} ||=
3393 $class->new(ID=>$id, RO=>$ro);
3398 unless ($clcnt) { # sanity check
3399 $CPAN::Frontend->myprint("Warning: Found no data in $metadata_file\n");
3402 if ($idcnt < 1000) {
3403 $CPAN::Frontend->myprint("Warning: Found only $idcnt objects ".
3404 "in $metadata_file\n");
3407 $CPAN::META->{PROTOCOL} ||=
3408 $cache->{PROTOCOL}; # reading does not up or downgrade, but it
3409 # does initialize to some protocol
3410 $LAST_TIME = $cache->{last_time};
3411 $DATE_OF_02 = $cache->{DATE_OF_02};
3412 $CPAN::Frontend->myprint(" Database was generated on $DATE_OF_02\n")
3413 if defined $DATE_OF_02; # An old cache may not contain DATE_OF_02
3417 package CPAN::InfoObj;
3420 sub cpan_userid { shift->{RO}{CPAN_USERID} }
3421 sub id { shift->{ID}; }
3423 #-> sub CPAN::InfoObj::new ;
3425 my $this = bless {}, shift;
3430 # The set method may only be used by code that reads index data or
3431 # otherwise "objective" data from the outside world. All session
3432 # related material may do anything else with instance variables but
3433 # must not touch the hash under the RO attribute. The reason is that
3434 # the RO hash gets written to Metadata file and is thus persistent.
3436 #-> sub CPAN::InfoObj::set ;
3438 my($self,%att) = @_;
3439 my $class = ref $self;
3441 # This must be ||=, not ||, because only if we write an empty
3442 # reference, only then the set method will write into the readonly
3443 # area. But for Distributions that spring into existence, maybe
3444 # because of a typo, we do not like it that they are written into
3445 # the readonly area and made permanent (at least for a while) and
3446 # that is why we do not "allow" other places to call ->set.
3447 unless ($self->id) {
3448 CPAN->debug("Bug? Empty ID, rejecting");
3451 my $ro = $self->{RO} =
3452 $CPAN::META->{readonly}{$class}{$self->id} ||= {};
3454 while (my($k,$v) = each %att) {
3459 #-> sub CPAN::InfoObj::as_glimpse ;
3463 my $class = ref($self);
3464 $class =~ s/^CPAN:://;
3465 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
3469 #-> sub CPAN::InfoObj::as_string ;
3473 my $class = ref($self);
3474 $class =~ s/^CPAN:://;
3475 push @m, $class, " id = $self->{ID}\n";
3476 for (sort keys %{$self->{RO}}) {
3477 # next if m/^(ID|RO)$/;
3479 if ($_ eq "CPAN_USERID") {
3480 $extra .= " (".$self->author;
3481 my $email; # old perls!
3482 if ($email = $CPAN::META->instance("CPAN::Author",
3485 $extra .= " <$email>";
3487 $extra .= " <no email>";
3490 } elsif ($_ eq "FULLNAME") { # potential UTF-8 conversion
3491 push @m, sprintf " %-12s %s\n", $_, $self->fullname;
3494 next unless defined $self->{RO}{$_};
3495 push @m, sprintf " %-12s %s%s\n", $_, $self->{RO}{$_}, $extra;
3497 for (sort keys %$self) {
3498 next if m/^(ID|RO)$/;
3499 if (ref($self->{$_}) eq "ARRAY") {
3500 push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
3501 } elsif (ref($self->{$_}) eq "HASH") {
3505 join(" ",keys %{$self->{$_}}),
3508 push @m, sprintf " %-12s %s\n", $_, $self->{$_};
3514 #-> sub CPAN::InfoObj::author ;
3517 $CPAN::META->instance("CPAN::Author",$self->cpan_userid)->fullname;
3520 #-> sub CPAN::InfoObj::dump ;
3523 require Data::Dumper;
3524 print Data::Dumper::Dumper($self);
3527 package CPAN::Author;
3529 #-> sub CPAN::Author::id
3532 my $id = $self->{ID};
3533 $CPAN::Frontend->mydie("Illegal author id[$id]") unless $id =~ /^[A-Z]/;
3537 #-> sub CPAN::Author::as_glimpse ;
3541 my $class = ref($self);
3542 $class =~ s/^CPAN:://;
3543 push @m, sprintf(qq{%-15s %s ("%s" <%s>)\n},
3551 #-> sub CPAN::Author::fullname ;
3553 shift->{RO}{FULLNAME};
3557 #-> sub CPAN::Author::email ;
3558 sub email { shift->{RO}{EMAIL}; }
3560 #-> sub CPAN::Author::ls ;
3565 # adapted from CPAN::Distribution::verifyMD5 ;
3566 my(@csf); # chksumfile
3567 @csf = $self->id =~ /(.)(.)(.*)/;
3568 $csf[1] = join "", @csf[0,1];
3569 $csf[2] = join "", @csf[1,2];
3571 @dl = $self->dir_listing([$csf[0],"CHECKSUMS"], 0);
3572 unless (grep {$_->[2] eq $csf[1]} @dl) {
3573 $CPAN::Frontend->myprint("No files in the directory of $id\n");
3576 @dl = $self->dir_listing([@csf[0,1],"CHECKSUMS"], 0);
3577 unless (grep {$_->[2] eq $csf[2]} @dl) {
3578 $CPAN::Frontend->myprint("No files in the directory of $id\n");
3581 @dl = $self->dir_listing([@csf,"CHECKSUMS"], 1);
3582 $CPAN::Frontend->myprint(join "", map {
3583 sprintf("%8d %10s %s/%s\n", $_->[0], $_->[1], $id, $_->[2])
3584 } sort { $a->[2] cmp $b->[2] } @dl);
3587 # returns an array of arrays, the latter contain (size,mtime,filename)
3588 #-> sub CPAN::Author::dir_listing ;
3591 my $chksumfile = shift;
3592 my $recursive = shift;
3594 File::Spec->catfile($CPAN::Config->{keep_source_where},
3595 "authors", "id", @$chksumfile);
3597 # connect "force" argument with "index_expire".
3599 if (my @stat = stat $lc_want) {
3600 $force = $stat[9] + $CPAN::Config->{index_expire}*86400 <= time;
3602 my $lc_file = CPAN::FTP->localize("authors/id/@$chksumfile",
3605 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
3606 $chksumfile->[-1] .= ".gz";
3607 $lc_file = CPAN::FTP->localize("authors/id/@$chksumfile",
3610 $lc_file =~ s{\.gz(?!\n)\Z}{}; #};
3611 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
3617 # adapted from CPAN::Distribution::MD5_check_file ;
3618 my $fh = FileHandle->new;
3620 if (open $fh, $lc_file){
3623 $eval =~ s/\015?\012/\n/g;
3625 my($comp) = Safe->new();
3626 $cksum = $comp->reval($eval);
3628 rename $lc_file, "$lc_file.bad";
3629 Carp::confess($@) if $@;
3632 Carp::carp "Could not open $lc_file for reading";
3635 for $f (sort keys %$cksum) {
3636 if (exists $cksum->{$f}{isdir}) {
3638 my(@dir) = @$chksumfile;
3640 push @dir, $f, "CHECKSUMS";
3642 [$_->[0], $_->[1], "$f/$_->[2]"]
3643 } $self->dir_listing(\@dir,1);
3645 push @result, [ 0, "-", $f ];
3649 ($cksum->{$f}{"size"}||0),
3650 $cksum->{$f}{"mtime"}||"---",
3658 package CPAN::Distribution;
3661 sub cpan_comment { shift->{RO}{CPAN_COMMENT} }
3665 delete $self->{later};
3668 # CPAN::Distribution::normalize
3671 $s = $self->id unless defined $s;
3675 $s !~ m|[A-Z]/[A-Z-]{2}/[A-Z-]{2,}/|
3677 return $s if $s =~ m:^N/A|^Contact Author: ;
3678 $s =~ s|^(.)(.)([^/]*/)(.+)$|$1/$1$2/$1$2$3$4| or
3679 $CPAN::Frontend->mywarn("Strange distribution name [$s]");
3680 CPAN->debug("s[$s]") if $CPAN::DEBUG;
3685 #-> sub CPAN::Distribution::color_cmd_tmps ;
3686 sub color_cmd_tmps {
3688 my($depth) = shift || 0;
3689 my($color) = shift || 0;
3690 # a distribution needs to recurse into its prereq_pms
3692 return if exists $self->{incommandcolor}
3693 && $self->{incommandcolor}==$color;
3694 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
3695 "color_cmd_tmps depth[%s] self[%s] id[%s]",
3700 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
3701 my $prereq_pm = $self->prereq_pm;
3702 if (defined $prereq_pm) {
3703 for my $pre (keys %$prereq_pm) {
3704 my $premo = CPAN::Shell->expand("Module",$pre);
3705 $premo->color_cmd_tmps($depth+1,$color);
3709 delete $self->{sponsored_mods};
3710 delete $self->{badtestcnt};
3712 $self->{incommandcolor} = $color;
3715 #-> sub CPAN::Distribution::as_string ;
3718 $self->containsmods;
3719 $self->SUPER::as_string(@_);
3722 #-> sub CPAN::Distribution::containsmods ;
3725 return keys %{$self->{CONTAINSMODS}} if exists $self->{CONTAINSMODS};
3726 my $dist_id = $self->{ID};
3727 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
3728 my $mod_file = $mod->cpan_file or next;
3729 my $mod_id = $mod->{ID} or next;
3730 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
3732 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
3734 keys %{$self->{CONTAINSMODS}};
3737 #-> sub CPAN::Distribution::uptodate ;
3741 foreach $c ($self->containsmods) {
3742 my $obj = CPAN::Shell->expandany($c);
3743 return 0 unless $obj->uptodate;
3748 #-> sub CPAN::Distribution::called_for ;
3751 $self->{CALLED_FOR} = $id if defined $id;
3752 return $self->{CALLED_FOR};
3755 #-> sub CPAN::Distribution::safe_chdir ;
3757 my($self,$todir) = @_;
3758 # we die if we cannot chdir and we are debuggable
3759 Carp::confess("safe_chdir called without todir argument")
3760 unless defined $todir and length $todir;
3762 $self->debug(sprintf "changed directory to %s", CPAN::anycwd())
3765 my $cwd = CPAN::anycwd();
3766 $CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
3767 qq{to todir[$todir]: $!});
3771 #-> sub CPAN::Distribution::get ;
3776 exists $self->{'build_dir'} and push @e,
3777 "Is already unwrapped into directory $self->{'build_dir'}";
3778 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3780 my $sub_wd = CPAN::anycwd(); # for cleaning up as good as possible
3783 # Get the file on local disk
3788 File::Spec->catfile(
3789 $CPAN::Config->{keep_source_where},
3792 split("/",$self->id)
3795 $self->debug("Doing localize") if $CPAN::DEBUG;
3796 unless ($local_file =
3797 CPAN::FTP->localize("authors/id/$self->{ID}",
3800 if ($CPAN::Index::DATE_OF_02) {
3801 $note = "Note: Current database in memory was generated ".
3802 "on $CPAN::Index::DATE_OF_02\n";
3804 $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n$note");
3806 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
3807 $self->{localfile} = $local_file;
3808 return if $CPAN::Signal;
3813 if ($CPAN::META->has_inst("Digest::MD5")) {
3814 $self->debug("Digest::MD5 is installed, verifying");
3817 $self->debug("Digest::MD5 is NOT installed");
3819 return if $CPAN::Signal;
3822 # Create a clean room and go there
3824 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
3825 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
3826 $self->safe_chdir($builddir);
3827 $self->debug("Removing tmp") if $CPAN::DEBUG;
3828 File::Path::rmtree("tmp");
3829 mkdir "tmp", 0755 or Carp::croak "Couldn't mkdir tmp: $!";
3831 $self->safe_chdir($sub_wd);
3834 $self->safe_chdir("tmp");
3839 if ($local_file =~ /(\.tar\.(gz|Z)|\.tgz)(?!\n)\Z/i){
3840 $self->{was_uncompressed}++ unless CPAN::Tarzip->gtest($local_file);
3841 $self->untar_me($local_file);
3842 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
3843 $self->unzip_me($local_file);
3844 } elsif ( $local_file =~ /\.pm\.(gz|Z)(?!\n)\Z/) {
3845 $self->{was_uncompressed}++ unless CPAN::Tarzip->gtest($local_file);
3846 $self->pm2dir_me($local_file);
3848 $self->{archived} = "NO";
3849 $self->safe_chdir($sub_wd);
3853 # we are still in the tmp directory!
3854 # Let's check if the package has its own directory.
3855 my $dh = DirHandle->new(File::Spec->curdir)
3856 or Carp::croak("Couldn't opendir .: $!");
3857 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
3859 my ($distdir,$packagedir);
3860 if (@readdir == 1 && -d $readdir[0]) {
3861 $distdir = $readdir[0];
3862 $packagedir = File::Spec->catdir($builddir,$distdir);
3863 $self->debug("packagedir[$packagedir]builddir[$builddir]distdir[$distdir]")
3865 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
3867 File::Path::rmtree($packagedir);
3868 rename($distdir,$packagedir) or
3869 Carp::confess("Couldn't rename $distdir to $packagedir: $!");
3870 $self->debug(sprintf("renamed distdir[%s] to packagedir[%s] -e[%s]-d[%s]",
3877 my $userid = $self->cpan_userid;
3879 CPAN->debug("no userid? self[$self]");
3882 my $pragmatic_dir = $userid . '000';
3883 $pragmatic_dir =~ s/\W_//g;
3884 $pragmatic_dir++ while -d "../$pragmatic_dir";
3885 $packagedir = File::Spec->catdir($builddir,$pragmatic_dir);
3886 $self->debug("packagedir[$packagedir]") if $CPAN::DEBUG;
3887 File::Path::mkpath($packagedir);
3889 for $f (@readdir) { # is already without "." and ".."
3890 my $to = File::Spec->catdir($packagedir,$f);
3891 rename($f,$to) or Carp::confess("Couldn't rename $f to $to: $!");
3895 $self->safe_chdir($sub_wd);
3899 $self->{'build_dir'} = $packagedir;
3900 $self->safe_chdir(File::Spec->updir);
3901 File::Path::rmtree("tmp");
3903 my($mpl) = File::Spec->catfile($packagedir,"Makefile.PL");
3904 my($mpl_exists) = -f $mpl;
3905 unless ($mpl_exists) {
3906 # NFS has been reported to have racing problems after the
3907 # renaming of a directory in some environments.
3910 my $mpldh = DirHandle->new($packagedir)
3911 or Carp::croak("Couldn't opendir $packagedir: $!");
3912 $mpl_exists = grep /^Makefile\.PL$/, $mpldh->read;
3915 unless ($mpl_exists) {
3916 $self->debug(sprintf("makefilepl[%s]anycwd[%s]",
3920 my($configure) = File::Spec->catfile($packagedir,"Configure");
3921 if (-f $configure) {
3922 # do we have anything to do?
3923 $self->{'configure'} = $configure;
3924 } elsif (-f File::Spec->catfile($packagedir,"Makefile")) {
3925 $CPAN::Frontend->myprint(qq{
3926 Package comes with a Makefile and without a Makefile.PL.
3927 We\'ll try to build it with that Makefile then.
3929 $self->{writemakefile} = "YES";
3932 my $cf = $self->called_for || "unknown";
3937 $cf =~ s|[/\\:]||g; # risk of filesystem damage
3938 $cf = "unknown" unless length($cf);
3939 $CPAN::Frontend->myprint(qq{Package seems to come without Makefile.PL.
3940 (The test -f "$mpl" returned false.)
3941 Writing one on our own (setting NAME to $cf)\a\n});
3942 $self->{had_no_makefile_pl}++;
3945 # Writing our own Makefile.PL
3947 my $fh = FileHandle->new;
3949 or Carp::croak("Could not open >$mpl: $!");
3951 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
3952 # because there was no Makefile.PL supplied.
3953 # Autogenerated on: }.scalar localtime().qq{
3955 use ExtUtils::MakeMaker;
3956 WriteMakefile(NAME => q[$cf]);
3966 # CPAN::Distribution::untar_me ;
3968 my($self,$local_file) = @_;
3969 $self->{archived} = "tar";
3970 if (CPAN::Tarzip->untar($local_file)) {
3971 $self->{unwrapped} = "YES";
3973 $self->{unwrapped} = "NO";
3977 # CPAN::Distribution::unzip_me ;
3979 my($self,$local_file) = @_;
3980 $self->{archived} = "zip";
3981 if (CPAN::Tarzip->unzip($local_file)) {
3982 $self->{unwrapped} = "YES";
3984 $self->{unwrapped} = "NO";
3990 my($self,$local_file) = @_;
3991 $self->{archived} = "pm";
3992 my $to = File::Basename::basename($local_file);
3993 $to =~ s/\.(gz|Z)(?!\n)\Z//;
3994 if (CPAN::Tarzip->gunzip($local_file,$to)) {
3995 $self->{unwrapped} = "YES";
3997 $self->{unwrapped} = "NO";
4001 #-> sub CPAN::Distribution::new ;
4003 my($class,%att) = @_;
4005 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
4007 my $this = { %att };
4008 return bless $this, $class;
4011 #-> sub CPAN::Distribution::look ;
4015 if ($^O eq 'MacOS') {
4016 $self->Mac::BuildTools::look;
4020 if ( $CPAN::Config->{'shell'} ) {
4021 $CPAN::Frontend->myprint(qq{
4022 Trying to open a subshell in the build directory...
4025 $CPAN::Frontend->myprint(qq{
4026 Your configuration does not define a value for subshells.
4027 Please define it with "o conf shell <your shell>"
4031 my $dist = $self->id;
4033 unless ($dir = $self->dir) {
4036 unless ($dir ||= $self->dir) {
4037 $CPAN::Frontend->mywarn(qq{
4038 Could not determine which directory to use for looking at $dist.
4042 my $pwd = CPAN::anycwd();
4043 $self->safe_chdir($dir);
4044 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
4045 system($CPAN::Config->{'shell'}) == 0
4046 or $CPAN::Frontend->mydie("Subprocess shell error");
4047 $self->safe_chdir($pwd);
4050 # CPAN::Distribution::cvs_import ;
4054 my $dir = $self->dir;
4056 my $package = $self->called_for;
4057 my $module = $CPAN::META->instance('CPAN::Module', $package);
4058 my $version = $module->cpan_version;
4060 my $userid = $self->cpan_userid;
4062 my $cvs_dir = (split '/', $dir)[-1];
4063 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
4065 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
4067 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
4068 if ($cvs_site_perl) {
4069 $cvs_dir = "$cvs_site_perl/$cvs_dir";
4071 my $cvs_log = qq{"imported $package $version sources"};
4072 $version =~ s/\./_/g;
4073 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
4074 "$cvs_dir", $userid, "v$version");
4076 my $pwd = CPAN::anycwd();
4077 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
4079 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
4081 $CPAN::Frontend->myprint(qq{@cmd\n});
4082 system(@cmd) == 0 or
4083 $CPAN::Frontend->mydie("cvs import failed");
4084 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
4087 #-> sub CPAN::Distribution::readme ;
4090 my($dist) = $self->id;
4091 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
4092 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
4095 File::Spec->catfile(
4096 $CPAN::Config->{keep_source_where},
4099 split("/","$sans.readme"),
4101 $self->debug("Doing localize") if $CPAN::DEBUG;
4102 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
4104 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
4106 if ($^O eq 'MacOS') {
4107 Mac::BuildTools::launch_file($local_file);
4111 my $fh_pager = FileHandle->new;
4112 local($SIG{PIPE}) = "IGNORE";
4113 $fh_pager->open("|$CPAN::Config->{'pager'}")
4114 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
4115 my $fh_readme = FileHandle->new;
4116 $fh_readme->open($local_file)
4117 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
4118 $CPAN::Frontend->myprint(qq{
4121 with pager "$CPAN::Config->{'pager'}"
4124 $fh_pager->print(<$fh_readme>);
4127 #-> sub CPAN::Distribution::verifyMD5 ;
4132 $self->{MD5_STATUS} ||= "";
4133 $self->{MD5_STATUS} eq "OK" and push @e, "MD5 Checksum was ok";
4134 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4136 my($lc_want,$lc_file,@local,$basename);
4137 @local = split("/",$self->id);
4139 push @local, "CHECKSUMS";
4141 File::Spec->catfile($CPAN::Config->{keep_source_where},
4142 "authors", "id", @local);
4147 $self->MD5_check_file($lc_want)
4149 return $self->{MD5_STATUS} = "OK";
4151 $lc_file = CPAN::FTP->localize("authors/id/@local",
4154 $CPAN::Frontend->myprint("Trying $lc_want.gz\n");
4155 $local[-1] .= ".gz";
4156 $lc_file = CPAN::FTP->localize("authors/id/@local",
4159 $lc_file =~ s/\.gz(?!\n)\Z//;
4160 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
4165 $self->MD5_check_file($lc_file);
4168 #-> sub CPAN::Distribution::MD5_check_file ;
4169 sub MD5_check_file {
4170 my($self,$chk_file) = @_;
4171 my($cksum,$file,$basename);
4172 $file = $self->{localfile};
4173 $basename = File::Basename::basename($file);
4174 my $fh = FileHandle->new;
4175 if (open $fh, $chk_file){
4178 $eval =~ s/\015?\012/\n/g;
4180 my($comp) = Safe->new();
4181 $cksum = $comp->reval($eval);
4183 rename $chk_file, "$chk_file.bad";
4184 Carp::confess($@) if $@;
4187 Carp::carp "Could not open $chk_file for reading";
4190 if (exists $cksum->{$basename}{md5}) {
4191 $self->debug("Found checksum for $basename:" .
4192 "$cksum->{$basename}{md5}\n") if $CPAN::DEBUG;
4196 my $eq = $self->eq_MD5($fh,$cksum->{$basename}{'md5'});
4198 $fh = CPAN::Tarzip->TIEHANDLE($file);
4201 # had to inline it, when I tied it, the tiedness got lost on
4202 # the call to eq_MD5. (Jan 1998)
4203 my $md5 = Digest::MD5->new;
4206 while ($fh->READ($ref, 4096) > 0){
4209 my $hexdigest = $md5->hexdigest;
4210 $eq += $hexdigest eq $cksum->{$basename}{'md5-ungz'};
4214 $CPAN::Frontend->myprint("Checksum for $file ok\n");
4215 return $self->{MD5_STATUS} = "OK";
4217 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
4218 qq{distribution file. }.
4219 qq{Please investigate.\n\n}.
4221 $CPAN::META->instance(
4226 my $wrap = qq{I\'d recommend removing $file. Its MD5
4227 checksum is incorrect. Maybe you have configured your 'urllist' with
4228 a bad URL. Please check this array with 'o conf urllist', and
4231 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
4233 # former versions just returned here but this seems a
4234 # serious threat that deserves a die
4236 # $CPAN::Frontend->myprint("\n\n");
4240 # close $fh if fileno($fh);
4242 $self->{MD5_STATUS} ||= "";
4243 if ($self->{MD5_STATUS} eq "NIL") {
4244 $CPAN::Frontend->mywarn(qq{
4245 Warning: No md5 checksum for $basename in $chk_file.
4247 The cause for this may be that the file is very new and the checksum
4248 has not yet been calculated, but it may also be that something is
4249 going awry right now.
4251 my $answer = ExtUtils::MakeMaker::prompt("Proceed?", "yes");
4252 $answer =~ /^\s*y/i or $CPAN::Frontend->mydie("Aborted.");
4254 $self->{MD5_STATUS} = "NIL";
4259 #-> sub CPAN::Distribution::eq_MD5 ;
4261 my($self,$fh,$expectMD5) = @_;
4262 my $md5 = Digest::MD5->new;
4264 while (read($fh, $data, 4096)){
4267 # $md5->addfile($fh);
4268 my $hexdigest = $md5->hexdigest;
4269 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
4270 $hexdigest eq $expectMD5;
4273 #-> sub CPAN::Distribution::force ;
4275 # Both modules and distributions know if "force" is in effect by
4276 # autoinspection, not by inspecting a global variable. One of the
4277 # reason why this was chosen to work that way was the treatment of
4278 # dependencies. They should not autpomatically inherit the force
4279 # status. But this has the downside that ^C and die() will return to
4280 # the prompt but will not be able to reset the force_update
4281 # attributes. We try to correct for it currently in the read_metadata
4282 # routine, and immediately before we check for a Signal. I hope this
4283 # works out in one of v1.57_53ff
4286 my($self, $method) = @_;
4288 MD5_STATUS archived build_dir localfile make install unwrapped
4291 delete $self->{$att};
4293 if ($method && $method eq "install") {
4294 $self->{"force_update"}++; # name should probably have been force_install
4298 #-> sub CPAN::Distribution::unforce ;
4301 delete $self->{'force_update'};
4304 #-> sub CPAN::Distribution::isa_perl ;
4307 my $file = File::Basename::basename($self->id);
4308 if ($file =~ m{ ^ perl
4321 } elsif ($self->cpan_comment
4323 $self->cpan_comment =~ /isa_perl\(.+?\)/){
4328 #-> sub CPAN::Distribution::perl ;
4331 my($perl) = File::Spec->file_name_is_absolute($^X) ? $^X : "";
4332 my $pwd = CPAN::anycwd();
4333 my $candidate = File::Spec->catfile($pwd,$^X);
4334 $perl ||= $candidate if MM->maybe_command($candidate);
4336 my ($component,$perl_name);
4337 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
4338 PATH_COMPONENT: foreach $component (File::Spec->path(),
4339 $Config::Config{'binexp'}) {
4340 next unless defined($component) && $component;
4341 my($abs) = File::Spec->catfile($component,$perl_name);
4342 if (MM->maybe_command($abs)) {
4352 #-> sub CPAN::Distribution::make ;
4355 $CPAN::Frontend->myprint(sprintf "Running make for %s\n", $self->id);
4356 # Emergency brake if they said install Pippi and get newest perl
4357 if ($self->isa_perl) {
4359 $self->called_for ne $self->id &&
4360 ! $self->{force_update}
4362 # if we die here, we break bundles
4363 $CPAN::Frontend->mywarn(sprintf qq{
4364 The most recent version "%s" of the module "%s"
4365 comes with the current version of perl (%s).
4366 I\'ll build that only if you ask for something like
4371 $CPAN::META->instance(
4385 $self->{archived} eq "NO" and push @e,
4386 "Is neither a tar nor a zip archive.";
4388 $self->{unwrapped} eq "NO" and push @e,
4389 "had problems unarchiving. Please build manually";
4391 exists $self->{writemakefile} &&
4392 $self->{writemakefile} =~ m/ ^ NO\s* ( .* ) /sx and push @e,
4393 $1 || "Had some problem writing Makefile";
4395 defined $self->{'make'} and push @e,
4396 "Has already been processed within this session";
4398 exists $self->{later} and length($self->{later}) and
4399 push @e, $self->{later};
4401 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4403 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
4404 my $builddir = $self->dir;
4405 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
4406 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
4408 if ($^O eq 'MacOS') {
4409 Mac::BuildTools::make($self);
4414 if ($self->{'configure'}) {
4415 $system = $self->{'configure'};
4417 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
4419 # This needs a handler that can be turned on or off:
4420 # $switch = "-MExtUtils::MakeMaker ".
4421 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
4423 $system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}";
4425 unless (exists $self->{writemakefile}) {
4426 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
4429 if ($CPAN::Config->{inactivity_timeout}) {
4431 alarm $CPAN::Config->{inactivity_timeout};
4432 local $SIG{CHLD}; # = sub { wait };
4433 if (defined($pid = fork)) {
4438 # note, this exec isn't necessary if
4439 # inactivity_timeout is 0. On the Mac I'd
4440 # suggest, we set it always to 0.
4444 $CPAN::Frontend->myprint("Cannot fork: $!");
4452 $CPAN::Frontend->myprint($@);
4453 $self->{writemakefile} = "NO $@";
4458 $ret = system($system);
4460 $self->{writemakefile} = "NO Makefile.PL returned status $ret";
4464 if (-f "Makefile") {
4465 $self->{writemakefile} = "YES";
4466 delete $self->{make_clean}; # if cleaned before, enable next
4468 $self->{writemakefile} =
4469 qq{NO Makefile.PL refused to write a Makefile.};
4470 # It's probably worth it to record the reason, so let's retry
4472 # my $fh = IO::File->new("$system |"); # STDERR? STDIN?
4473 # $self->{writemakefile} .= <$fh>;
4477 delete $self->{force_update};
4480 if (my @prereq = $self->unsat_prereq){
4481 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4483 $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
4484 if (system($system) == 0) {
4485 $CPAN::Frontend->myprint(" $system -- OK\n");
4486 $self->{'make'} = "YES";
4488 $self->{writemakefile} ||= "YES";
4489 $self->{'make'} = "NO";
4490 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4494 sub follow_prereqs {
4498 $CPAN::Frontend->myprint("---- Unsatisfied dependencies detected ".
4499 "during [$id] -----\n");
4501 for my $p (@prereq) {
4502 $CPAN::Frontend->myprint(" $p\n");
4505 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
4507 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
4508 require ExtUtils::MakeMaker;
4509 my $answer = ExtUtils::MakeMaker::prompt(
4510 "Shall I follow them and prepend them to the queue
4511 of modules we are processing right now?", "yes");
4512 $follow = $answer =~ /^\s*y/i;
4516 myprint(" Ignoring dependencies on modules @prereq\n");
4519 # color them as dirty
4520 for my $p (@prereq) {
4521 CPAN::Shell->expandany($p)->color_cmd_tmps(0,1);
4523 CPAN::Queue->jumpqueue(@prereq,$id); # queue them and requeue yourself
4524 $self->{later} = "Delayed until after prerequisites";
4525 return 1; # signal success to the queuerunner
4529 #-> sub CPAN::Distribution::unsat_prereq ;
4532 my $prereq_pm = $self->prereq_pm or return;
4534 NEED: while (my($need_module, $need_version) = each %$prereq_pm) {
4535 my $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
4536 # we were too demanding:
4537 next if $nmo->uptodate;
4539 # if they have not specified a version, we accept any installed one
4540 if (not defined $need_version or
4541 $need_version == 0 or
4542 $need_version eq "undef") {
4543 next if defined $nmo->inst_file;
4546 # We only want to install prereqs if either they're not installed
4547 # or if the installed version is too old. We cannot omit this
4548 # check, because if 'force' is in effect, nobody else will check.
4552 defined $nmo->inst_file &&
4553 ! CPAN::Version->vgt($need_version, $nmo->inst_version)
4555 CPAN->debug(sprintf "id[%s]inst_file[%s]inst_version[%s]need_version[%s]",
4559 CPAN::Version->readable($need_version)
4565 if ($self->{sponsored_mods}{$need_module}++){
4566 # We have already sponsored it and for some reason it's still
4567 # not available. So we do nothing. Or what should we do?
4568 # if we push it again, we have a potential infinite loop
4571 push @need, $need_module;
4576 #-> sub CPAN::Distribution::prereq_pm ;
4579 return $self->{prereq_pm} if
4580 exists $self->{prereq_pm_detected} && $self->{prereq_pm_detected};
4581 return unless $self->{writemakefile}; # no need to have succeeded
4582 # but we must have run it
4583 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
4584 my $makefile = File::Spec->catfile($build_dir,"Makefile");
4589 $fh = FileHandle->new("<$makefile\0")) {
4593 # A.Speer @p -> %p, where %p is $p{Module::Name}=Required_Version
4595 last if /MakeMaker post_initialize section/;
4597 \s+PREREQ_PM\s+=>\s+(.+)
4600 # warn "Found prereq expr[$p]";
4602 # Regexp modified by A.Speer to remember actual version of file
4603 # PREREQ_PM hash key wants, then add to
4604 while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
4605 # In case a prereq is mentioned twice, complain.
4606 if ( defined $p{$1} ) {
4607 warn "Warning: PREREQ_PM mentions $1 more than once, last mention wins";
4614 $self->{prereq_pm_detected}++;
4615 return $self->{prereq_pm} = \%p;
4618 #-> sub CPAN::Distribution::test ;
4623 delete $self->{force_update};
4626 $CPAN::Frontend->myprint("Running make test\n");
4627 if (my @prereq = $self->unsat_prereq){
4628 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4632 exists $self->{make} or exists $self->{later} or push @e,
4633 "Make had some problems, maybe interrupted? Won't test";
4635 exists $self->{'make'} and
4636 $self->{'make'} eq 'NO' and
4637 push @e, "Can't test without successful make";
4639 exists $self->{build_dir} or push @e, "Has no own directory";
4640 $self->{badtestcnt} ||= 0;
4641 $self->{badtestcnt} > 0 and
4642 push @e, "Won't repeat unsuccessful test during this command";
4644 exists $self->{later} and length($self->{later}) and
4645 push @e, $self->{later};
4647 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4649 chdir $self->{'build_dir'} or
4650 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4651 $self->debug("Changed directory to $self->{'build_dir'}")
4654 if ($^O eq 'MacOS') {
4655 Mac::BuildTools::make_test($self);
4659 local $ENV{PERL5LIB} = $ENV{PERL5LIB} || "";
4660 $CPAN::META->set_perl5lib;
4661 my $system = join " ", $CPAN::Config->{'make'}, "test";
4662 if (system($system) == 0) {
4663 $CPAN::Frontend->myprint(" $system -- OK\n");
4664 $CPAN::META->is_tested($self->{'build_dir'});
4665 $self->{make_test} = "YES";
4667 $self->{make_test} = "NO";
4668 $self->{badtestcnt}++;
4669 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4673 #-> sub CPAN::Distribution::clean ;
4676 $CPAN::Frontend->myprint("Running make clean\n");
4679 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
4680 push @e, "make clean already called once";
4681 exists $self->{build_dir} or push @e, "Has no own directory";
4682 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4684 chdir $self->{'build_dir'} or
4685 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4686 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
4688 if ($^O eq 'MacOS') {
4689 Mac::BuildTools::make_clean($self);
4693 my $system = join " ", $CPAN::Config->{'make'}, "clean";
4694 if (system($system) == 0) {
4695 $CPAN::Frontend->myprint(" $system -- OK\n");
4699 # Jost Krieger pointed out that this "force" was wrong because
4700 # it has the effect that the next "install" on this distribution
4701 # will untar everything again. Instead we should bring the
4702 # object's state back to where it is after untarring.
4704 delete $self->{force_update};
4705 delete $self->{install};
4706 delete $self->{writemakefile};
4707 delete $self->{make};
4708 delete $self->{make_test}; # no matter if yes or no, tests must be redone
4709 $self->{make_clean} = "YES";
4712 # Hmmm, what to do if make clean failed?
4714 $CPAN::Frontend->myprint(qq{ $system -- NOT OK
4716 make clean did not succeed, marking directory as unusable for further work.
4718 $self->force("make"); # so that this directory won't be used again
4723 #-> sub CPAN::Distribution::install ;
4728 delete $self->{force_update};
4731 $CPAN::Frontend->myprint("Running make install\n");
4734 exists $self->{build_dir} or push @e, "Has no own directory";
4736 exists $self->{make} or exists $self->{later} or push @e,
4737 "Make had some problems, maybe interrupted? Won't install";
4739 exists $self->{'make'} and
4740 $self->{'make'} eq 'NO' and
4741 push @e, "make had returned bad status, install seems impossible";
4743 push @e, "make test had returned bad status, ".
4744 "won't install without force"
4745 if exists $self->{'make_test'} and
4746 $self->{'make_test'} eq 'NO' and
4747 ! $self->{'force_update'};
4749 exists $self->{'install'} and push @e,
4750 $self->{'install'} eq "YES" ?
4751 "Already done" : "Already tried without success";
4753 exists $self->{later} and length($self->{later}) and
4754 push @e, $self->{later};
4756 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4758 chdir $self->{'build_dir'} or
4759 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4760 $self->debug("Changed directory to $self->{'build_dir'}")
4763 if ($^O eq 'MacOS') {
4764 Mac::BuildTools::make_install($self);
4768 my $system = join(" ", $CPAN::Config->{'make'},
4769 "install", $CPAN::Config->{make_install_arg});
4770 my($stderr) = $^O =~ /Win/i ? "" : " 2>&1 ";
4771 my($pipe) = FileHandle->new("$system $stderr |");
4774 $CPAN::Frontend->myprint($_);
4779 $CPAN::Frontend->myprint(" $system -- OK\n");
4780 $CPAN::META->is_installed($self->{'build_dir'});
4781 return $self->{'install'} = "YES";
4783 $self->{'install'} = "NO";
4784 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4785 if ($makeout =~ /permission/s && $> > 0) {
4786 $CPAN::Frontend->myprint(qq{ You may have to su }.
4787 qq{to root to install the package\n});
4790 delete $self->{force_update};
4793 #-> sub CPAN::Distribution::dir ;
4795 shift->{'build_dir'};
4798 package CPAN::Bundle;
4802 $CPAN::Frontend->myprint(
4803 qq{ look() commmand on bundles not}.
4804 qq{ implemented (What should it do?)}
4810 delete $self->{later};
4811 for my $c ( $self->contains ) {
4812 my $obj = CPAN::Shell->expandany($c) or next;
4817 #-> sub CPAN::Bundle::color_cmd_tmps ;
4818 sub color_cmd_tmps {
4820 my($depth) = shift || 0;
4821 my($color) = shift || 0;
4822 # a module needs to recurse to its cpan_file, a distribution needs
4823 # to recurse into its prereq_pms, a bundle needs to recurse into its modules
4825 return if exists $self->{incommandcolor}
4826 && $self->{incommandcolor}==$color;
4827 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
4828 "color_cmd_tmps depth[%s] self[%s] id[%s]",
4833 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
4835 for my $c ( $self->contains ) {
4836 my $obj = CPAN::Shell->expandany($c) or next;
4837 CPAN->debug("c[$c]obj[$obj]") if $CPAN::DEBUG;
4838 $obj->color_cmd_tmps($depth+1,$color);
4841 delete $self->{badtestcnt};
4843 $self->{incommandcolor} = $color;
4846 #-> sub CPAN::Bundle::as_string ;
4850 # following line must be "=", not "||=" because we have a moving target
4851 $self->{INST_VERSION} = $self->inst_version;
4852 return $self->SUPER::as_string;
4855 #-> sub CPAN::Bundle::contains ;
4858 my($inst_file) = $self->inst_file || "";
4859 my($id) = $self->id;
4860 $self->debug("inst_file[$inst_file]id[$id]") if $CPAN::DEBUG;
4861 unless ($inst_file) {
4862 # Try to get at it in the cpan directory
4863 $self->debug("no inst_file") if $CPAN::DEBUG;
4865 $CPAN::Frontend->mydie("I don't know a bundle with ID $id\n") unless
4866 $cpan_file = $self->cpan_file;
4867 if ($cpan_file eq "N/A") {
4868 $CPAN::Frontend->mydie("Bundle $id not found on disk and not on CPAN.
4869 Maybe stale symlink? Maybe removed during session? Giving up.\n");
4871 my $dist = $CPAN::META->instance('CPAN::Distribution',
4874 $self->debug($dist->as_string) if $CPAN::DEBUG;
4875 my($todir) = $CPAN::Config->{'cpan_home'};
4876 my(@me,$from,$to,$me);
4877 @me = split /::/, $self->id;
4879 $me = File::Spec->catfile(@me);
4880 $from = $self->find_bundle_file($dist->{'build_dir'},$me);
4881 $to = File::Spec->catfile($todir,$me);
4882 File::Path::mkpath(File::Basename::dirname($to));
4883 File::Copy::copy($from, $to)
4884 or Carp::confess("Couldn't copy $from to $to: $!");
4888 my $fh = FileHandle->new;
4890 open($fh,$inst_file) or die "Could not open '$inst_file': $!";
4892 $self->debug("inst_file[$inst_file]") if $CPAN::DEBUG;
4894 $in_cont = m/^=(?!head1\s+CONTENTS)/ ? 0 :
4895 m/^=head1\s+CONTENTS/ ? 1 : $in_cont;
4896 next unless $in_cont;
4901 push @result, (split " ", $_, 2)[0];
4904 delete $self->{STATUS};
4905 $self->{CONTAINS} = \@result;
4906 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
4908 $CPAN::Frontend->mywarn(qq{
4909 The bundle file "$inst_file" may be a broken
4910 bundlefile. It seems not to contain any bundle definition.
4911 Please check the file and if it is bogus, please delete it.
4912 Sorry for the inconvenience.
4918 #-> sub CPAN::Bundle::find_bundle_file
4919 sub find_bundle_file {
4920 my($self,$where,$what) = @_;
4921 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
4922 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
4923 ### my $bu = File::Spec->catfile($where,$what);
4924 ### return $bu if -f $bu;
4925 my $manifest = File::Spec->catfile($where,"MANIFEST");
4926 unless (-f $manifest) {
4927 require ExtUtils::Manifest;
4928 my $cwd = CPAN::anycwd();
4929 chdir $where or $CPAN::Frontend->mydie(qq{Could not chdir to "$where": $!});
4930 ExtUtils::Manifest::mkmanifest();
4931 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
4933 my $fh = FileHandle->new($manifest)
4934 or Carp::croak("Couldn't open $manifest: $!");
4937 if ($^O eq 'MacOS') {
4940 $what2 =~ s/:Bundle://;
4943 $what2 =~ s|Bundle[/\\]||;
4948 my($file) = /(\S+)/;
4949 if ($file =~ m|\Q$what\E$|) {
4951 # return File::Spec->catfile($where,$bu); # bad
4954 # retry if she managed to
4955 # have no Bundle directory
4956 $bu = $file if $file =~ m|\Q$what2\E$|;
4958 $bu =~ tr|/|:| if $^O eq 'MacOS';
4959 return File::Spec->catfile($where, $bu) if $bu;
4960 Carp::croak("Couldn't find a Bundle file in $where");
4963 # needs to work quite differently from Module::inst_file because of
4964 # cpan_home/Bundle/ directory and the possibility that we have
4965 # shadowing effect. As it makes no sense to take the first in @INC for
4966 # Bundles, we parse them all for $VERSION and take the newest.
4968 #-> sub CPAN::Bundle::inst_file ;
4973 @me = split /::/, $self->id;
4976 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
4977 my $bfile = File::Spec->catfile($incdir, @me);
4978 CPAN->debug("bfile[$bfile]") if $CPAN::DEBUG;
4979 next unless -f $bfile;
4980 my $foundv = MM->parse_version($bfile);
4981 if (!$bestv || CPAN::Version->vgt($foundv,$bestv)) {
4982 $self->{INST_FILE} = $bfile;
4983 $self->{INST_VERSION} = $bestv = $foundv;
4989 #-> sub CPAN::Bundle::inst_version ;
4992 $self->inst_file; # finds INST_VERSION as side effect
4993 $self->{INST_VERSION};
4996 #-> sub CPAN::Bundle::rematein ;
4998 my($self,$meth) = @_;
4999 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
5000 my($id) = $self->id;
5001 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
5002 unless $self->inst_file || $self->cpan_file;
5004 for $s ($self->contains) {
5005 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
5006 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
5007 if ($type eq 'CPAN::Distribution') {
5008 $CPAN::Frontend->mywarn(qq{
5009 The Bundle }.$self->id.qq{ contains
5010 explicitly a file $s.
5014 # possibly noisy action:
5015 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
5016 my $obj = $CPAN::META->instance($type,$s);
5018 if ($obj->isa(CPAN::Bundle)
5020 exists $obj->{install_failed}
5022 ref($obj->{install_failed}) eq "HASH"
5024 for (keys %{$obj->{install_failed}}) {
5025 $self->{install_failed}{$_} = undef; # propagate faiure up
5028 $fail{$s} = 1; # the bundle itself may have succeeded but
5033 $success = $obj->can("uptodate") ? $obj->uptodate : 0;
5034 $success ||= $obj->{'install'} && $obj->{'install'} eq "YES";
5036 delete $self->{install_failed}{$s};
5043 # recap with less noise
5044 if ( $meth eq "install" ) {
5047 my $raw = sprintf(qq{Bundle summary:
5048 The following items in bundle %s had installation problems:},
5051 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
5052 $CPAN::Frontend->myprint("\n");
5055 for $s ($self->contains) {
5057 $paragraph .= "$s ";
5058 $self->{install_failed}{$s} = undef;
5059 $reported{$s} = undef;
5062 my $report_propagated;
5063 for $s (sort keys %{$self->{install_failed}}) {
5064 next if exists $reported{$s};
5065 $paragraph .= "and the following items had problems
5066 during recursive bundle calls: " unless $report_propagated++;
5067 $paragraph .= "$s ";
5069 $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
5070 $CPAN::Frontend->myprint("\n");
5072 $self->{'install'} = 'YES';
5077 #sub CPAN::Bundle::xs_file
5079 # If a bundle contains another that contains an xs_file we have
5080 # here, we just don't bother I suppose
5084 #-> sub CPAN::Bundle::force ;
5085 sub force { shift->rematein('force',@_); }
5086 #-> sub CPAN::Bundle::get ;
5087 sub get { shift->rematein('get',@_); }
5088 #-> sub CPAN::Bundle::make ;
5089 sub make { shift->rematein('make',@_); }
5090 #-> sub CPAN::Bundle::test ;
5093 $self->{badtestcnt} ||= 0;
5094 $self->rematein('test',@_);
5096 #-> sub CPAN::Bundle::install ;
5099 $self->rematein('install',@_);
5101 #-> sub CPAN::Bundle::clean ;
5102 sub clean { shift->rematein('clean',@_); }
5104 #-> sub CPAN::Bundle::uptodate ;
5107 return 0 unless $self->SUPER::uptodate; # we mut have the current Bundle def
5109 foreach $c ($self->contains) {
5110 my $obj = CPAN::Shell->expandany($c);
5111 return 0 unless $obj->uptodate;
5116 #-> sub CPAN::Bundle::readme ;
5119 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
5120 No File found for bundle } . $self->id . qq{\n}), return;
5121 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
5122 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
5125 package CPAN::Module;
5128 # sub cpan_userid { shift->{RO}{CPAN_USERID} }
5131 return unless exists $self->{RO}; # should never happen
5132 return $self->{RO}{CPAN_USERID} || $self->{RO}{userid};
5134 sub description { shift->{RO}{description} }
5138 delete $self->{later};
5139 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
5144 #-> sub CPAN::Module::color_cmd_tmps ;
5145 sub color_cmd_tmps {
5147 my($depth) = shift || 0;
5148 my($color) = shift || 0;
5149 # a module needs to recurse to its cpan_file
5151 return if exists $self->{incommandcolor}
5152 && $self->{incommandcolor}==$color;
5153 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
5154 "color_cmd_tmps depth[%s] self[%s] id[%s]",
5159 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
5161 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
5162 $dist->color_cmd_tmps($depth+1,$color);
5165 delete $self->{badtestcnt};
5167 $self->{incommandcolor} = $color;
5170 #-> sub CPAN::Module::as_glimpse ;
5174 my $class = ref($self);
5175 $class =~ s/^CPAN:://;
5179 $CPAN::Shell::COLOR_REGISTERED
5181 $CPAN::META->has_inst("Term::ANSIColor")
5183 $self->{RO}{description}
5185 $color_on = Term::ANSIColor::color("green");
5186 $color_off = Term::ANSIColor::color("reset");
5188 push @m, sprintf("%-15s %s%-15s%s (%s)\n",
5197 #-> sub CPAN::Module::as_string ;
5201 CPAN->debug($self) if $CPAN::DEBUG;
5202 my $class = ref($self);
5203 $class =~ s/^CPAN:://;
5205 push @m, $class, " id = $self->{ID}\n";
5206 my $sprintf = " %-12s %s\n";
5207 push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
5208 if $self->description;
5209 my $sprintf2 = " %-12s %s (%s)\n";
5211 if ($userid = $self->cpan_userid || $self->userid){
5213 if ($author = CPAN::Shell->expand('Author',$userid)) {
5216 if ($m = $author->email) {
5223 $author->fullname . $email
5227 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
5228 if $self->cpan_version;
5229 push @m, sprintf($sprintf, 'CPAN_FILE', $self->cpan_file)
5230 if $self->cpan_file;
5231 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
5232 my(%statd,%stats,%statl,%stati);
5233 @statd{qw,? i c a b R M S,} = qw,unknown idea
5234 pre-alpha alpha beta released mature standard,;
5235 @stats{qw,? m d u n,} = qw,unknown mailing-list
5236 developer comp.lang.perl.* none,;
5237 @statl{qw,? p c + o h,} = qw,unknown perl C C++ other hybrid,;
5238 @stati{qw,? f r O h,} = qw,unknown functions
5239 references+ties object-oriented hybrid,;
5240 $statd{' '} = 'unknown';
5241 $stats{' '} = 'unknown';
5242 $statl{' '} = 'unknown';
5243 $stati{' '} = 'unknown';
5251 $statd{$self->{RO}{statd}},
5252 $stats{$self->{RO}{stats}},
5253 $statl{$self->{RO}{statl}},
5254 $stati{$self->{RO}{stati}}
5255 ) if $self->{RO}{statd};
5256 my $local_file = $self->inst_file;
5257 unless ($self->{MANPAGE}) {
5259 $self->{MANPAGE} = $self->manpage_headline($local_file);
5261 # If we have already untarred it, we should look there
5262 my $dist = $CPAN::META->instance('CPAN::Distribution',
5264 # warn "dist[$dist]";
5265 # mff=manifest file; mfh=manifest handle
5270 (-f ($mff = File::Spec->catfile($dist->{build_dir}, "MANIFEST")))
5272 $mfh = FileHandle->new($mff)
5274 CPAN->debug("mff[$mff]") if $CPAN::DEBUG;
5275 my $lfre = $self->id; # local file RE
5278 my($lfl); # local file file
5280 my(@mflines) = <$mfh>;
5285 while (length($lfre)>5 and !$lfl) {
5286 ($lfl) = grep /$lfre/, @mflines;
5287 CPAN->debug("lfl[$lfl]lfre[$lfre]") if $CPAN::DEBUG;
5290 $lfl =~ s/\s.*//; # remove comments
5291 $lfl =~ s/\s+//g; # chomp would maybe be too system-specific
5292 my $lfl_abs = File::Spec->catfile($dist->{build_dir},$lfl);
5293 # warn "lfl_abs[$lfl_abs]";
5295 $self->{MANPAGE} = $self->manpage_headline($lfl_abs);
5301 for $item (qw/MANPAGE/) {
5302 push @m, sprintf($sprintf, $item, $self->{$item})
5303 if exists $self->{$item};
5305 for $item (qw/CONTAINS/) {
5306 push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
5307 if exists $self->{$item} && @{$self->{$item}};
5309 push @m, sprintf($sprintf, 'INST_FILE',
5310 $local_file || "(not installed)");
5311 push @m, sprintf($sprintf, 'INST_VERSION',
5312 $self->inst_version) if $local_file;
5316 sub manpage_headline {
5317 my($self,$local_file) = @_;
5318 my(@local_file) = $local_file;
5319 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
5320 push @local_file, $local_file;
5322 for $locf (@local_file) {
5323 next unless -f $locf;
5324 my $fh = FileHandle->new($locf)
5325 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
5329 $inpod = m/^=(?!head1\s+NAME\s*$)/ ? 0 :
5330 m/^=head1\s+NAME\s*$/ ? 1 : $inpod;
5343 #-> sub CPAN::Module::cpan_file ;
5344 # Note: also inherited by CPAN::Bundle
5347 CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
5348 unless (defined $self->{RO}{CPAN_FILE}) {
5349 CPAN::Index->reload;
5351 if (exists $self->{RO}{CPAN_FILE} && defined $self->{RO}{CPAN_FILE}){
5352 return $self->{RO}{CPAN_FILE};
5354 my $userid = $self->userid;
5356 if ($CPAN::META->exists("CPAN::Author",$userid)) {
5357 my $author = $CPAN::META->instance("CPAN::Author",
5359 my $fullname = $author->fullname;
5360 my $email = $author->email;
5361 unless (defined $fullname && defined $email) {
5362 return sprintf("Contact Author %s",
5366 return "Contact Author $fullname <$email>";
5368 return "UserID $userid";
5376 #-> sub CPAN::Module::cpan_version ;
5380 $self->{RO}{CPAN_VERSION} = 'undef'
5381 unless defined $self->{RO}{CPAN_VERSION};
5382 # I believe this is always a bug in the index and should be reported
5383 # as such, but usually I find out such an error and do not want to
5384 # provoke too many bugreports
5386 $self->{RO}{CPAN_VERSION};
5389 #-> sub CPAN::Module::force ;
5392 $self->{'force_update'}++;
5395 #-> sub CPAN::Module::rematein ;
5397 my($self,$meth) = @_;
5398 $CPAN::Frontend->myprint(sprintf("Running %s for module %s\n",
5401 my $cpan_file = $self->cpan_file;
5402 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
5403 $CPAN::Frontend->mywarn(sprintf qq{
5404 The module %s isn\'t available on CPAN.
5406 Either the module has not yet been uploaded to CPAN, or it is
5407 temporary unavailable. Please contact the author to find out
5408 more about the status. Try 'i %s'.
5415 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
5416 $pack->called_for($self->id);
5417 $pack->force($meth) if exists $self->{'force_update'};
5419 $pack->unforce if $pack->can("unforce") && exists $self->{'force_update'};
5420 delete $self->{'force_update'};
5423 #-> sub CPAN::Module::readme ;
5424 sub readme { shift->rematein('readme') }
5425 #-> sub CPAN::Module::look ;
5426 sub look { shift->rematein('look') }
5427 #-> sub CPAN::Module::cvs_import ;
5428 sub cvs_import { shift->rematein('cvs_import') }
5429 #-> sub CPAN::Module::get ;
5430 sub get { shift->rematein('get',@_); }
5431 #-> sub CPAN::Module::make ;
5434 $self->rematein('make');
5436 #-> sub CPAN::Module::test ;
5439 $self->{badtestcnt} ||= 0;
5440 $self->rematein('test',@_);
5442 #-> sub CPAN::Module::uptodate ;
5445 my($latest) = $self->cpan_version;
5447 my($inst_file) = $self->inst_file;
5449 if (defined $inst_file) {
5450 $have = $self->inst_version;
5455 ! CPAN::Version->vgt($latest, $have)
5457 CPAN->debug("returning uptodate. inst_file[$inst_file] ".
5458 "latest[$latest] have[$have]") if $CPAN::DEBUG;
5463 #-> sub CPAN::Module::install ;
5469 not exists $self->{'force_update'}
5471 $CPAN::Frontend->myprint( $self->id. " is up to date.\n");
5475 $self->rematein('install') if $doit;
5477 #-> sub CPAN::Module::clean ;
5478 sub clean { shift->rematein('clean') }
5480 #-> sub CPAN::Module::inst_file ;
5484 @packpath = split /::/, $self->{ID};
5485 $packpath[-1] .= ".pm";
5486 foreach $dir (@INC) {
5487 my $pmfile = File::Spec->catfile($dir,@packpath);
5495 #-> sub CPAN::Module::xs_file ;
5499 @packpath = split /::/, $self->{ID};
5500 push @packpath, $packpath[-1];
5501 $packpath[-1] .= "." . $Config::Config{'dlext'};
5502 foreach $dir (@INC) {
5503 my $xsfile = File::Spec->catfile($dir,'auto',@packpath);
5511 #-> sub CPAN::Module::inst_version ;
5514 my $parsefile = $self->inst_file or return;
5515 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
5518 # there was a bug in 5.6.0 that let lots of unini warnings out of
5519 # parse_version. Fixed shortly after 5.6.0 by PMQS. We can remove
5520 # the following workaround after 5.6.1 is out.
5521 local($SIG{__WARN__}) = sub { my $w = shift;
5522 return if $w =~ /uninitialized/i;
5526 $have = MM->parse_version($parsefile) || "undef";
5527 $have =~ s/^ //; # since the %vd hack these two lines here are needed
5528 $have =~ s/ $//; # trailing whitespace happens all the time
5530 # My thoughts about why %vd processing should happen here
5532 # Alt1 maintain it as string with leading v:
5533 # read index files do nothing
5534 # compare it use utility for compare
5535 # print it do nothing
5537 # Alt2 maintain it as what it is
5538 # read index files convert
5539 # compare it use utility because there's still a ">" vs "gt" issue
5540 # print it use CPAN::Version for print
5542 # Seems cleaner to hold it in memory as a string starting with a "v"
5544 # If the author of this module made a mistake and wrote a quoted
5545 # "v1.13" instead of v1.13, we simply leave it at that with the
5546 # effect that *we* will treat it like a v-tring while the rest of
5547 # perl won't. Seems sensible when we consider that any action we
5548 # could take now would just add complexity.
5550 $have = CPAN::Version->readable($have);
5552 $have =~ s/\s*//g; # stringify to float around floating point issues
5553 $have; # no stringify needed, \s* above matches always
5556 package CPAN::Tarzip;
5558 # CPAN::Tarzip::gzip
5560 my($class,$read,$write) = @_;
5561 if ($CPAN::META->has_inst("Compress::Zlib")) {
5563 $fhw = FileHandle->new($read)
5564 or $CPAN::Frontend->mydie("Could not open $read: $!");
5565 my $gz = Compress::Zlib::gzopen($write, "wb")
5566 or $CPAN::Frontend->mydie("Cannot gzopen $write: $!\n");
5567 $gz->gzwrite($buffer)
5568 while read($fhw,$buffer,4096) > 0 ;
5573 system("$CPAN::Config->{gzip} -c $read > $write")==0;
5578 # CPAN::Tarzip::gunzip
5580 my($class,$read,$write) = @_;
5581 if ($CPAN::META->has_inst("Compress::Zlib")) {
5583 $fhw = FileHandle->new(">$write")
5584 or $CPAN::Frontend->mydie("Could not open >$write: $!");
5585 my $gz = Compress::Zlib::gzopen($read, "rb")
5586 or $CPAN::Frontend->mydie("Cannot gzopen $read: $!\n");
5587 $fhw->print($buffer)
5588 while $gz->gzread($buffer) > 0 ;
5589 $CPAN::Frontend->mydie("Error reading from $read: $!\n")
5590 if $gz->gzerror != Compress::Zlib::Z_STREAM_END();
5595 system("$CPAN::Config->{gzip} -dc $read > $write")==0;
5600 # CPAN::Tarzip::gtest
5602 my($class,$read) = @_;
5603 # After I had reread the documentation in zlib.h, I discovered that
5604 # uncompressed files do not lead to an gzerror (anymore?).
5605 if ( $CPAN::META->has_inst("Compress::Zlib") ) {
5608 my $gz = Compress::Zlib::gzopen($read, "rb")
5609 or $CPAN::Frontend->mydie(sprintf("Cannot gzopen %s: %s\n",
5611 $Compress::Zlib::gzerrno));
5612 while ($gz->gzread($buffer) > 0 ){
5613 $len += length($buffer);
5616 my $err = $gz->gzerror;
5617 my $success = ! $err || $err == Compress::Zlib::Z_STREAM_END();
5618 if ($len == -s $read){
5620 CPAN->debug("hit an uncompressed file") if $CPAN::DEBUG;
5623 CPAN->debug("err[$err]success[$success]") if $CPAN::DEBUG;
5626 return system("$CPAN::Config->{gzip} -dt $read")==0;
5631 # CPAN::Tarzip::TIEHANDLE
5633 my($class,$file) = @_;
5635 $class->debug("file[$file]");
5636 if ($CPAN::META->has_inst("Compress::Zlib")) {
5637 my $gz = Compress::Zlib::gzopen($file,"rb") or
5638 die "Could not gzopen $file";
5639 $ret = bless {GZ => $gz}, $class;
5641 my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $file |";
5642 my $fh = FileHandle->new($pipe) or die "Could not pipe[$pipe]: $!";
5644 $ret = bless {FH => $fh}, $class;
5650 # CPAN::Tarzip::READLINE
5653 if (exists $self->{GZ}) {
5654 my $gz = $self->{GZ};
5655 my($line,$bytesread);
5656 $bytesread = $gz->gzreadline($line);
5657 return undef if $bytesread <= 0;
5660 my $fh = $self->{FH};
5661 return scalar <$fh>;
5666 # CPAN::Tarzip::READ
5668 my($self,$ref,$length,$offset) = @_;
5669 die "read with offset not implemented" if defined $offset;
5670 if (exists $self->{GZ}) {
5671 my $gz = $self->{GZ};
5672 my $byteread = $gz->gzread($$ref,$length);# 30eaf79e8b446ef52464b5422da328a8
5675 my $fh = $self->{FH};
5676 return read($fh,$$ref,$length);
5681 # CPAN::Tarzip::DESTROY
5684 if (exists $self->{GZ}) {
5685 my $gz = $self->{GZ};
5686 $gz->gzclose() if defined $gz; # hard to say if it is allowed
5687 # to be undef ever. AK, 2000-09
5689 my $fh = $self->{FH};
5690 $fh->close if defined $fh;
5696 # CPAN::Tarzip::untar
5698 my($class,$file) = @_;
5701 if (0) { # makes changing order easier
5702 } elsif ($BUGHUNTING){
5704 } elsif (MM->maybe_command($CPAN::Config->{gzip})
5706 MM->maybe_command($CPAN::Config->{'tar'})) {
5707 # should be default until Archive::Tar is fixed
5710 $CPAN::META->has_inst("Archive::Tar")
5712 $CPAN::META->has_inst("Compress::Zlib") ) {
5715 $CPAN::Frontend->mydie(qq{
5716 CPAN.pm needs either both external programs tar and gzip installed or
5717 both the modules Archive::Tar and Compress::Zlib. Neither prerequisite
5718 is available. Can\'t continue.
5721 if ($prefer==1) { # 1 => external gzip+tar
5723 my $is_compressed = $class->gtest($file);
5724 if ($is_compressed) {
5725 $system = "$CPAN::Config->{gzip} --decompress --stdout " .
5726 "< $file | $CPAN::Config->{tar} xvf -";
5728 $system = "$CPAN::Config->{tar} xvf $file";
5730 if (system($system) != 0) {
5731 # people find the most curious tar binaries that cannot handle
5733 if ($is_compressed) {
5734 (my $ungzf = $file) =~ s/\.gz(?!\n)\Z//;
5735 if (CPAN::Tarzip->gunzip($file, $ungzf)) {
5736 $CPAN::Frontend->myprint(qq{Uncompressed $file successfully\n});
5738 $CPAN::Frontend->mydie(qq{Couldn\'t uncompress $file\n});
5742 $system = "$CPAN::Config->{tar} xvf $file";
5743 $CPAN::Frontend->myprint(qq{Using Tar:$system:\n});
5744 if (system($system)==0) {
5745 $CPAN::Frontend->myprint(qq{Untarred $file successfully\n});
5747 $CPAN::Frontend->mydie(qq{Couldn\'t untar $file\n});
5753 } elsif ($prefer==2) { # 2 => modules
5754 my $tar = Archive::Tar->new($file,1);
5755 my $af; # archive file
5758 # RCS 1.337 had this code, it turned out unacceptable slow but
5759 # it revealed a bug in Archive::Tar. Code is only here to hunt
5760 # the bug again. It should never be enabled in published code.
5761 # GDGraph3d-0.53 was an interesting case according to Larry
5763 warn(">>>Bughunting code enabled<<< " x 20);
5764 for $af ($tar->list_files) {
5765 if ($af =~ m!^(/|\.\./)!) {
5766 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5767 "illegal member [$af]");
5769 $CPAN::Frontend->myprint("$af\n");
5770 $tar->extract($af); # slow but effective for finding the bug
5771 return if $CPAN::Signal;
5774 for $af ($tar->list_files) {
5775 if ($af =~ m!^(/|\.\./)!) {
5776 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5777 "illegal member [$af]");
5779 $CPAN::Frontend->myprint("$af\n");
5781 return if $CPAN::Signal;
5786 Mac::BuildTools::convert_files([$tar->list_files], 1)
5787 if ($^O eq 'MacOS');
5794 my($class,$file) = @_;
5795 if ($CPAN::META->has_inst("Archive::Zip")) {
5796 # blueprint of the code from Archive::Zip::Tree::extractTree();
5797 my $zip = Archive::Zip->new();
5799 $status = $zip->read($file);
5800 die "Read of file[$file] failed\n" if $status != Archive::Zip::AZ_OK();
5801 $CPAN::META->debug("Successfully read file[$file]") if $CPAN::DEBUG;
5802 my @members = $zip->members();
5803 for my $member ( @members ) {
5804 my $af = $member->fileName();
5805 if ($af =~ m!^(/|\.\./)!) {
5806 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5807 "illegal member [$af]");
5809 my $status = $member->extractToFileNamed( $af );
5810 $CPAN::META->debug("af[$af]status[$status]") if $CPAN::DEBUG;
5811 die "Extracting of file[$af] from zipfile[$file] failed\n" if
5812 $status != Archive::Zip::AZ_OK();
5813 return if $CPAN::Signal;
5817 my $unzip = $CPAN::Config->{unzip} or
5818 $CPAN::Frontend->mydie("Cannot unzip, no unzip program available");
5819 my @system = ($unzip, $file);
5820 return system(@system) == 0;
5825 package CPAN::Version;
5826 # CPAN::Version::vcmp courtesy Jost Krieger
5828 my($self,$l,$r) = @_;
5830 CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG;
5832 return 0 if $l eq $r; # short circuit for quicker success
5834 if ($l=~/^v/ <=> $r=~/^v/) {
5837 $_ = $self->float2vv($_);
5842 ($l ne "undef") <=> ($r ne "undef") ||
5846 $self->vstring($l) cmp $self->vstring($r)) ||
5852 my($self,$l,$r) = @_;
5853 $self->vcmp($l,$r) > 0;
5858 $n =~ s/^v// or die "CPAN::Version::vstring() called with invalid arg [$n]";
5859 pack "U*", split /\./, $n;
5862 # vv => visible vstring
5867 my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits to limit
5868 # architecture influence
5870 $mantissa .= "0" while length($mantissa)%3;
5871 my $ret = "v" . $rev;
5873 $mantissa =~ s/(\d{1,3})// or
5874 die "Panic: length>0 but not a digit? mantissa[$mantissa]";
5875 $ret .= ".".int($1);
5877 # warn "n[$n]ret[$ret]";
5883 $n =~ /^([\w\-\+\.]+)/;
5885 return $1 if defined $1 && length($1)>0;
5886 # if the first user reaches version v43, he will be treated as "+".
5887 # We'll have to decide about a new rule here then, depending on what
5888 # will be the prevailing versioning behavior then.
5890 if ($] < 5.006) { # or whenever v-strings were introduced
5891 # we get them wrong anyway, whatever we do, because 5.005 will
5892 # have already interpreted 0.2.4 to be "0.24". So even if he
5893 # indexer sends us something like "v0.2.4" we compare wrongly.
5895 # And if they say v1.2, then the old perl takes it as "v12"
5897 $CPAN::Frontend->mywarn("Suspicious version string seen [$n]");
5900 my $better = sprintf "v%vd", $n;
5901 CPAN->debug("n[$n] better[$better]") if $CPAN::DEBUG;
5913 CPAN - query, download and build perl modules from CPAN sites
5919 perl -MCPAN -e shell;
5925 autobundle, clean, install, make, recompile, test
5929 The CPAN module is designed to automate the make and install of perl
5930 modules and extensions. It includes some searching capabilities and
5931 knows how to use Net::FTP or LWP (or lynx or an external ftp client)
5932 to fetch the raw data from the net.
5934 Modules are fetched from one or more of the mirrored CPAN
5935 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
5938 The CPAN module also supports the concept of named and versioned
5939 I<bundles> of modules. Bundles simplify the handling of sets of
5940 related modules. See Bundles below.
5942 The package contains a session manager and a cache manager. There is
5943 no status retained between sessions. The session manager keeps track
5944 of what has been fetched, built and installed in the current
5945 session. The cache manager keeps track of the disk space occupied by
5946 the make processes and deletes excess space according to a simple FIFO
5949 For extended searching capabilities there's a plugin for CPAN available,
5950 L<C<CPAN::WAIT>|CPAN::WAIT>. C<CPAN::WAIT> is a full-text search engine
5951 that indexes all documents available in CPAN authors directories. If
5952 C<CPAN::WAIT> is installed on your system, the interactive shell of
5953 CPAN.pm will enable the C<wq>, C<wr>, C<wd>, C<wl>, and C<wh> commands
5954 which send queries to the WAIT server that has been configured for your
5957 All other methods provided are accessible in a programmer style and in an
5958 interactive shell style.
5960 =head2 Interactive Mode
5962 The interactive mode is entered by running
5964 perl -MCPAN -e shell
5966 which puts you into a readline interface. You will have the most fun if
5967 you install Term::ReadKey and Term::ReadLine to enjoy both history and
5970 Once you are on the command line, type 'h' and the rest should be
5973 The function call C<shell> takes two optional arguments, one is the
5974 prompt, the second is the default initial command line (the latter
5975 only works if a real ReadLine interface module is installed).
5977 The most common uses of the interactive modes are
5981 =item Searching for authors, bundles, distribution files and modules
5983 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
5984 for each of the four categories and another, C<i> for any of the
5985 mentioned four. Each of the four entities is implemented as a class
5986 with slightly differing methods for displaying an object.
5988 Arguments you pass to these commands are either strings exactly matching
5989 the identification string of an object or regular expressions that are
5990 then matched case-insensitively against various attributes of the
5991 objects. The parser recognizes a regular expression only if you
5992 enclose it between two slashes.
5994 The principle is that the number of found objects influences how an
5995 item is displayed. If the search finds one item, the result is
5996 displayed with the rather verbose method C<as_string>, but if we find
5997 more than one, we display each object with the terse method
6000 =item make, test, install, clean modules or distributions
6002 These commands take any number of arguments and investigate what is
6003 necessary to perform the action. If the argument is a distribution
6004 file name (recognized by embedded slashes), it is processed. If it is
6005 a module, CPAN determines the distribution file in which this module
6006 is included and processes that, following any dependencies named in
6007 the module's Makefile.PL (this behavior is controlled by
6008 I<prerequisites_policy>.)
6010 Any C<make> or C<test> are run unconditionally. An
6012 install <distribution_file>
6014 also is run unconditionally. But for
6018 CPAN checks if an install is actually needed for it and prints
6019 I<module up to date> in the case that the distribution file containing
6020 the module doesn't need to be updated.
6022 CPAN also keeps track of what it has done within the current session
6023 and doesn't try to build a package a second time regardless if it
6024 succeeded or not. The C<force> command takes as a first argument the
6025 method to invoke (currently: C<make>, C<test>, or C<install>) and executes the
6026 command from scratch.
6030 cpan> install OpenGL
6031 OpenGL is up to date.
6032 cpan> force install OpenGL
6035 OpenGL-0.4/COPYRIGHT
6038 A C<clean> command results in a
6042 being executed within the distribution file's working directory.
6044 =item get, readme, look module or distribution
6046 C<get> downloads a distribution file without further action. C<readme>
6047 displays the README file of the associated distribution. C<Look> gets
6048 and untars (if not yet done) the distribution file, changes to the
6049 appropriate directory and opens a subshell process in that directory.
6053 C<ls> lists all distribution files in and below an author's CPAN
6054 directory. Only those files that contain modules are listed and if
6055 there is more than one for any given module, only the most recent one
6060 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
6061 in the cpan-shell it is intended that you can press C<^C> anytime and
6062 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
6063 to clean up and leave the shell loop. You can emulate the effect of a
6064 SIGTERM by sending two consecutive SIGINTs, which usually means by
6065 pressing C<^C> twice.
6067 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
6068 SIGALRM is used during the run of the C<perl Makefile.PL> subprocess.
6074 The commands that are available in the shell interface are methods in
6075 the package CPAN::Shell. If you enter the shell command, all your
6076 input is split by the Text::ParseWords::shellwords() routine which
6077 acts like most shells do. The first word is being interpreted as the
6078 method to be called and the rest of the words are treated as arguments
6079 to this method. Continuation lines are supported if a line ends with a
6084 C<autobundle> writes a bundle file into the
6085 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
6086 a list of all modules that are both available from CPAN and currently
6087 installed within @INC. The name of the bundle file is based on the
6088 current date and a counter.
6092 recompile() is a very special command in that it takes no argument and
6093 runs the make/test/install cycle with brute force over all installed
6094 dynamically loadable extensions (aka XS modules) with 'force' in
6095 effect. The primary purpose of this command is to finish a network
6096 installation. Imagine, you have a common source tree for two different
6097 architectures. You decide to do a completely independent fresh
6098 installation. You start on one architecture with the help of a Bundle
6099 file produced earlier. CPAN installs the whole Bundle for you, but
6100 when you try to repeat the job on the second architecture, CPAN
6101 responds with a C<"Foo up to date"> message for all modules. So you
6102 invoke CPAN's recompile on the second architecture and you're done.
6104 Another popular use for C<recompile> is to act as a rescue in case your
6105 perl breaks binary compatibility. If one of the modules that CPAN uses
6106 is in turn depending on binary compatibility (so you cannot run CPAN
6107 commands), then you should try the CPAN::Nox module for recovery.
6109 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
6111 Although it may be considered internal, the class hierarchy does matter
6112 for both users and programmer. CPAN.pm deals with above mentioned four
6113 classes, and all those classes share a set of methods. A classical
6114 single polymorphism is in effect. A metaclass object registers all
6115 objects of all kinds and indexes them with a string. The strings
6116 referencing objects have a separated namespace (well, not completely
6121 words containing a "/" (slash) Distribution
6122 words starting with Bundle:: Bundle
6123 everything else Module or Author
6125 Modules know their associated Distribution objects. They always refer
6126 to the most recent official release. Developers may mark their releases
6127 as unstable development versions (by inserting an underbar into the
6128 module version number which will also be reflected in the distribution
6129 name when you run 'make dist'), so the really hottest and newest
6130 distribution is not always the default. If a module Foo circulates
6131 on CPAN in both version 1.23 and 1.23_90, CPAN.pm offers a convenient
6132 way to install version 1.23 by saying
6136 This would install the complete distribution file (say
6137 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
6138 like to install version 1.23_90, you need to know where the
6139 distribution file resides on CPAN relative to the authors/id/
6140 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
6141 so you would have to say
6143 install BAR/Foo-1.23_90.tar.gz
6145 The first example will be driven by an object of the class
6146 CPAN::Module, the second by an object of class CPAN::Distribution.
6148 =head2 Programmer's interface
6150 If you do not enter the shell, the available shell commands are both
6151 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
6152 functions in the calling package (C<install(...)>).
6154 There's currently only one class that has a stable interface -
6155 CPAN::Shell. All commands that are available in the CPAN shell are
6156 methods of the class CPAN::Shell. Each of the commands that produce
6157 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
6158 the IDs of all modules within the list.
6162 =item expand($type,@things)
6164 The IDs of all objects available within a program are strings that can
6165 be expanded to the corresponding real objects with the
6166 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
6167 list of CPAN::Module objects according to the C<@things> arguments
6168 given. In scalar context it only returns the first element of the
6171 =item expandany(@things)
6173 Like expand, but returns objects of the appropriate type, i.e.
6174 CPAN::Bundle objects for bundles, CPAN::Module objects for modules and
6175 CPAN::Distribution objects fro distributions.
6177 =item Programming Examples
6179 This enables the programmer to do operations that combine
6180 functionalities that are available in the shell.
6182 # install everything that is outdated on my disk:
6183 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
6185 # install my favorite programs if necessary:
6186 for $mod (qw(Net::FTP Digest::MD5 Data::Dumper)){
6187 my $obj = CPAN::Shell->expand('Module',$mod);
6191 # list all modules on my disk that have no VERSION number
6192 for $mod (CPAN::Shell->expand("Module","/./")){
6193 next unless $mod->inst_file;
6194 # MakeMaker convention for undefined $VERSION:
6195 next unless $mod->inst_version eq "undef";
6196 print "No VERSION in ", $mod->id, "\n";
6199 # find out which distribution on CPAN contains a module:
6200 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
6202 Or if you want to write a cronjob to watch The CPAN, you could list
6203 all modules that need updating. First a quick and dirty way:
6205 perl -e 'use CPAN; CPAN::Shell->r;'
6207 If you don't want to get any output in the case that all modules are
6208 up to date, you can parse the output of above command for the regular
6209 expression //modules are up to date// and decide to mail the output
6210 only if it doesn't match. Ick?
6212 If you prefer to do it more in a programmer style in one single
6213 process, maybe something like this suits you better:
6215 # list all modules on my disk that have newer versions on CPAN
6216 for $mod (CPAN::Shell->expand("Module","/./")){
6217 next unless $mod->inst_file;
6218 next if $mod->uptodate;
6219 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
6220 $mod->id, $mod->inst_version, $mod->cpan_version;
6223 If that gives you too much output every day, you maybe only want to
6224 watch for three modules. You can write
6226 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")){
6228 as the first line instead. Or you can combine some of the above
6231 # watch only for a new mod_perl module
6232 $mod = CPAN::Shell->expand("Module","mod_perl");
6233 exit if $mod->uptodate;
6234 # new mod_perl arrived, let me know all update recommendations
6239 =head2 Methods in the other Classes
6241 The programming interface for the classes CPAN::Module,
6242 CPAN::Distribution, CPAN::Bundle, and CPAN::Author is still considered
6243 beta and partially even alpha. In the following paragraphs only those
6244 methods are documented that have proven useful over a longer time and
6245 thus are unlikely to change.
6249 =item CPAN::Author::as_glimpse()
6251 Returns a one-line description of the author
6253 =item CPAN::Author::as_string()
6255 Returns a multi-line description of the author
6257 =item CPAN::Author::email()
6259 Returns the author's email address
6261 =item CPAN::Author::fullname()
6263 Returns the author's name
6265 =item CPAN::Author::name()
6267 An alias for fullname
6269 =item CPAN::Bundle::as_glimpse()
6271 Returns a one-line description of the bundle
6273 =item CPAN::Bundle::as_string()
6275 Returns a multi-line description of the bundle
6277 =item CPAN::Bundle::clean()
6279 Recursively runs the C<clean> method on all items contained in the bundle.
6281 =item CPAN::Bundle::contains()
6283 Returns a list of objects' IDs contained in a bundle. The associated
6284 objects may be bundles, modules or distributions.
6286 =item CPAN::Bundle::force($method,@args)
6288 Forces CPAN to perform a task that normally would have failed. Force
6289 takes as arguments a method name to be called and any number of
6290 additional arguments that should be passed to the called method. The
6291 internals of the object get the needed changes so that CPAN.pm does
6292 not refuse to take the action. The C<force> is passed recursively to
6293 all contained objects.
6295 =item CPAN::Bundle::get()
6297 Recursively runs the C<get> method on all items contained in the bundle
6299 =item CPAN::Bundle::inst_file()
6301 Returns the highest installed version of the bundle in either @INC or
6302 C<$CPAN::Config->{cpan_home}>. Note that this is different from
6303 CPAN::Module::inst_file.
6305 =item CPAN::Bundle::inst_version()
6307 Like CPAN::Bundle::inst_file, but returns the $VERSION
6309 =item CPAN::Bundle::uptodate()
6311 Returns 1 if the bundle itself and all its members are uptodate.
6313 =item CPAN::Bundle::install()
6315 Recursively runs the C<install> method on all items contained in the bundle
6317 =item CPAN::Bundle::make()
6319 Recursively runs the C<make> method on all items contained in the bundle
6321 =item CPAN::Bundle::readme()
6323 Recursively runs the C<readme> method on all items contained in the bundle
6325 =item CPAN::Bundle::test()
6327 Recursively runs the C<test> method on all items contained in the bundle
6329 =item CPAN::Distribution::as_glimpse()
6331 Returns a one-line description of the distribution
6333 =item CPAN::Distribution::as_string()
6335 Returns a multi-line description of the distribution
6337 =item CPAN::Distribution::clean()
6339 Changes to the directory where the distribution has been unpacked and
6340 runs C<make clean> there.
6342 =item CPAN::Distribution::containsmods()
6344 Returns a list of IDs of modules contained in a distribution file.
6345 Only works for distributions listed in the 02packages.details.txt.gz
6346 file. This typically means that only the most recent version of a
6347 distribution is covered.
6349 =item CPAN::Distribution::cvs_import()
6351 Changes to the directory where the distribution has been unpacked and
6354 cvs -d $cvs_root import -m $cvs_log $cvs_dir $userid v$version
6358 =item CPAN::Distribution::dir()
6360 Returns the directory into which this distribution has been unpacked.
6362 =item CPAN::Distribution::force($method,@args)
6364 Forces CPAN to perform a task that normally would have failed. Force
6365 takes as arguments a method name to be called and any number of
6366 additional arguments that should be passed to the called method. The
6367 internals of the object get the needed changes so that CPAN.pm does
6368 not refuse to take the action.
6370 =item CPAN::Distribution::get()
6372 Downloads the distribution from CPAN and unpacks it. Does nothing if
6373 the distribution has already been downloaded and unpacked within the
6376 =item CPAN::Distribution::install()
6378 Changes to the directory where the distribution has been unpacked and
6379 runs the external command C<make install> there. If C<make> has not
6380 yet been run, it will be run first. A C<make test> will be issued in
6381 any case and if this fails, the install will be canceled. The
6382 cancellation can be avoided by letting C<force> run the C<install> for
6385 =item CPAN::Distribution::isa_perl()
6387 Returns 1 if this distribution file seems to be a perl distribution.
6388 Normally this is derived from the file name only, but the index from
6389 CPAN can contain a hint to achieve a return value of true for other
6392 =item CPAN::Distribution::look()
6394 Changes to the directory where the distribution has been unpacked and
6395 opens a subshell there. Exiting the subshell returns.
6397 =item CPAN::Distribution::make()
6399 First runs the C<get> method to make sure the distribution is
6400 downloaded and unpacked. Changes to the directory where the
6401 distribution has been unpacked and runs the external commands C<perl
6402 Makefile.PL> and C<make> there.
6404 =item CPAN::Distribution::prereq_pm()
6406 Returns the hash reference that has been announced by a distribution
6407 as the PREREQ_PM hash in the Makefile.PL. Note: works only after an
6408 attempt has been made to C<make> the distribution. Returns undef
6411 =item CPAN::Distribution::readme()
6413 Downloads the README file associated with a distribution and runs it
6414 through the pager specified in C<$CPAN::Config->{pager}>.
6416 =item CPAN::Distribution::test()
6418 Changes to the directory where the distribution has been unpacked and
6419 runs C<make test> there.
6421 =item CPAN::Distribution::uptodate()
6423 Returns 1 if all the modules contained in the distribution are
6424 uptodate. Relies on containsmods.
6426 =item CPAN::Index::force_reload()
6428 Forces a reload of all indices.
6430 =item CPAN::Index::reload()
6432 Reloads all indices if they have been read more than
6433 C<$CPAN::Config->{index_expire}> days.
6435 =item CPAN::InfoObj::dump()
6437 CPAN::Author, CPAN::Bundle, CPAN::Module, and CPAN::Distribution
6438 inherit this method. It prints the data structure associated with an
6439 object. Useful for debugging. Note: the data structure is considered
6440 internal and thus subject to change without notice.
6442 =item CPAN::Module::as_glimpse()
6444 Returns a one-line description of the module
6446 =item CPAN::Module::as_string()
6448 Returns a multi-line description of the module
6450 =item CPAN::Module::clean()
6452 Runs a clean on the distribution associated with this module.
6454 =item CPAN::Module::cpan_file()
6456 Returns the filename on CPAN that is associated with the module.
6458 =item CPAN::Module::cpan_version()
6460 Returns the latest version of this module available on CPAN.
6462 =item CPAN::Module::cvs_import()
6464 Runs a cvs_import on the distribution associated with this module.
6466 =item CPAN::Module::description()
6468 Returns a 44 character description of this module. Only available for
6469 modules listed in The Module List (CPAN/modules/00modlist.long.html
6470 or 00modlist.long.txt.gz)
6472 =item CPAN::Module::force($method,@args)
6474 Forces CPAN to perform a task that normally would have failed. Force
6475 takes as arguments a method name to be called and any number of
6476 additional arguments that should be passed to the called method. The
6477 internals of the object get the needed changes so that CPAN.pm does
6478 not refuse to take the action.
6480 =item CPAN::Module::get()
6482 Runs a get on the distribution associated with this module.
6484 =item CPAN::Module::inst_file()
6486 Returns the filename of the module found in @INC. The first file found
6487 is reported just like perl itself stops searching @INC when it finds a
6490 =item CPAN::Module::inst_version()
6492 Returns the version number of the module in readable format.
6494 =item CPAN::Module::install()
6496 Runs an C<install> on the distribution associated with this module.
6498 =item CPAN::Module::look()
6500 Changes to the directory where the distribution associated with this
6501 module has been unpacked and opens a subshell there. Exiting the
6504 =item CPAN::Module::make()
6506 Runs a C<make> on the distribution associated with this module.
6508 =item CPAN::Module::manpage_headline()
6510 If module is installed, peeks into the module's manpage, reads the
6511 headline and returns it. Moreover, if the module has been downloaded
6512 within this session, does the equivalent on the downloaded module even
6513 if it is not installed.
6515 =item CPAN::Module::readme()
6517 Runs a C<readme> on the distribution associated with this module.
6519 =item CPAN::Module::test()
6521 Runs a C<test> on the distribution associated with this module.
6523 =item CPAN::Module::uptodate()
6525 Returns 1 if the module is installed and up-to-date.
6527 =item CPAN::Module::userid()
6529 Returns the author's ID of the module.
6533 =head2 Cache Manager
6535 Currently the cache manager only keeps track of the build directory
6536 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
6537 deletes complete directories below C<build_dir> as soon as the size of
6538 all directories there gets bigger than $CPAN::Config->{build_cache}
6539 (in MB). The contents of this cache may be used for later
6540 re-installations that you intend to do manually, but will never be
6541 trusted by CPAN itself. This is due to the fact that the user might
6542 use these directories for building modules on different architectures.
6544 There is another directory ($CPAN::Config->{keep_source_where}) where
6545 the original distribution files are kept. This directory is not
6546 covered by the cache manager and must be controlled by the user. If
6547 you choose to have the same directory as build_dir and as
6548 keep_source_where directory, then your sources will be deleted with
6549 the same fifo mechanism.
6553 A bundle is just a perl module in the namespace Bundle:: that does not
6554 define any functions or methods. It usually only contains documentation.
6556 It starts like a perl module with a package declaration and a $VERSION
6557 variable. After that the pod section looks like any other pod with the
6558 only difference being that I<one special pod section> exists starting with
6563 In this pod section each line obeys the format
6565 Module_Name [Version_String] [- optional text]
6567 The only required part is the first field, the name of a module
6568 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
6569 of the line is optional. The comment part is delimited by a dash just
6570 as in the man page header.
6572 The distribution of a bundle should follow the same convention as
6573 other distributions.
6575 Bundles are treated specially in the CPAN package. If you say 'install
6576 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
6577 the modules in the CONTENTS section of the pod. You can install your
6578 own Bundles locally by placing a conformant Bundle file somewhere into
6579 your @INC path. The autobundle() command which is available in the
6580 shell interface does that for you by including all currently installed
6581 modules in a snapshot bundle file.
6583 =head2 Prerequisites
6585 If you have a local mirror of CPAN and can access all files with
6586 "file:" URLs, then you only need a perl better than perl5.003 to run
6587 this module. Otherwise Net::FTP is strongly recommended. LWP may be
6588 required for non-UNIX systems or if your nearest CPAN site is
6589 associated with a URL that is not C<ftp:>.
6591 If you have neither Net::FTP nor LWP, there is a fallback mechanism
6592 implemented for an external ftp command or for an external lynx
6595 =head2 Finding packages and VERSION
6597 This module presumes that all packages on CPAN
6603 declare their $VERSION variable in an easy to parse manner. This
6604 prerequisite can hardly be relaxed because it consumes far too much
6605 memory to load all packages into the running program just to determine
6606 the $VERSION variable. Currently all programs that are dealing with
6607 version use something like this
6609 perl -MExtUtils::MakeMaker -le \
6610 'print MM->parse_version(shift)' filename
6612 If you are author of a package and wonder if your $VERSION can be
6613 parsed, please try the above method.
6617 come as compressed or gzipped tarfiles or as zip files and contain a
6618 Makefile.PL (well, we try to handle a bit more, but without much
6625 The debugging of this module is a bit complex, because we have
6626 interferences of the software producing the indices on CPAN, of the
6627 mirroring process on CPAN, of packaging, of configuration, of
6628 synchronicity, and of bugs within CPAN.pm.
6630 For code debugging in interactive mode you can try "o debug" which
6631 will list options for debugging the various parts of the code. You
6632 should know that "o debug" has built-in completion support.
6634 For data debugging there is the C<dump> command which takes the same
6635 arguments as make/test/install and outputs the object's Data::Dumper
6638 =head2 Floppy, Zip, Offline Mode
6640 CPAN.pm works nicely without network too. If you maintain machines
6641 that are not networked at all, you should consider working with file:
6642 URLs. Of course, you have to collect your modules somewhere first. So
6643 you might use CPAN.pm to put together all you need on a networked
6644 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
6645 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
6646 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
6647 with this floppy. See also below the paragraph about CD-ROM support.
6649 =head1 CONFIGURATION
6651 When the CPAN module is installed, a site wide configuration file is
6652 created as CPAN/Config.pm. The default values defined there can be
6653 overridden in another configuration file: CPAN/MyConfig.pm. You can
6654 store this file in $HOME/.cpan/CPAN/MyConfig.pm if you want, because
6655 $HOME/.cpan is added to the search path of the CPAN module before the
6656 use() or require() statements.
6658 Currently the following keys in the hash reference $CPAN::Config are
6661 build_cache size of cache for directories to build modules
6662 build_dir locally accessible directory to build modules
6663 index_expire after this many days refetch index files
6664 cache_metadata use serializer to cache metadata
6665 cpan_home local directory reserved for this package
6666 dontload_hash anonymous hash: modules in the keys will not be
6667 loaded by the CPAN::has_inst() routine
6668 gzip location of external program gzip
6669 inactivity_timeout breaks interactive Makefile.PLs after this
6670 many seconds inactivity. Set to 0 to never break.
6671 inhibit_startup_message
6672 if true, does not print the startup message
6673 keep_source_where directory in which to keep the source (if we do)
6674 make location of external make program
6675 make_arg arguments that should always be passed to 'make'
6676 make_install_arg same as make_arg for 'make install'
6677 makepl_arg arguments passed to 'perl Makefile.PL'
6678 pager location of external program more (or any pager)
6679 prerequisites_policy
6680 what to do if you are missing module prerequisites
6681 ('follow' automatically, 'ask' me, or 'ignore')
6682 proxy_user username for accessing an authenticating proxy
6683 proxy_pass password for accessing an authenticating proxy
6684 scan_cache controls scanning of cache ('atstart' or 'never')
6685 tar location of external program tar
6686 term_is_latin if true internal UTF-8 is translated to ISO-8859-1
6687 (and nonsense for characters outside latin range)
6688 unzip location of external program unzip
6689 urllist arrayref to nearby CPAN sites (or equivalent locations)
6690 wait_list arrayref to a wait server to try (See CPAN::WAIT)
6691 ftp_proxy, } the three usual variables for configuring
6692 http_proxy, } proxy requests. Both as CPAN::Config variables
6693 no_proxy } and as environment variables configurable.
6695 You can set and query each of these options interactively in the cpan
6696 shell with the command set defined within the C<o conf> command:
6700 =item C<o conf E<lt>scalar optionE<gt>>
6702 prints the current value of the I<scalar option>
6704 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
6706 Sets the value of the I<scalar option> to I<value>
6708 =item C<o conf E<lt>list optionE<gt>>
6710 prints the current value of the I<list option> in MakeMaker's
6713 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
6715 shifts or pops the array in the I<list option> variable
6717 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
6719 works like the corresponding perl commands.
6723 =head2 Note on urllist parameter's format
6725 urllist parameters are URLs according to RFC 1738. We do a little
6726 guessing if your URL is not compliant, but if you have problems with
6727 file URLs, please try the correct format. Either:
6729 file://localhost/whatever/ftp/pub/CPAN/
6733 file:///home/ftp/pub/CPAN/
6735 =head2 urllist parameter has CD-ROM support
6737 The C<urllist> parameter of the configuration table contains a list of
6738 URLs that are to be used for downloading. If the list contains any
6739 C<file> URLs, CPAN always tries to get files from there first. This
6740 feature is disabled for index files. So the recommendation for the
6741 owner of a CD-ROM with CPAN contents is: include your local, possibly
6742 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
6744 o conf urllist push file://localhost/CDROM/CPAN
6746 CPAN.pm will then fetch the index files from one of the CPAN sites
6747 that come at the beginning of urllist. It will later check for each
6748 module if there is a local copy of the most recent version.
6750 Another peculiarity of urllist is that the site that we could
6751 successfully fetch the last file from automatically gets a preference
6752 token and is tried as the first site for the next request. So if you
6753 add a new site at runtime it may happen that the previously preferred
6754 site will be tried another time. This means that if you want to disallow
6755 a site for the next transfer, it must be explicitly removed from
6760 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
6761 install foreign, unmasked, unsigned code on your machine. We compare
6762 to a checksum that comes from the net just as the distribution file
6763 itself. If somebody has managed to tamper with the distribution file,
6764 they may have as well tampered with the CHECKSUMS file. Future
6765 development will go towards strong authentication.
6769 Most functions in package CPAN are exported per default. The reason
6770 for this is that the primary use is intended for the cpan shell or for
6773 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
6775 Populating a freshly installed perl with my favorite modules is pretty
6776 easy if you maintain a private bundle definition file. To get a useful
6777 blueprint of a bundle definition file, the command autobundle can be used
6778 on the CPAN shell command line. This command writes a bundle definition
6779 file for all modules that are installed for the currently running perl
6780 interpreter. It's recommended to run this command only once and from then
6781 on maintain the file manually under a private name, say
6782 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
6784 cpan> install Bundle::my_bundle
6786 then answer a few questions and then go out for a coffee.
6788 Maintaining a bundle definition file means keeping track of two
6789 things: dependencies and interactivity. CPAN.pm sometimes fails on
6790 calculating dependencies because not all modules define all MakeMaker
6791 attributes correctly, so a bundle definition file should specify
6792 prerequisites as early as possible. On the other hand, it's a bit
6793 annoying that many distributions need some interactive configuring. So
6794 what I try to accomplish in my private bundle file is to have the
6795 packages that need to be configured early in the file and the gentle
6796 ones later, so I can go out after a few minutes and leave CPAN.pm
6799 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
6801 Thanks to Graham Barr for contributing the following paragraphs about
6802 the interaction between perl, and various firewall configurations. For
6803 further informations on firewalls, it is recommended to consult the
6804 documentation that comes with the ncftp program. If you are unable to
6805 go through the firewall with a simple Perl setup, it is very likely
6806 that you can configure ncftp so that it works for your firewall.
6808 =head2 Three basic types of firewalls
6810 Firewalls can be categorized into three basic types.
6816 This is where the firewall machine runs a web server and to access the
6817 outside world you must do it via the web server. If you set environment
6818 variables like http_proxy or ftp_proxy to a values beginning with http://
6819 or in your web browser you have to set proxy information then you know
6820 you are running an http firewall.
6822 To access servers outside these types of firewalls with perl (even for
6823 ftp) you will need to use LWP.
6827 This where the firewall machine runs an ftp server. This kind of
6828 firewall will only let you access ftp servers outside the firewall.
6829 This is usually done by connecting to the firewall with ftp, then
6830 entering a username like "user@outside.host.com"
6832 To access servers outside these type of firewalls with perl you
6833 will need to use Net::FTP.
6835 =item One way visibility
6837 I say one way visibility as these firewalls try to make themselves look
6838 invisible to the users inside the firewall. An FTP data connection is
6839 normally created by sending the remote server your IP address and then
6840 listening for the connection. But the remote server will not be able to
6841 connect to you because of the firewall. So for these types of firewall
6842 FTP connections need to be done in a passive mode.
6844 There are two that I can think off.
6850 If you are using a SOCKS firewall you will need to compile perl and link
6851 it with the SOCKS library, this is what is normally called a 'socksified'
6852 perl. With this executable you will be able to connect to servers outside
6853 the firewall as if it is not there.
6857 This is the firewall implemented in the Linux kernel, it allows you to
6858 hide a complete network behind one IP address. With this firewall no
6859 special compiling is needed as you can access hosts directly.
6865 =head2 Configuring lynx or ncftp for going through a firewall
6867 If you can go through your firewall with e.g. lynx, presumably with a
6870 /usr/local/bin/lynx -pscott:tiger
6872 then you would configure CPAN.pm with the command
6874 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
6876 That's all. Similarly for ncftp or ftp, you would configure something
6879 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
6881 Your mileage may vary...
6889 I installed a new version of module X but CPAN keeps saying,
6890 I have the old version installed
6892 Most probably you B<do> have the old version installed. This can
6893 happen if a module installs itself into a different directory in the
6894 @INC path than it was previously installed. This is not really a
6895 CPAN.pm problem, you would have the same problem when installing the
6896 module manually. The easiest way to prevent this behaviour is to add
6897 the argument C<UNINST=1> to the C<make install> call, and that is why
6898 many people add this argument permanently by configuring
6900 o conf make_install_arg UNINST=1
6904 So why is UNINST=1 not the default?
6906 Because there are people who have their precise expectations about who
6907 may install where in the @INC path and who uses which @INC array. In
6908 fine tuned environments C<UNINST=1> can cause damage.
6912 I want to clean up my mess, and install a new perl along with
6913 all modules I have. How do I go about it?
6915 Run the autobundle command for your old perl and optionally rename the
6916 resulting bundle file (e.g. Bundle/mybundle.pm), install the new perl
6917 with the Configure option prefix, e.g.
6919 ./Configure -Dprefix=/usr/local/perl-5.6.78.9
6921 Install the bundle file you produced in the first step with something like
6923 cpan> install Bundle::mybundle
6929 When I install bundles or multiple modules with one command
6930 there is too much output to keep track of.
6932 You may want to configure something like
6934 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
6935 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
6937 so that STDOUT is captured in a file for later inspection.
6942 I am not root, how can I install a module in a personal directory?
6944 You will most probably like something like this:
6946 o conf makepl_arg "LIB=~/myperl/lib \
6947 INSTALLMAN1DIR=~/myperl/man/man1 \
6948 INSTALLMAN3DIR=~/myperl/man/man3"
6949 install Sybase::Sybperl
6951 You can make this setting permanent like all C<o conf> settings with
6954 You will have to add ~/myperl/man to the MANPATH environment variable
6955 and also tell your perl programs to look into ~/myperl/lib, e.g. by
6958 use lib "$ENV{HOME}/myperl/lib";
6960 or setting the PERL5LIB environment variable.
6962 Another thing you should bear in mind is that the UNINST parameter
6963 should never be set if you are not root.
6967 How to get a package, unwrap it, and make a change before building it?
6969 look Sybase::Sybperl
6973 I installed a Bundle and had a couple of fails. When I
6974 retried, everything resolved nicely. Can this be fixed to work
6977 The reason for this is that CPAN does not know the dependencies of all
6978 modules when it starts out. To decide about the additional items to
6979 install, it just uses data found in the generated Makefile. An
6980 undetected missing piece breaks the process. But it may well be that
6981 your Bundle installs some prerequisite later than some depending item
6982 and thus your second try is able to resolve everything. Please note,
6983 CPAN.pm does not know the dependency tree in advance and cannot sort
6984 the queue of things to install in a topologically correct order. It
6985 resolves perfectly well IFF all modules declare the prerequisites
6986 correctly with the PREREQ_PM attribute to MakeMaker. For bundles which
6987 fail and you need to install often, it is recommended sort the Bundle
6988 definition file manually. It is planned to improve the metadata
6989 situation for dependencies on CPAN in general, but this will still
6994 In our intranet we have many modules for internal use. How
6995 can I integrate these modules with CPAN.pm but without uploading
6996 the modules to CPAN?
6998 Have a look at the CPAN::Site module.
7002 When I run CPAN's shell, I get error msg about line 1 to 4,
7003 setting meta input/output via the /etc/inputrc file.
7005 Some versions of readline are picky about capitalization in the
7006 /etc/inputrc file and specifically RedHat 6.2 comes with a
7007 /etc/inputrc that contains the word C<on> in lowercase. Change the
7008 occurrences of C<on> to C<On> and the bug should disappear.
7012 Some authors have strange characters in their names.
7014 Internally CPAN.pm uses the UTF-8 charset. If your terminal is
7015 expecting ISO-8859-1 charset, a converter can be activated by setting
7016 term_is_latin to a true value in your config file. One way of doing so
7019 cpan> ! $CPAN::Config->{term_is_latin}=1
7021 Extended support for converters will be made available as soon as perl
7022 becomes stable with regard to charset issues.
7028 We should give coverage for B<all> of the CPAN and not just the PAUSE
7029 part, right? In this discussion CPAN and PAUSE have become equal --
7030 but they are not. PAUSE is authors/, modules/ and scripts/. CPAN is
7031 PAUSE plus the clpa/, doc/, misc/, ports/, and src/.
7033 Future development should be directed towards a better integration of
7036 If a Makefile.PL requires special customization of libraries, prompts
7037 the user for special input, etc. then you may find CPAN is not able to
7038 build the distribution. In that case, you should attempt the
7039 traditional method of building a Perl module package from a shell.
7043 Andreas Koenig E<lt>andreas.koenig@anima.deE<gt>
7047 Kawai,Takanori provides a Japanese translation of this manpage at
7048 http://member.nifty.ne.jp/hippo2000/perltips/CPAN.htm
7052 perl(1), CPAN::Nox(3)