1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
5 # $Id: CPAN.pm,v 1.351 2000/09/10 08:02:42 k Exp $
7 # only used during development:
9 # $Revision = "[".substr(q$Revision: 1.351 $, 10)."]";
16 use ExtUtils::MakeMaker (); # $SelfLoader::DEBUG=1;
17 use File::Basename ();
23 use Text::ParseWords ();
26 no lib "."; # we need to run chdir all over and we would get at wrong
29 END { $End++; &cleanup; }
52 $CPAN::Frontend ||= "CPAN::Shell";
53 $CPAN::Defaultsite ||= "ftp://ftp.perl.org/pub/CPAN";
58 use vars qw($VERSION @EXPORT $AUTOLOAD $DEBUG $META $HAS_USABLE $term
59 $Revision $Signal $Cwd $End $Suppress_readline $Frontend
62 @CPAN::ISA = qw(CPAN::Debug Exporter);
65 autobundle bundle expand force get cvs_import
66 install make readme recompile shell test clean
69 #-> sub CPAN::AUTOLOAD ;
74 @EXPORT{@EXPORT} = '';
75 CPAN::Config->load unless $CPAN::Config_loaded++;
76 if (exists $EXPORT{$l}){
79 $CPAN::Frontend->mywarn(qq{Unknown command "$AUTOLOAD". }.
88 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
89 CPAN::Config->load unless $CPAN::Config_loaded++;
91 CPAN::Index->read_metadata_cache;
93 my $prompt = "cpan> ";
95 unless ($Suppress_readline) {
96 require Term::ReadLine;
97 # import Term::ReadLine;
98 $term = Term::ReadLine->new('CPAN Monitor');
99 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
100 my $attribs = $term->Attribs;
101 # $attribs->{completion_entry_function} =
102 # $attribs->{'list_completion_function'};
103 $attribs->{attempted_completion_function} = sub {
104 &CPAN::Complete::gnu_cpl;
106 # $attribs->{completion_word} =
107 # [qw(help me somebody to find out how
108 # to use completion with GNU)];
110 $readline::rl_completion_function =
111 $readline::rl_completion_function = 'CPAN::Complete::cpl';
113 # $term->OUT is autoflushed anyway
114 my $odef = select STDERR;
121 # no strict; # I do not recall why no strict was here (2000-09-03)
124 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
125 my $cwd = CPAN->$getcwd();
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) = "";
145 if ($Suppress_readline) {
147 last unless defined ($_ = <> );
150 last unless defined ($_ = $term->readline($prompt));
152 $_ = "$continuation$_" if $continuation;
155 $_ = 'h' if /^\s*\?/;
156 if (/^(?:q(?:uit)?|bye|exit)$/i) {
166 use vars qw($import_done);
167 CPAN->import(':DEFAULT') unless $import_done++;
168 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
175 if ($] < 5.00322) { # parsewords had a bug until recently
178 eval { @line = Text::ParseWords::shellwords($_) };
179 warn($@), next if $@;
181 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
182 my $command = shift @line;
183 eval { CPAN::Shell->$command(@line) };
185 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
186 $CPAN::Frontend->myprint("\n");
192 CPAN::Queue->nullify_queue;
193 if ($try_detect_readline) {
194 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
196 $CPAN::META->has_inst("Term::ReadLine::Perl")
198 delete $INC{"Term/ReadLine.pm"};
200 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
201 require Term::ReadLine;
202 $CPAN::Frontend->myprint("\n$redef subroutines in ".
203 "Term::ReadLine redefined\n");
210 package CPAN::CacheMgr;
211 @CPAN::CacheMgr::ISA = qw(CPAN::InfoObj CPAN);
214 package CPAN::Config;
215 use vars qw(%can $dot_cpan);
218 'commit' => "Commit changes to disk",
219 'defaults' => "Reload defaults from disk",
220 'init' => "Interactive setting of all options",
224 use vars qw($Ua $Thesite $Themethod);
225 @CPAN::FTP::ISA = qw(CPAN::Debug);
227 package CPAN::Complete;
228 @CPAN::Complete::ISA = qw(CPAN::Debug);
231 use vars qw($last_time $date_of_03);
232 @CPAN::Index::ISA = qw(CPAN::Debug);
235 # use constant PROTOCOL => "2.0"; # outcommented to avoid warning on upgrade from 1.57
238 package CPAN::InfoObj;
239 @CPAN::InfoObj::ISA = qw(CPAN::Debug);
241 package CPAN::Author;
242 @CPAN::Author::ISA = qw(CPAN::InfoObj);
244 package CPAN::Distribution;
245 @CPAN::Distribution::ISA = qw(CPAN::InfoObj);
247 package CPAN::Bundle;
248 @CPAN::Bundle::ISA = qw(CPAN::Module);
250 package CPAN::Module;
251 @CPAN::Module::ISA = qw(CPAN::InfoObj);
254 use vars qw($AUTOLOAD @ISA);
255 @CPAN::Shell::ISA = qw(CPAN::Debug);
257 #-> sub CPAN::Shell::AUTOLOAD ;
259 my($autoload) = $AUTOLOAD;
260 my $class = shift(@_);
261 # warn "autoload[$autoload] class[$class]";
262 $autoload =~ s/.*:://;
263 if ($autoload =~ /^w/) {
264 if ($CPAN::META->has_inst('CPAN::WAIT')) {
265 CPAN::WAIT->$autoload(@_);
267 $CPAN::Frontend->mywarn(qq{
268 Commands starting with "w" require CPAN::WAIT to be installed.
269 Please consider installing CPAN::WAIT to use the fulltext index.
270 For this you just need to type
275 $CPAN::Frontend->mywarn(qq{Unknown command '$autoload'. }.
281 package CPAN::Tarzip;
282 use vars qw($AUTOLOAD @ISA);
283 @CPAN::Tarzip::ISA = qw(CPAN::Debug);
287 # One use of the queue is to determine if we should or shouldn't
288 # announce the availability of a new CPAN module
290 # Now we try to use it for dependency tracking. For that to happen
291 # we need to draw a dependency tree and do the leaves first. This can
292 # easily be reached by running CPAN.pm recursively, but we don't want
293 # to waste memory and run into deep recursion. So what we can do is
296 # CPAN::Queue is the package where the queue is maintained. Dependencies
297 # often have high priority and must be brought to the head of the queue,
298 # possibly by jumping the queue if they are already there. My first code
299 # attempt tried to be extremely correct. Whenever a module needed
300 # immediate treatment, I either unshifted it to the front of the queue,
301 # or, if it was already in the queue, I spliced and let it bypass the
302 # others. This became a too correct model that made it impossible to put
303 # an item more than once into the queue. Why would you need that? Well,
304 # you need temporary duplicates as the manager of the queue is a loop
307 # (1) looks at the first item in the queue without shifting it off
309 # (2) cares for the item
311 # (3) removes the item from the queue, *even if its agenda failed and
312 # even if the item isn't the first in the queue anymore* (that way
313 # protecting against never ending queues)
315 # So if an item has prerequisites, the installation fails now, but we
316 # want to retry later. That's easy if we have it twice in the queue.
318 # I also expect insane dependency situations where an item gets more
319 # than two lives in the queue. Simplest example is triggered by 'install
320 # Foo Foo Foo'. People make this kind of mistakes and I don't want to
321 # get in the way. I wanted the queue manager to be a dumb servant, not
322 # one that knows everything.
324 # Who would I tell in this model that the user wants to be asked before
325 # processing? I can't attach that information to the module object,
326 # because not modules are installed but distributions. So I'd have to
327 # tell the distribution object that it should ask the user before
328 # processing. Where would the question be triggered then? Most probably
329 # in CPAN::Distribution::rematein.
330 # Hope that makes sense, my head is a bit off:-) -- AK
337 my $self = bless { qmod => $s }, $class;
342 # CPAN::Queue::first ;
348 # CPAN::Queue::delete_first ;
350 my($class,$what) = @_;
352 for my $i (0..$#All) {
353 if ( $All[$i]->{qmod} eq $what ) {
360 # CPAN::Queue::jumpqueue ;
364 CPAN->debug(sprintf("before jumpqueue All[%s] what[%s]",
365 join(",",map {$_->{qmod}} @All),
368 WHAT: for my $what (reverse @what) {
370 for (my $i=0; $i<$#All;$i++) { #prevent deep recursion
371 CPAN->debug("i[$All[$i]]what[$what]") if $CPAN::DEBUG;
372 if ($All[$i]->{qmod} eq $what){
374 if ($jumped > 100) { # one's OK if e.g. just
375 # processing now; more are OK if
376 # user typed it several times
377 $CPAN::Frontend->mywarn(
378 qq{Object [$what] queued more than 100 times, ignoring}
384 my $obj = bless { qmod => $what }, $class;
387 CPAN->debug(sprintf("after jumpqueue All[%s] what[%s]",
388 join(",",map {$_->{qmod}} @All),
393 # CPAN::Queue::exists ;
395 my($self,$what) = @_;
396 my @all = map { $_->{qmod} } @All;
397 my $exists = grep { $_->{qmod} eq $what } @All;
398 # warn "in exists what[$what] all[@all] exists[$exists]";
402 # CPAN::Queue::delete ;
405 @All = grep { $_->{qmod} ne $mod } @All;
408 # CPAN::Queue::nullify_queue ;
417 $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
419 # from here on only subs.
420 ################################################################################
422 #-> sub CPAN::all_objects ;
424 my($mgr,$class) = @_;
425 CPAN::Config->load unless $CPAN::Config_loaded++;
426 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
428 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
430 *all = \&all_objects;
432 # Called by shell, not in batch mode. In batch mode I see no risk in
433 # having many processes updating something as installations are
434 # continually checked at runtime. In shell mode I suspect it is
435 # unintentional to open more than one shell at a time
437 #-> sub CPAN::checklock ;
440 my $lockfile = MM->catfile($CPAN::Config->{cpan_home},".lock");
441 if (-f $lockfile && -M _ > 0) {
442 my $fh = FileHandle->new($lockfile) or
443 $CPAN::Frontend->mydie("Could not open $lockfile: $!");
446 if (defined $other && $other) {
448 return if $$==$other; # should never happen
449 $CPAN::Frontend->mywarn(
451 There seems to be running another CPAN process ($other). Contacting...
453 if (kill 0, $other) {
454 $CPAN::Frontend->mydie(qq{Other job is running.
455 You may want to kill it and delete the lockfile, maybe. On UNIX try:
459 } elsif (-w $lockfile) {
461 ExtUtils::MakeMaker::prompt
462 (qq{Other job not responding. Shall I overwrite }.
463 qq{the lockfile? (Y/N)},"y");
464 $CPAN::Frontend->myexit("Ok, bye\n")
465 unless $ans =~ /^y/i;
468 qq{Lockfile $lockfile not writeable by you. }.
469 qq{Cannot proceed.\n}.
472 qq{ and then rerun us.\n}
476 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile $lockfile ".
477 "reports other process with ID ".
478 "$other. Cannot proceed.\n"));
481 my $dotcpan = $CPAN::Config->{cpan_home};
482 eval { File::Path::mkpath($dotcpan);};
484 # A special case at least for Jarkko.
489 $symlinkcpan = readlink $dotcpan;
490 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
491 eval { File::Path::mkpath($symlinkcpan); };
495 $CPAN::Frontend->mywarn(qq{
496 Working directory $symlinkcpan created.
500 unless (-d $dotcpan) {
502 Your configuration suggests "$dotcpan" as your
503 CPAN.pm working directory. I could not create this directory due
504 to this error: $firsterror\n};
506 As "$dotcpan" is a symlink to "$symlinkcpan",
507 I tried to create that, but I failed with this error: $seconderror
510 Please make sure the directory exists and is writable.
512 $CPAN::Frontend->mydie($diemess);
516 unless ($fh = FileHandle->new(">$lockfile")) {
517 if ($! =~ /Permission/) {
518 my $incc = $INC{'CPAN/Config.pm'};
519 my $myincc = MM->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
520 $CPAN::Frontend->myprint(qq{
522 Your configuration suggests that CPAN.pm should use a working
524 $CPAN::Config->{cpan_home}
525 Unfortunately we could not create the lock file
527 due to permission problems.
529 Please make sure that the configuration variable
530 \$CPAN::Config->{cpan_home}
531 points to a directory where you can write a .lock file. You can set
532 this variable in either
539 $CPAN::Frontend->mydie("Could not open >$lockfile: $!");
541 $fh->print($$, "\n");
542 $self->{LOCK} = $lockfile;
546 $CPAN::Frontend->mydie("Got SIGTERM, leaving");
551 $CPAN::Frontend->mydie("Got another SIGINT") if $Signal;
552 print "Caught SIGINT\n";
556 # From: Larry Wall <larry@wall.org>
557 # Subject: Re: deprecating SIGDIE
558 # To: perl5-porters@perl.org
559 # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
561 # The original intent of __DIE__ was only to allow you to substitute one
562 # kind of death for another on an application-wide basis without respect
563 # to whether you were in an eval or not. As a global backstop, it should
564 # not be used any more lightly (or any more heavily :-) than class
565 # UNIVERSAL. Any attempt to build a general exception model on it should
566 # be politely squashed. Any bug that causes every eval {} to have to be
567 # modified should be not so politely squashed.
569 # Those are my current opinions. It is also my optinion that polite
570 # arguments degenerate to personal arguments far too frequently, and that
571 # when they do, it's because both people wanted it to, or at least didn't
572 # sufficiently want it not to.
576 # global backstop to cleanup if we should really die
577 $SIG{__DIE__} = \&cleanup;
578 $self->debug("Signal handler set.") if $CPAN::DEBUG;
581 #-> sub CPAN::DESTROY ;
583 &cleanup; # need an eval?
587 sub cwd {Cwd::cwd();}
589 #-> sub CPAN::getcwd ;
590 sub getcwd {Cwd::getcwd();}
592 #-> sub CPAN::exists ;
594 my($mgr,$class,$id) = @_;
596 ### Carp::croak "exists called without class argument" unless $class;
598 exists $META->{readonly}{$class}{$id} or
599 exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
602 #-> sub CPAN::delete ;
604 my($mgr,$class,$id) = @_;
605 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
606 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
609 #-> sub CPAN::has_usable
610 # has_inst is sometimes too optimistic, we should replace it with this
611 # has_usable whenever a case is given
613 my($self,$mod,$message) = @_;
614 return 1 if $HAS_USABLE->{$mod};
615 my $has_inst = $self->has_inst($mod,$message);
616 return unless $has_inst;
619 LWP => [ # we frequently had "Can't locate object
620 # method "new" via package "LWP::UserAgent" at
621 # (eval 69) line 2006
623 sub {require LWP::UserAgent},
624 sub {require HTTP::Request},
625 sub {require URI::URL},
628 sub {require Net::FTP},
629 sub {require Net::Config},
632 if ($usable->{$mod}) {
633 for my $c (0..$#{$usable->{$mod}}) {
634 my $code = $usable->{$mod}[$c];
635 my $ret = eval { &$code() };
637 warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
642 return $HAS_USABLE->{$mod} = 1;
645 #-> sub CPAN::has_inst
647 my($self,$mod,$message) = @_;
648 Carp::croak("CPAN->has_inst() called without an argument")
650 if (defined $message && $message eq "no"
652 exists $CPAN::META->{dontload_hash}{$mod} # unsafe meta access, ok
654 exists $CPAN::Config->{dontload_hash}{$mod}
656 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
662 $file =~ s|/|\\|g if $^O eq 'MSWin32';
665 # checking %INC is wrong, because $INC{LWP} may be true
666 # although $INC{"URI/URL.pm"} may have failed. But as
667 # I really want to say "bla loaded OK", I have to somehow
669 ### warn "$file in %INC"; #debug
671 } elsif (eval { require $file }) {
672 # eval is good: if we haven't yet read the database it's
673 # perfect and if we have installed the module in the meantime,
674 # it tries again. The second require is only a NOOP returning
675 # 1 if we had success, otherwise it's retrying
677 $CPAN::Frontend->myprint("CPAN: $mod loaded ok\n");
678 if ($mod eq "CPAN::WAIT") {
679 push @CPAN::Shell::ISA, CPAN::WAIT;
682 } elsif ($mod eq "Net::FTP") {
683 $CPAN::Frontend->mywarn(qq{
684 Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
686 install Bundle::libnet
690 } elsif ($mod eq "MD5"){
691 $CPAN::Frontend->myprint(qq{
692 CPAN: MD5 security checks disabled because MD5 not installed.
693 Please consider installing the MD5 module.
698 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
703 #-> sub CPAN::instance ;
705 my($mgr,$class,$id) = @_;
708 # unsafe meta access, ok?
709 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
710 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
718 #-> sub CPAN::cleanup ;
720 # warn "cleanup called with arg[@_] End[$End] Signal[$Signal]";
721 local $SIG{__DIE__} = '';
726 0 && # disabled, try reload cpan with it
727 $] > 5.004_60 # thereabouts
732 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
734 $subroutine eq '(eval)';
737 return if $ineval && !$End;
738 return unless defined $META->{LOCK}; # unsafe meta access, ok
739 return unless -f $META->{LOCK}; # unsafe meta access, ok
740 unlink $META->{LOCK}; # unsafe meta access, ok
742 # Carp::cluck("DEBUGGING");
743 $CPAN::Frontend->mywarn("Lockfile removed.\n");
746 package CPAN::CacheMgr;
748 #-> sub CPAN::CacheMgr::as_string ;
750 eval { require Data::Dumper };
752 return shift->SUPER::as_string;
754 return Data::Dumper::Dumper(shift);
758 #-> sub CPAN::CacheMgr::cachesize ;
763 #-> sub CPAN::CacheMgr::tidyup ;
766 return unless -d $self->{ID};
767 while ($self->{DU} > $self->{'MAX'} ) {
768 my($toremove) = shift @{$self->{FIFO}};
769 $CPAN::Frontend->myprint(sprintf(
770 "Deleting from cache".
771 ": $toremove (%.1f>%.1f MB)\n",
772 $self->{DU}, $self->{'MAX'})
774 return if $CPAN::Signal;
775 $self->force_clean_cache($toremove);
776 return if $CPAN::Signal;
780 #-> sub CPAN::CacheMgr::dir ;
785 #-> sub CPAN::CacheMgr::entries ;
788 return unless defined $dir;
789 $self->debug("reading dir[$dir]") if $CPAN::DEBUG;
790 $dir ||= $self->{ID};
792 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
793 my($cwd) = CPAN->$getcwd();
794 chdir $dir or Carp::croak("Can't chdir to $dir: $!");
795 my $dh = DirHandle->new(File::Spec->curdir)
796 or Carp::croak("Couldn't opendir $dir: $!");
799 next if $_ eq "." || $_ eq "..";
801 push @entries, MM->catfile($dir,$_);
803 push @entries, MM->catdir($dir,$_);
805 $CPAN::Frontend->mywarn("Warning: weird direntry in $dir: $_\n");
808 chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
809 sort { -M $b <=> -M $a} @entries;
812 #-> sub CPAN::CacheMgr::disk_usage ;
815 return if exists $self->{SIZE}{$dir};
816 return if $CPAN::Signal;
820 $File::Find::prune++ if $CPAN::Signal;
822 if ($^O eq 'MacOS') {
824 my $cat = Mac::Files::FSpGetCatInfo($_);
825 $Du += $cat->ioFlLgLen() + $cat->ioFlRLgLen() if $cat;
832 return if $CPAN::Signal;
833 $self->{SIZE}{$dir} = $Du/1024/1024;
834 push @{$self->{FIFO}}, $dir;
835 $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
836 $self->{DU} += $Du/1024/1024;
840 #-> sub CPAN::CacheMgr::force_clean_cache ;
841 sub force_clean_cache {
843 return unless -e $dir;
844 $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}")
846 File::Path::rmtree($dir);
847 $self->{DU} -= $self->{SIZE}{$dir};
848 delete $self->{SIZE}{$dir};
851 #-> sub CPAN::CacheMgr::new ;
858 ID => $CPAN::Config->{'build_dir'},
859 MAX => $CPAN::Config->{'build_cache'},
860 SCAN => $CPAN::Config->{'scan_cache'} || 'atstart',
863 File::Path::mkpath($self->{ID});
864 my $dh = DirHandle->new($self->{ID});
868 $debug .= "timing of CacheMgr->new: ".($t2 - $time);
870 CPAN->debug($debug) if $CPAN::DEBUG;
874 #-> sub CPAN::CacheMgr::scan_cache ;
877 return if $self->{SCAN} eq 'never';
878 $CPAN::Frontend->mydie("Unknown scan_cache argument: $self->{SCAN}")
879 unless $self->{SCAN} eq 'atstart';
880 $CPAN::Frontend->myprint(
881 sprintf("Scanning cache %s for sizes\n",
884 for $e ($self->entries($self->{ID})) {
885 next if $e eq ".." || $e eq ".";
886 $self->disk_usage($e);
887 return if $CPAN::Signal;
894 #-> sub CPAN::Debug::debug ;
897 my($caller,$func,$line,@rest) = caller(1); # caller(0) eg
898 # Complete, caller(1)
900 ($caller) = caller(0);
902 $arg = "" unless defined $arg;
903 my $rest = join "|", map { defined $_ ? $_ : "UNDEF" } @rest;
904 if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
905 if ($arg and ref $arg) {
906 eval { require Data::Dumper };
908 $CPAN::Frontend->myprint($arg->as_string);
910 $CPAN::Frontend->myprint(Data::Dumper::Dumper($arg));
913 $CPAN::Frontend->myprint("Debug($caller:$func,$line,[$rest]): $arg\n");
918 package CPAN::Config;
920 #-> sub CPAN::Config::edit ;
921 # returns true on successful action
923 my($self,@args) = @_;
925 CPAN->debug("self[$self]args[".join(" | ",@args)."]");
926 my($o,$str,$func,$args,$key_exists);
932 CPAN->debug("o[$o]") if $CPAN::DEBUG;
936 CPAN->debug("func[$func]") if $CPAN::DEBUG;
938 # Let's avoid eval, it's easier to comprehend without.
939 if ($func eq "push") {
940 push @{$CPAN::Config->{$o}}, @args;
942 } elsif ($func eq "pop") {
943 pop @{$CPAN::Config->{$o}};
945 } elsif ($func eq "shift") {
946 shift @{$CPAN::Config->{$o}};
948 } elsif ($func eq "unshift") {
949 unshift @{$CPAN::Config->{$o}}, @args;
951 } elsif ($func eq "splice") {
952 splice @{$CPAN::Config->{$o}}, @args;
955 $CPAN::Config->{$o} = [@args];
958 $self->prettyprint($o);
960 if ($o eq "urllist" && $changed) {
961 # reset the cached values
962 undef $CPAN::FTP::Thesite;
963 undef $CPAN::FTP::Themethod;
967 $CPAN::Config->{$o} = $args[0] if defined $args[0];
968 $self->prettyprint($o);
975 my $v = $CPAN::Config->{$k};
977 my(@report) = ref $v eq "ARRAY" ?
979 map { sprintf(" %-18s => %s\n",
981 defined $v->{$_} ? $v->{$_} : "UNDEFINED"
983 $CPAN::Frontend->myprint(
990 map {"\t$_\n"} @report
993 } elsif (defined $v) {
994 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
996 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, "UNDEFINED");
1000 #-> sub CPAN::Config::commit ;
1002 my($self,$configpm) = @_;
1003 unless (defined $configpm){
1004 $configpm ||= $INC{"CPAN/MyConfig.pm"};
1005 $configpm ||= $INC{"CPAN/Config.pm"};
1006 $configpm || Carp::confess(q{
1007 CPAN::Config::commit called without an argument.
1008 Please specify a filename where to save the configuration or try
1009 "o conf init" to have an interactive course through configing.
1014 $mode = (stat $configpm)[2];
1015 if ($mode && ! -w _) {
1016 Carp::confess("$configpm is not writable");
1021 $msg = <<EOF unless $configpm =~ /MyConfig/;
1023 # This is CPAN.pm's systemwide configuration file. This file provides
1024 # defaults for users, and the values can be changed in a per-user
1025 # configuration file. The user-config file is being looked for as
1026 # ~/.cpan/CPAN/MyConfig.pm.
1030 my($fh) = FileHandle->new;
1031 rename $configpm, "$configpm~" if -f $configpm;
1032 open $fh, ">$configpm" or
1033 $CPAN::Frontend->mywarn("Couldn't open >$configpm: $!");
1034 $fh->print(qq[$msg\$CPAN::Config = \{\n]);
1035 foreach (sort keys %$CPAN::Config) {
1038 ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}),
1043 $fh->print("};\n1;\n__END__\n");
1046 #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
1047 #chmod $mode, $configpm;
1048 ###why was that so? $self->defaults;
1049 $CPAN::Frontend->myprint("commit: wrote $configpm\n");
1053 *default = \&defaults;
1054 #-> sub CPAN::Config::defaults ;
1064 undef $CPAN::Config->{'inhibit_startup_message'}; # lazy trick to
1073 #-> sub CPAN::Config::load ;
1078 eval {require CPAN::Config;}; # We eval because of some
1079 # MakeMaker problems
1080 unless ($dot_cpan++){
1081 unshift @INC, MM->catdir($ENV{HOME},".cpan");
1082 eval {require CPAN::MyConfig;}; # where you can override
1083 # system wide settings
1086 return unless @miss = $self->missing_config_data;
1088 require CPAN::FirstTime;
1089 my($configpm,$fh,$redo,$theycalled);
1091 $theycalled++ if @miss==1 && $miss[0] eq 'inhibit_startup_message';
1092 if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
1093 $configpm = $INC{"CPAN/Config.pm"};
1095 } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
1096 $configpm = $INC{"CPAN/MyConfig.pm"};
1099 my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
1100 my($configpmdir) = MM->catdir($path_to_cpan,"CPAN");
1101 my($configpmtest) = MM->catfile($configpmdir,"Config.pm");
1102 if (-d $configpmdir or File::Path::mkpath($configpmdir)) {
1103 if (-w $configpmtest) {
1104 $configpm = $configpmtest;
1105 } elsif (-w $configpmdir) {
1106 #_#_# following code dumped core on me with 5.003_11, a.k.
1107 unlink "$configpmtest.bak" if -f "$configpmtest.bak";
1108 rename $configpmtest, "$configpmtest.bak" if -f $configpmtest;
1109 my $fh = FileHandle->new;
1110 if ($fh->open(">$configpmtest")) {
1112 $configpm = $configpmtest;
1114 # Should never happen
1115 Carp::confess("Cannot open >$configpmtest");
1119 unless ($configpm) {
1120 $configpmdir = MM->catdir($ENV{HOME},".cpan","CPAN");
1121 File::Path::mkpath($configpmdir);
1122 $configpmtest = MM->catfile($configpmdir,"MyConfig.pm");
1123 if (-w $configpmtest) {
1124 $configpm = $configpmtest;
1125 } elsif (-w $configpmdir) {
1126 #_#_# following code dumped core on me with 5.003_11, a.k.
1127 my $fh = FileHandle->new;
1128 if ($fh->open(">$configpmtest")) {
1130 $configpm = $configpmtest;
1132 # Should never happen
1133 Carp::confess("Cannot open >$configpmtest");
1136 Carp::confess(qq{WARNING: CPAN.pm is unable to }.
1137 qq{create a configuration file.});
1142 $CPAN::Frontend->myprint(<<END) if $redo && ! $theycalled;
1143 We have to reconfigure CPAN.pm due to following uninitialized parameters:
1147 $CPAN::Frontend->myprint(qq{
1148 $configpm initialized.
1151 CPAN::FirstTime::init($configpm);
1154 #-> sub CPAN::Config::missing_config_data ;
1155 sub missing_config_data {
1158 "cpan_home", "keep_source_where", "build_dir", "build_cache",
1159 "scan_cache", "index_expire", "gzip", "tar", "unzip", "make", "pager",
1160 "makepl_arg", "make_arg", "make_install_arg", "urllist",
1161 "inhibit_startup_message", "ftp_proxy", "http_proxy", "no_proxy",
1162 "prerequisites_policy",
1164 # "cache_metadata" # not yet stable enough
1167 push @miss, $_ unless defined $CPAN::Config->{$_};
1172 #-> sub CPAN::Config::unload ;
1174 delete $INC{'CPAN/MyConfig.pm'};
1175 delete $INC{'CPAN/Config.pm'};
1178 #-> sub CPAN::Config::help ;
1180 $CPAN::Frontend->myprint(q[
1182 defaults reload default config values from disk
1183 commit commit session changes to disk
1184 init go through a dialog to set all parameters
1186 You may edit key values in the follow fashion (the "o" is a literal
1189 o conf build_cache 15
1191 o conf build_dir "/foo/bar"
1193 o conf urllist shift
1195 o conf urllist unshift ftp://ftp.foo.bar/
1198 undef; #don't reprint CPAN::Config
1201 #-> sub CPAN::Config::cpl ;
1203 my($word,$line,$pos) = @_;
1205 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
1206 my(@words) = split " ", substr($line,0,$pos+1);
1211 $words[2] =~ /list$/ && @words == 3
1213 $words[2] =~ /list$/ && @words == 4 && length($word)
1216 return grep /^\Q$word\E/, qw(splice shift unshift pop push);
1217 } elsif (@words >= 4) {
1220 my(@o_conf) = (keys %CPAN::Config::can, keys %$CPAN::Config);
1221 return grep /^\Q$word\E/, @o_conf;
1224 package CPAN::Shell;
1226 #-> sub CPAN::Shell::h ;
1228 my($class,$about) = @_;
1229 if (defined $about) {
1230 $CPAN::Frontend->myprint("Detailed help not yet implemented\n");
1232 $CPAN::Frontend->myprint(q{
1235 b string display bundles
1236 d or info distributions
1237 m /regex/ about modules
1238 i or anything of above
1239 r none reinstall recommendations
1240 u uninstalled distributions
1242 Download, Test, Make, Install...
1244 make make (implies get)
1245 test modules, make test (implies make)
1246 install dists, bundles make install (implies test)
1248 look open subshell in these dists' directories
1249 readme display these dists' README files
1252 h,? display this menu ! perl-code eval a perl command
1253 o conf [opt] set and query options q quit the cpan shell
1254 reload cpan load CPAN.pm again reload index load newer indices
1255 autobundle Snapshot force cmd unconditionally do cmd});
1261 #-> sub CPAN::Shell::a ;
1263 my($self,@arg) = @_;
1264 # authors are always UPPERCASE
1268 $CPAN::Frontend->myprint($self->format_result('Author',@arg));
1271 #-> sub CPAN::Shell::local_bundles ;
1274 my($self,@which) = @_;
1275 my($incdir,$bdir,$dh);
1276 foreach $incdir ($CPAN::Config->{'cpan_home'},@INC) {
1277 $bdir = MM->catdir($incdir,"Bundle");
1278 if ($dh = DirHandle->new($bdir)) { # may fail
1280 for $entry ($dh->read) {
1281 next if -d MM->catdir($bdir,$entry);
1282 next unless $entry =~ s/\.pm(?!\n)\Z//;
1283 $CPAN::META->instance('CPAN::Bundle',"Bundle::$entry");
1289 #-> sub CPAN::Shell::b ;
1291 my($self,@which) = @_;
1292 CPAN->debug("which[@which]") if $CPAN::DEBUG;
1293 $self->local_bundles;
1294 $CPAN::Frontend->myprint($self->format_result('Bundle',@which));
1297 #-> sub CPAN::Shell::d ;
1298 sub d { $CPAN::Frontend->myprint(shift->format_result('Distribution',@_));}
1300 #-> sub CPAN::Shell::m ;
1301 sub m { # emacs confused here }; sub mimimimimi { # emacs in sync here
1302 $CPAN::Frontend->myprint(shift->format_result('Module',@_));
1305 #-> sub CPAN::Shell::i ;
1310 @type = qw/Author Bundle Distribution Module/;
1311 @args = '/./' unless @args;
1314 push @result, $self->expand($type,@args);
1316 my $result = @result == 1 ?
1317 $result[0]->as_string :
1318 join "", map {$_->as_glimpse} @result;
1319 $result ||= "No objects found of any type for argument @args\n";
1320 $CPAN::Frontend->myprint($result);
1323 #-> sub CPAN::Shell::o ;
1325 # CPAN::Shell::o and CPAN::Config::edit are closely related. 'o conf'
1326 # should have been called set and 'o debug' maybe 'set debug'
1328 my($self,$o_type,@o_what) = @_;
1330 CPAN->debug("o_type[$o_type] o_what[".join(" | ",@o_what)."]\n");
1331 if ($o_type eq 'conf') {
1332 shift @o_what if @o_what && $o_what[0] eq 'help';
1333 if (!@o_what) { # print all things, "o conf"
1335 $CPAN::Frontend->myprint("CPAN::Config options");
1336 if (exists $INC{'CPAN/Config.pm'}) {
1337 $CPAN::Frontend->myprint(" from $INC{'CPAN/Config.pm'}");
1339 if (exists $INC{'CPAN/MyConfig.pm'}) {
1340 $CPAN::Frontend->myprint(" and $INC{'CPAN/MyConfig.pm'}");
1342 $CPAN::Frontend->myprint(":\n");
1343 for $k (sort keys %CPAN::Config::can) {
1344 $v = $CPAN::Config::can{$k};
1345 $CPAN::Frontend->myprint(sprintf " %-18s %s\n", $k, $v);
1347 $CPAN::Frontend->myprint("\n");
1348 for $k (sort keys %$CPAN::Config) {
1349 CPAN::Config->prettyprint($k);
1351 $CPAN::Frontend->myprint("\n");
1352 } elsif (!CPAN::Config->edit(@o_what)) {
1353 $CPAN::Frontend->myprint(qq{Type 'o conf' to view configuration }.
1354 qq{edit options\n\n});
1356 } elsif ($o_type eq 'debug') {
1358 @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
1361 my($what) = shift @o_what;
1362 if ( exists $CPAN::DEBUG{$what} ) {
1363 $CPAN::DEBUG |= $CPAN::DEBUG{$what};
1364 } elsif ($what =~ /^\d/) {
1365 $CPAN::DEBUG = $what;
1366 } elsif (lc $what eq 'all') {
1368 for (values %CPAN::DEBUG) {
1371 $CPAN::DEBUG = $max;
1374 for (keys %CPAN::DEBUG) {
1375 next unless lc($_) eq lc($what);
1376 $CPAN::DEBUG |= $CPAN::DEBUG{$_};
1379 $CPAN::Frontend->myprint("unknown argument [$what]\n")
1384 my $raw = "Valid options for debug are ".
1385 join(", ",sort(keys %CPAN::DEBUG), 'all').
1386 qq{ or a number. Completion works on the options. }.
1387 qq{Case is ignored.};
1389 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
1390 $CPAN::Frontend->myprint("\n\n");
1393 $CPAN::Frontend->myprint("Options set for debugging:\n");
1395 for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
1396 $v = $CPAN::DEBUG{$k};
1397 $CPAN::Frontend->myprint(sprintf " %-14s(%s)\n", $k, $v)
1398 if $v & $CPAN::DEBUG;
1401 $CPAN::Frontend->myprint("Debugging turned off completely.\n");
1404 $CPAN::Frontend->myprint(qq{
1406 conf set or get configuration variables
1407 debug set or get debugging options
1412 sub paintdots_onreload {
1415 if ( $_[0] =~ /[Ss]ubroutine (\w+) redefined/ ) {
1419 # $CPAN::Frontend->myprint(".($subr)");
1420 $CPAN::Frontend->myprint(".");
1427 #-> sub CPAN::Shell::reload ;
1429 my($self,$command,@arg) = @_;
1431 $self->debug("self[$self]command[$command]arg[@arg]") if $CPAN::DEBUG;
1432 if ($command =~ /cpan/i) {
1433 CPAN->debug("reloading the whole CPAN.pm") if $CPAN::DEBUG;
1434 my $fh = FileHandle->new($INC{'CPAN.pm'});
1437 local($SIG{__WARN__}) = paintdots_onreload(\$redef);
1440 $CPAN::Frontend->myprint("\n$redef subroutines redefined\n");
1441 } elsif ($command =~ /index/) {
1442 CPAN::Index->force_reload;
1444 $CPAN::Frontend->myprint(qq{cpan re-evals the CPAN.pm file
1445 index re-reads the index files\n});
1449 #-> sub CPAN::Shell::_binary_extensions ;
1450 sub _binary_extensions {
1451 my($self) = shift @_;
1452 my(@result,$module,%seen,%need,$headerdone);
1453 for $module ($self->expand('Module','/./')) {
1454 my $file = $module->cpan_file;
1455 next if $file eq "N/A";
1456 next if $file =~ /^Contact Author/;
1457 my $dist = $CPAN::META->instance('CPAN::Distribution',$file);
1458 next if $dist->isa_perl;
1459 next unless $module->xs_file;
1461 $CPAN::Frontend->myprint(".");
1462 push @result, $module;
1464 # print join " | ", @result;
1465 $CPAN::Frontend->myprint("\n");
1469 #-> sub CPAN::Shell::recompile ;
1471 my($self) = shift @_;
1472 my($module,@module,$cpan_file,%dist);
1473 @module = $self->_binary_extensions();
1474 for $module (@module){ # we force now and compile later, so we
1476 $cpan_file = $module->cpan_file;
1477 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1479 $dist{$cpan_file}++;
1481 for $cpan_file (sort keys %dist) {
1482 $CPAN::Frontend->myprint(" CPAN: Recompiling $cpan_file\n\n");
1483 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
1485 $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
1486 # stop a package from recompiling,
1487 # e.g. IO-1.12 when we have perl5.003_10
1491 #-> sub CPAN::Shell::_u_r_common ;
1493 my($self) = shift @_;
1494 my($what) = shift @_;
1495 CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
1496 Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless
1497 $what && $what =~ /^[aru]$/;
1499 @args = '/./' unless @args;
1500 my(@result,$module,%seen,%need,$headerdone,
1501 $version_undefs,$version_zeroes);
1502 $version_undefs = $version_zeroes = 0;
1503 my $sprintf = "%-25s %9s %9s %s\n";
1504 my @expand = $self->expand('Module',@args);
1505 my $expand = scalar @expand;
1506 if (0) { # Looks like noise to me, was very useful for debugging
1507 # for metadata cache
1508 $CPAN::Frontend->myprint(sprintf "%d matches in the database\n", $expand);
1510 for $module (@expand) {
1511 my $file = $module->cpan_file;
1512 next unless defined $file; # ??
1513 my($latest) = $module->cpan_version;
1514 my($inst_file) = $module->inst_file;
1516 return if $CPAN::Signal;
1519 $have = $module->inst_version;
1520 } elsif ($what eq "r") {
1521 $have = $module->inst_version;
1523 if ($have eq "undef"){
1525 } elsif ($have == 0){
1528 next unless CPAN::Version->vgt($latest, $have);
1529 # to be pedantic we should probably say:
1530 # && !($have eq "undef" && $latest ne "undef" && $latest gt "");
1531 # to catch the case where CPAN has a version 0 and we have a version undef
1532 } elsif ($what eq "u") {
1538 } elsif ($what eq "r") {
1540 } elsif ($what eq "u") {
1544 return if $CPAN::Signal; # this is sometimes lengthy
1547 push @result, sprintf "%s %s\n", $module->id, $have;
1548 } elsif ($what eq "r") {
1549 push @result, $module->id;
1550 next if $seen{$file}++;
1551 } elsif ($what eq "u") {
1552 push @result, $module->id;
1553 next if $seen{$file}++;
1554 next if $file =~ /^Contact/;
1556 unless ($headerdone++){
1557 $CPAN::Frontend->myprint("\n");
1558 $CPAN::Frontend->myprint(sprintf(
1560 "Package namespace",
1566 $CPAN::Frontend->myprint(sprintf $sprintf,
1571 $need{$module->id}++;
1575 $CPAN::Frontend->myprint("No modules found for @args\n");
1576 } elsif ($what eq "r") {
1577 $CPAN::Frontend->myprint("All modules are up to date for @args\n");
1581 if ($version_zeroes) {
1582 my $s_has = $version_zeroes > 1 ? "s have" : " has";
1583 $CPAN::Frontend->myprint(qq{$version_zeroes installed module$s_has }.
1584 qq{a version number of 0\n});
1586 if ($version_undefs) {
1587 my $s_has = $version_undefs > 1 ? "s have" : " has";
1588 $CPAN::Frontend->myprint(qq{$version_undefs installed module$s_has no }.
1589 qq{parseable version number\n});
1595 #-> sub CPAN::Shell::r ;
1597 shift->_u_r_common("r",@_);
1600 #-> sub CPAN::Shell::u ;
1602 shift->_u_r_common("u",@_);
1605 #-> sub CPAN::Shell::autobundle ;
1608 CPAN::Config->load unless $CPAN::Config_loaded++;
1609 my(@bundle) = $self->_u_r_common("a",@_);
1610 my($todir) = MM->catdir($CPAN::Config->{'cpan_home'},"Bundle");
1611 File::Path::mkpath($todir);
1612 unless (-d $todir) {
1613 $CPAN::Frontend->myprint("Couldn't mkdir $todir for some reason\n");
1616 my($y,$m,$d) = (localtime)[5,4,3];
1620 my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
1621 my($to) = MM->catfile($todir,"$me.pm");
1623 $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
1624 $to = MM->catfile($todir,"$me.pm");
1626 my($fh) = FileHandle->new(">$to") or Carp::croak "Can't open >$to: $!";
1628 "package Bundle::$me;\n\n",
1629 "\$VERSION = '0.01';\n\n",
1633 "Bundle::$me - Snapshot of installation on ",
1634 $Config::Config{'myhostname'},
1637 "\n\n=head1 SYNOPSIS\n\n",
1638 "perl -MCPAN -e 'install Bundle::$me'\n\n",
1639 "=head1 CONTENTS\n\n",
1640 join("\n", @bundle),
1641 "\n\n=head1 CONFIGURATION\n\n",
1643 "\n\n=head1 AUTHOR\n\n",
1644 "This Bundle has been generated automatically ",
1645 "by the autobundle routine in CPAN.pm.\n",
1648 $CPAN::Frontend->myprint("\nWrote bundle file
1652 #-> sub CPAN::Shell::expandany ;
1655 CPAN->debug("s[$s]") if $CPAN::DEBUG;
1656 if ($s =~ m|/|) { # looks like a file
1657 return $CPAN::META->instance('CPAN::Distribution',$s);
1658 # Distributions spring into existence, not expand
1659 } elsif ($s =~ m|^Bundle::|) {
1660 $self->local_bundles; # scanning so late for bundles seems
1661 # both attractive and crumpy: always
1662 # current state but easy to forget
1664 return $self->expand('Bundle',$s);
1666 return $self->expand('Module',$s)
1667 if $CPAN::META->exists('CPAN::Module',$s);
1672 #-> sub CPAN::Shell::expand ;
1675 my($type,@args) = @_;
1678 my($regex,$command);
1679 if ($arg =~ m|^/(.*)/$|) {
1681 } elsif ($arg =~ m/^=/) {
1682 $command = substr($arg,1);
1684 my $class = "CPAN::$type";
1686 if (defined $regex) {
1690 $CPAN::META->all_objects($class)
1693 # BUG, we got an empty object somewhere
1694 CPAN->debug(sprintf(
1695 "Empty id on obj[%s]%%[%s]",
1702 if $obj->id =~ /$regex/i
1706 $] < 5.00303 ### provide sort of
1707 ### compatibility with 5.003
1712 $obj->name =~ /$regex/i
1715 } elsif ($command) {
1716 die "leading equal sign in command disabled, ".
1717 "please edit CPAN.pm to enable eval() or ".
1718 "do not use = on argument list";
1722 $CPAN::META->all_objects($class)
1724 push @m, $self if eval $command;
1728 if ( $type eq 'Bundle' ) {
1729 $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
1731 if ($CPAN::META->exists($class,$xarg)) {
1732 $obj = $CPAN::META->instance($class,$xarg);
1733 } elsif ($CPAN::META->exists($class,$arg)) {
1734 $obj = $CPAN::META->instance($class,$arg);
1741 return wantarray ? @m : $m[0];
1744 #-> sub CPAN::Shell::format_result ;
1747 my($type,@args) = @_;
1748 @args = '/./' unless @args;
1749 my(@result) = $self->expand($type,@args);
1750 my $result = @result == 1 ?
1751 $result[0]->as_string :
1752 join "", map {$_->as_glimpse} @result;
1753 $result ||= "No objects of type $type found for argument @args\n";
1757 # The only reason for this method is currently to have a reliable
1758 # debugging utility that reveals which output is going through which
1759 # channel. No, I don't like the colors ;-)
1760 sub print_ornamented {
1761 my($self,$what,$ornament) = @_;
1763 my $ornamenting = 0; # turn the colors on
1766 unless (defined &color) {
1767 if ($CPAN::META->has_inst("Term::ANSIColor")) {
1768 import Term::ANSIColor "color";
1770 *color = sub { return "" };
1774 for $line (split /\n/, $what) {
1775 $longest = length($line) if length($line) > $longest;
1777 my $sprintf = "%-" . $longest . "s";
1779 $what =~ s/(.*\n?)//m;
1782 my($nl) = chomp $line ? "\n" : "";
1783 # print "line[$line]ornament[$ornament]sprintf[$sprintf]\n";
1784 print color($ornament), sprintf($sprintf,$line), color("reset"), $nl;
1792 my($self,$what) = @_;
1793 $self->print_ornamented($what, 'bold blue on_yellow');
1797 my($self,$what) = @_;
1798 $self->myprint($what);
1803 my($self,$what) = @_;
1804 $self->print_ornamented($what, 'bold red on_yellow');
1808 my($self,$what) = @_;
1809 $self->print_ornamented($what, 'bold red on_white');
1810 Carp::confess "died";
1814 my($self,$what) = @_;
1815 $self->print_ornamented($what, 'bold red on_white');
1820 return if -t STDOUT;
1821 my $odef = select STDERR;
1828 #-> sub CPAN::Shell::rematein ;
1829 # RE-adme||MA-ke||TE-st||IN-stall
1832 my($meth,@some) = @_;
1834 if ($meth eq 'force') {
1836 $meth = shift @some;
1839 CPAN->debug("pragma[$pragma]meth[$meth] some[@some]") if $CPAN::DEBUG;
1841 # Here is the place to set "test_count" on all involved parties to
1842 # 0. We then can pass this counter on to the involved
1843 # distributions and those can refuse to test if test_count > X. In
1844 # the first stab at it we could use a 1 for "X".
1846 # But when do I reset the distributions to start with 0 again?
1847 # Jost suggested to have a random or cycling interaction ID that
1848 # we pass through. But the ID is something that is just left lying
1849 # around in addition to the counter, so I'd prefer to set the
1850 # counter to 0 now, and repeat at the end of the loop. But what
1851 # about dependencies? They appear later and are not reset, they
1852 # enter the queue but not its copy. How do they get a sensible
1855 # construct the queue
1857 foreach $s (@some) {
1860 CPAN->debug("s is an object[$s]") if $CPAN::DEBUG;
1862 } elsif ($s =~ m|^/|) { # looks like a regexp
1863 $CPAN::Frontend->mywarn("Sorry, $meth with a regular expression is ".
1868 CPAN->debug("calling expandany [$s]") if $CPAN::DEBUG;
1869 $obj = CPAN::Shell->expandany($s);
1872 $obj->color_cmd_tmps(0,1);
1873 CPAN::Queue->new($s);
1875 } elsif ($CPAN::META->exists('CPAN::Author',$s)) {
1876 $obj = $CPAN::META->instance('CPAN::Author',$s);
1877 $CPAN::Frontend->myprint(
1879 "Don't be silly, you can't $meth ",
1886 ->myprint(qq{Warning: Cannot $meth $s, }.
1887 qq{don\'t know what it is.
1892 to find objects with matching identifiers.
1898 # queuerunner (please be warned: when I started to change the
1899 # queue to hold objects instead of names, I made one or two
1900 # mistakes and never found which. I reverted back instead)
1901 while ($s = CPAN::Queue->first) {
1904 $obj = $s; # I do not believe, we would survive if this happened
1906 $obj = CPAN::Shell->expandany($s);
1910 ($] < 5.00303 || $obj->can($pragma))){
1911 ### compatibility with 5.003
1912 $obj->$pragma($meth); # the pragma "force" in
1913 # "CPAN::Distribution" must know
1914 # what we are intending
1916 if ($]>=5.00303 && $obj->can('called_for')) {
1917 $obj->called_for($s);
1920 qq{pragma[$pragma]meth[$meth]obj[$obj]as_string\[}.
1926 CPAN::Queue->delete($s);
1928 CPAN->debug("failed");
1932 CPAN::Queue->delete_first($s);
1934 for my $obj (@qcopy) {
1935 $obj->color_cmd_tmps(0,0);
1939 #-> sub CPAN::Shell::dump ;
1940 sub dump { shift->rematein('dump',@_); }
1941 #-> sub CPAN::Shell::force ;
1942 sub force { shift->rematein('force',@_); }
1943 #-> sub CPAN::Shell::get ;
1944 sub get { shift->rematein('get',@_); }
1945 #-> sub CPAN::Shell::readme ;
1946 sub readme { shift->rematein('readme',@_); }
1947 #-> sub CPAN::Shell::make ;
1948 sub make { shift->rematein('make',@_); }
1949 #-> sub CPAN::Shell::test ;
1950 sub test { shift->rematein('test',@_); }
1951 #-> sub CPAN::Shell::install ;
1952 sub install { shift->rematein('install',@_); }
1953 #-> sub CPAN::Shell::clean ;
1954 sub clean { shift->rematein('clean',@_); }
1955 #-> sub CPAN::Shell::look ;
1956 sub look { shift->rematein('look',@_); }
1957 #-> sub CPAN::Shell::cvs_import ;
1958 sub cvs_import { shift->rematein('cvs_import',@_); }
1962 #-> sub CPAN::FTP::ftp_get ;
1964 my($class,$host,$dir,$file,$target) = @_;
1966 qq[Going to fetch file [$file] from dir [$dir]
1967 on host [$host] as local [$target]\n]
1969 my $ftp = Net::FTP->new($host);
1970 return 0 unless defined $ftp;
1971 $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
1972 $class->debug(qq[Going to login("anonymous","$Config::Config{cf_email}")]);
1973 unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
1974 warn "Couldn't login on $host";
1977 unless ( $ftp->cwd($dir) ){
1978 warn "Couldn't cwd $dir";
1982 $class->debug(qq[Going to ->get("$file","$target")\n]) if $CPAN::DEBUG;
1983 unless ( $ftp->get($file,$target) ){
1984 warn "Couldn't fetch $file from $host\n";
1987 $ftp->quit; # it's ok if this fails
1991 # If more accuracy is wanted/needed, Chris Leach sent me this patch...
1993 # > *** /install/perl/live/lib/CPAN.pm- Wed Sep 24 13:08:48 1997
1994 # > --- /tmp/cp Wed Sep 24 13:26:40 1997
1996 # > *** 1562,1567 ****
1997 # > --- 1562,1580 ----
1998 # > return 1 if substr($url,0,4) eq "file";
1999 # > return 1 unless $url =~ m|://([^/]+)|;
2001 # > + my $proxy = $CPAN::Config->{'http_proxy'} || $ENV{'http_proxy'};
2003 # > + $proxy =~ m|://([^/:]+)|;
2005 # > + my $noproxy = $CPAN::Config->{'no_proxy'} || $ENV{'no_proxy'};
2006 # > + if ($noproxy) {
2007 # > + if ($host !~ /$noproxy$/) {
2008 # > + $host = $proxy;
2011 # > + $host = $proxy;
2014 # > require Net::Ping;
2015 # > return 1 unless $Net::Ping::VERSION >= 2;
2019 # this is quite optimistic and returns one on several occasions where
2020 # inappropriate. But this does no harm. It would do harm if we were
2021 # too pessimistic (as I was before the http_proxy
2023 my($self,$url) = @_;
2024 return 1; # we can't simply roll our own, firewalls may break ping
2025 return 0 unless $url;
2026 return 1 if substr($url,0,4) eq "file";
2027 return 1 unless $url =~ m|^(\w+)://([^/]+)|;
2028 my $proxytype = $1 . "_proxy"; # ftp_proxy or http_proxy
2030 return 1 if $CPAN::Config->{$proxytype} || $ENV{$proxytype};
2032 return 1 unless $Net::Ping::VERSION >= 2;
2034 # 1.3101 had it different: only if the first eval raised an
2035 # exception we tried it with TCP. Now we are happy if icmp wins
2036 # the order and return, we don't even check for $@. Thanks to
2037 # thayer@uis.edu for the suggestion.
2038 eval {$p = Net::Ping->new("icmp");};
2039 return 1 if $p && ref($p) && $p->ping($host, 10);
2040 eval {$p = Net::Ping->new("tcp");};
2041 $CPAN::Frontend->mydie($@) if $@;
2042 return $p->ping($host, 10);
2045 #-> sub CPAN::FTP::localize ;
2047 my($self,$file,$aslocal,$force) = @_;
2049 Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])"
2050 unless defined $aslocal;
2051 $self->debug("file[$file] aslocal[$aslocal] force[$force]")
2054 if ($^O eq 'MacOS') {
2055 # Comment by AK on 2000-09-03: Uniq short filenames would be
2056 # available in CHECKSUMS file
2057 my($name, $path) = File::Basename::fileparse($aslocal, '');
2058 if (length($name) > 31) {
2069 my $size = 31 - length($suf);
2070 while (length($name) > $size) {
2074 $aslocal = File::Spec->catfile($path, $name);
2078 return $aslocal if -f $aslocal && -r _ && !($force & 1);
2081 rename $aslocal, "$aslocal.bak";
2085 my($aslocal_dir) = File::Basename::dirname($aslocal);
2086 File::Path::mkpath($aslocal_dir);
2087 $CPAN::Frontend->mywarn(qq{Warning: You are not allowed to write into }.
2088 qq{directory "$aslocal_dir".
2089 I\'ll continue, but if you encounter problems, they may be due
2090 to insufficient permissions.\n}) unless -w $aslocal_dir;
2092 # Inheritance is not easier to manage than a few if/else branches
2093 if ($CPAN::META->has_usable('LWP::UserAgent')) {
2095 $Ua = LWP::UserAgent->new;
2097 $Ua->proxy('ftp', $var)
2098 if $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
2099 $Ua->proxy('http', $var)
2100 if $var = $CPAN::Config->{http_proxy} || $ENV{http_proxy};
2102 if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
2105 $ENV{ftp_proxy} = $CPAN::Config->{ftp_proxy} if $CPAN::Config->{ftp_proxy};
2106 $ENV{http_proxy} = $CPAN::Config->{http_proxy}
2107 if $CPAN::Config->{http_proxy};
2108 $ENV{no_proxy} = $CPAN::Config->{no_proxy} if $CPAN::Config->{no_proxy};
2110 # Try the list of urls for each single object. We keep a record
2111 # where we did get a file from
2112 my(@reordered,$last);
2113 $CPAN::Config->{urllist} ||= [];
2114 $last = $#{$CPAN::Config->{urllist}};
2115 if ($force & 2) { # local cpans probably out of date, don't reorder
2116 @reordered = (0..$last);
2120 (substr($CPAN::Config->{urllist}[$b],0,4) eq "file")
2122 (substr($CPAN::Config->{urllist}[$a],0,4) eq "file")
2133 @levels = ($Themethod, grep {$_ ne $Themethod} qw/easy hard hardest/);
2135 @levels = qw/easy hard hardest/;
2137 @levels = qw/easy/ if $^O eq 'MacOS';
2139 for $levelno (0..$#levels) {
2140 my $level = $levels[$levelno];
2141 my $method = "host$level";
2142 my @host_seq = $level eq "easy" ?
2143 @reordered : 0..$last; # reordered has CDROM up front
2144 @host_seq = (0) unless @host_seq;
2145 my $ret = $self->$method(\@host_seq,$file,$aslocal);
2147 $Themethod = $level;
2149 # utime $now, $now, $aslocal; # too bad, if we do that, we
2150 # might alter a local mirror
2151 $self->debug("level[$level]") if $CPAN::DEBUG;
2155 last if $CPAN::Signal; # need to cleanup
2158 unless ($CPAN::Signal) {
2161 qq{Please check, if the URLs I found in your configuration file \(}.
2162 join(", ", @{$CPAN::Config->{urllist}}).
2163 qq{\) are valid. The urllist can be edited.},
2164 qq{E.g. with 'o conf urllist push ftp://myurl/'};
2165 $CPAN::Frontend->myprint(Text::Wrap::wrap("","",@mess). "\n\n");
2167 $CPAN::Frontend->myprint("Cannot fetch $file\n\n");
2170 rename "$aslocal.bak", $aslocal;
2171 $CPAN::Frontend->myprint("Trying to get away with old file:\n" .
2172 $self->ls($aslocal));
2179 my($self,$host_seq,$file,$aslocal) = @_;
2181 HOSTEASY: for $i (@$host_seq) {
2182 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2183 unless ($self->is_reachable($url)) {
2184 $CPAN::Frontend->myprint("Skipping $url (seems to be not reachable)\n");
2188 $url .= "/" unless substr($url,-1) eq "/";
2190 $self->debug("localizing perlish[$url]") if $CPAN::DEBUG;
2191 if ($url =~ /^file:/) {
2193 if ($CPAN::META->has_inst('URI::URL')) {
2194 my $u = URI::URL->new($url);
2196 } else { # works only on Unix, is poorly constructed, but
2197 # hopefully better than nothing.
2198 # RFC 1738 says fileurl BNF is
2199 # fileurl = "file://" [ host | "localhost" ] "/" fpath
2200 # Thanks to "Mark D. Baushke" <mdb@cisco.com> for
2202 ($l = $url) =~ s|^file://[^/]*/|/|; # discard the host part
2203 $l =~ s|^file:||; # assume they
2206 $l =~ s|^/||s unless -f $l; # e.g. /P:
2208 if ( -f $l && -r _) {
2212 # Maybe mirror has compressed it?
2214 $self->debug("found compressed $l.gz") if $CPAN::DEBUG;
2215 CPAN::Tarzip->gunzip("$l.gz", $aslocal);
2222 if ($CPAN::META->has_usable('LWP')) {
2223 $CPAN::Frontend->myprint("Fetching with LWP:
2227 require LWP::UserAgent;
2228 $Ua = LWP::UserAgent->new;
2230 my $res = $Ua->mirror($url, $aslocal);
2231 if ($res->is_success) {
2234 utime $now, $now, $aslocal; # download time is more
2235 # important than upload time
2237 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2238 my $gzurl = "$url.gz";
2239 $CPAN::Frontend->myprint("Fetching with LWP:
2242 $res = $Ua->mirror($gzurl, "$aslocal.gz");
2243 if ($res->is_success &&
2244 CPAN::Tarzip->gunzip("$aslocal.gz",$aslocal)
2250 # Alan Burlison informed me that in firewall environments
2251 # Net::FTP can still succeed where LWP fails. So we do not
2252 # skip Net::FTP anymore when LWP is available.
2255 $self->debug("LWP not installed") if $CPAN::DEBUG;
2257 return if $CPAN::Signal;
2258 if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2259 # that's the nice and easy way thanks to Graham
2260 my($host,$dir,$getfile) = ($1,$2,$3);
2261 if ($CPAN::META->has_usable('Net::FTP')) {
2263 $CPAN::Frontend->myprint("Fetching with Net::FTP:
2266 $self->debug("getfile[$getfile]dir[$dir]host[$host]" .
2267 "aslocal[$aslocal]") if $CPAN::DEBUG;
2268 if (CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal)) {
2272 if ($aslocal !~ /\.gz(?!\n)\Z/) {
2273 my $gz = "$aslocal.gz";
2274 $CPAN::Frontend->myprint("Fetching with Net::FTP
2277 if (CPAN::FTP->ftp_get($host,
2281 CPAN::Tarzip->gunzip($gz,$aslocal)
2290 return if $CPAN::Signal;
2295 my($self,$host_seq,$file,$aslocal) = @_;
2297 # Came back if Net::FTP couldn't establish connection (or
2298 # failed otherwise) Maybe they are behind a firewall, but they
2299 # gave us a socksified (or other) ftp program...
2302 my($devnull) = $CPAN::Config->{devnull} || "";
2304 my($aslocal_dir) = File::Basename::dirname($aslocal);
2305 File::Path::mkpath($aslocal_dir);
2306 HOSTHARD: for $i (@$host_seq) {
2307 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2308 unless ($self->is_reachable($url)) {
2309 $CPAN::Frontend->myprint("Skipping $url (not reachable)\n");
2312 $url .= "/" unless substr($url,-1) eq "/";
2314 my($proto,$host,$dir,$getfile);
2316 # Courtesy Mark Conty mark_conty@cargill.com change from
2317 # if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2319 if ($url =~ m|^([^:]+)://(.*?)/(.*)/(.*)|) {
2320 # proto not yet used
2321 ($proto,$host,$dir,$getfile) = ($1,$2,$3,$4);
2323 next HOSTHARD; # who said, we could ftp anything except ftp?
2326 $self->debug("localizing funkyftpwise[$url]") if $CPAN::DEBUG;
2328 for $f ('lynx','ncftpget','ncftp') {
2329 next unless exists $CPAN::Config->{$f};
2330 $funkyftp = $CPAN::Config->{$f};
2331 next unless defined $funkyftp;
2332 next if $funkyftp =~ /^\s*$/;
2333 my($asl_ungz, $asl_gz);
2334 ($asl_ungz = $aslocal) =~ s/\.gz//;
2335 $asl_gz = "$asl_ungz.gz";
2336 my($src_switch) = "";
2338 $src_switch = " -source";
2339 } elsif ($f eq "ncftp"){
2340 $src_switch = " -c";
2343 my($stdout_redir) = " > $asl_ungz";
2344 if ($f eq "ncftpget"){
2345 $chdir = "cd $aslocal_dir && ";
2348 $CPAN::Frontend->myprint(
2350 Trying with "$funkyftp$src_switch" to get
2354 "$chdir$funkyftp$src_switch '$url' $devnull$stdout_redir";
2355 $self->debug("system[$system]") if $CPAN::DEBUG;
2357 if (($wstatus = system($system)) == 0
2360 -s $asl_ungz # lynx returns 0 on my
2361 # system even if it fails
2367 } elsif ($asl_ungz ne $aslocal) {
2368 # test gzip integrity
2370 CPAN::Tarzip->gtest($asl_ungz)
2372 rename $asl_ungz, $aslocal;
2374 CPAN::Tarzip->gzip($asl_ungz,$asl_gz);
2379 } elsif ($url !~ /\.gz(?!\n)\Z/) {
2381 -f $asl_ungz && -s _ == 0;
2382 my $gz = "$aslocal.gz";
2383 my $gzurl = "$url.gz";
2384 $CPAN::Frontend->myprint(
2386 Trying with "$funkyftp$src_switch" to get
2389 my($system) = "$funkyftp$src_switch '$url.gz' $devnull > $asl_gz";
2390 $self->debug("system[$system]") if $CPAN::DEBUG;
2392 if (($wstatus = system($system)) == 0
2396 # test gzip integrity
2397 if (CPAN::Tarzip->gtest($asl_gz)) {
2398 CPAN::Tarzip->gunzip($asl_gz,$aslocal);
2400 rename $asl_ungz, $aslocal;
2405 unlink $asl_gz if -f $asl_gz;
2408 my $estatus = $wstatus >> 8;
2409 my $size = -f $aslocal ?
2410 ", left\n$aslocal with size ".-s _ :
2411 "\nWarning: expected file [$aslocal] doesn't exist";
2412 $CPAN::Frontend->myprint(qq{
2413 System call "$system"
2414 returned status $estatus (wstat $wstatus)$size
2417 return if $CPAN::Signal;
2418 } # lynx,ncftpget,ncftp
2423 my($self,$host_seq,$file,$aslocal) = @_;
2426 my($aslocal_dir) = File::Basename::dirname($aslocal);
2427 File::Path::mkpath($aslocal_dir);
2428 HOSTHARDEST: for $i (@$host_seq) {
2429 unless (length $CPAN::Config->{'ftp'}) {
2430 $CPAN::Frontend->myprint("No external ftp command available\n\n");
2433 my $url = $CPAN::Config->{urllist}[$i] || $CPAN::Defaultsite;
2434 unless ($self->is_reachable($url)) {
2435 $CPAN::Frontend->myprint("Skipping $url (not reachable)\n");
2438 $url .= "/" unless substr($url,-1) eq "/";
2440 $self->debug("localizing ftpwise[$url]") if $CPAN::DEBUG;
2441 unless ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
2444 my($host,$dir,$getfile) = ($1,$2,$3);
2446 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,
2447 $ctime,$blksize,$blocks) = stat($aslocal);
2448 $timestamp = $mtime ||= 0;
2449 my($netrc) = CPAN::FTP::netrc->new;
2450 my($netrcfile) = $netrc->netrc;
2451 my($verbose) = $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG ? " -v" : "";
2452 my $targetfile = File::Basename::basename($aslocal);
2458 map("cd $_", split "/", $dir), # RFC 1738
2460 "get $getfile $targetfile",
2464 CPAN->debug("No ~/.netrc file found") if $CPAN::DEBUG;
2465 } elsif ($netrc->hasdefault || $netrc->contains($host)) {
2466 CPAN->debug(sprintf("hasdef[%d]cont($host)[%d]",
2468 $netrc->contains($host))) if $CPAN::DEBUG;
2469 if ($netrc->protected) {
2470 $CPAN::Frontend->myprint(qq{
2471 Trying with external ftp to get
2473 As this requires some features that are not thoroughly tested, we\'re
2474 not sure, that we get it right....
2478 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose $host",
2480 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2481 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2483 if ($mtime > $timestamp) {
2484 $CPAN::Frontend->myprint("GOT $aslocal\n");
2488 $CPAN::Frontend->myprint("Hmm... Still failed!\n");
2490 return if $CPAN::Signal;
2492 $CPAN::Frontend->mywarn(qq{Your $netrcfile is not }.
2493 qq{correctly protected.\n});
2496 $CPAN::Frontend->mywarn("Your ~/.netrc neither contains $host
2497 nor does it have a default entry\n");
2500 # OK, they don't have a valid ~/.netrc. Use 'ftp -n'
2501 # then and login manually to host, using e-mail as
2503 $CPAN::Frontend->myprint(qq{Issuing "$CPAN::Config->{'ftp'}$verbose -n"\n});
2507 "user anonymous $Config::Config{'cf_email'}"
2509 $self->talk_ftp("$CPAN::Config->{'ftp'}$verbose -n", @dialog);
2510 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2511 $atime,$mtime,$ctime,$blksize,$blocks) = stat($aslocal);
2513 if ($mtime > $timestamp) {
2514 $CPAN::Frontend->myprint("GOT $aslocal\n");
2518 $CPAN::Frontend->myprint("Bad luck... Still failed!\n");
2520 return if $CPAN::Signal;
2521 $CPAN::Frontend->myprint("Can't access URL $url.\n\n");
2527 my($self,$command,@dialog) = @_;
2528 my $fh = FileHandle->new;
2529 $fh->open("|$command") or die "Couldn't open ftp: $!";
2530 foreach (@dialog) { $fh->print("$_\n") }
2531 $fh->close; # Wait for process to complete
2533 my $estatus = $wstatus >> 8;
2534 $CPAN::Frontend->myprint(qq{
2535 Subprocess "|$command"
2536 returned status $estatus (wstat $wstatus)
2540 # find2perl needs modularization, too, all the following is stolen
2544 my($self,$name) = @_;
2545 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
2546 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($name);
2548 my($perms,%user,%group);
2552 $blocks = int(($blocks + 1) / 2);
2555 $blocks = int(($sizemm + 1023) / 1024);
2558 if (-f _) { $perms = '-'; }
2559 elsif (-d _) { $perms = 'd'; }
2560 elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
2561 elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
2562 elsif (-p _) { $perms = 'p'; }
2563 elsif (-S _) { $perms = 's'; }
2564 else { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
2566 my(@rwx) = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
2567 my(@moname) = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
2568 my $tmpmode = $mode;
2569 my $tmp = $rwx[$tmpmode & 7];
2571 $tmp = $rwx[$tmpmode & 7] . $tmp;
2573 $tmp = $rwx[$tmpmode & 7] . $tmp;
2574 substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
2575 substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
2576 substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
2579 my $user = $user{$uid} || $uid; # too lazy to implement lookup
2580 my $group = $group{$gid} || $gid;
2582 my($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
2584 my($moname) = $moname[$mon];
2585 if (-M _ > 365.25 / 2) {
2586 $timeyear = $year + 1900;
2589 $timeyear = sprintf("%02d:%02d", $hour, $min);
2592 sprintf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
2606 package CPAN::FTP::netrc;
2610 my $file = MM->catfile($ENV{HOME},".netrc");
2612 my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
2613 $atime,$mtime,$ctime,$blksize,$blocks)
2618 my($fh,@machines,$hasdefault);
2620 $fh = FileHandle->new or die "Could not create a filehandle";
2622 if($fh->open($file)){
2623 $protected = ($mode & 077) == 0;
2625 NETRC: while (<$fh>) {
2626 my(@tokens) = split " ", $_;
2627 TOKEN: while (@tokens) {
2628 my($t) = shift @tokens;
2629 if ($t eq "default"){
2633 last TOKEN if $t eq "macdef";
2634 if ($t eq "machine") {
2635 push @machines, shift @tokens;
2640 $file = $hasdefault = $protected = "";
2644 'mach' => [@machines],
2646 'hasdefault' => $hasdefault,
2647 'protected' => $protected,
2651 sub hasdefault { shift->{'hasdefault'} }
2652 sub netrc { shift->{'netrc'} }
2653 sub protected { shift->{'protected'} }
2655 my($self,$mach) = @_;
2656 for ( @{$self->{'mach'}} ) {
2657 return 1 if $_ eq $mach;
2662 package CPAN::Complete;
2665 my($text, $line, $start, $end) = @_;
2666 my(@perlret) = cpl($text, $line, $start);
2667 # find longest common match. Can anybody show me how to peruse
2668 # T::R::Gnu to have this done automatically? Seems expensive.
2669 return () unless @perlret;
2670 my($newtext) = $text;
2671 for (my $i = length($text)+1;;$i++) {
2672 last unless length($perlret[0]) && length($perlret[0]) >= $i;
2673 my $try = substr($perlret[0],0,$i);
2674 my @tries = grep {substr($_,0,$i) eq $try} @perlret;
2675 # warn "try[$try]tries[@tries]";
2676 if (@tries == @perlret) {
2682 ($newtext,@perlret);
2685 #-> sub CPAN::Complete::cpl ;
2687 my($word,$line,$pos) = @_;
2691 CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2693 if ($line =~ s/^(force\s*)//) {
2701 ! a b d h i m o q r u autobundle clean dump
2702 make test install force readme reload look cvs_import
2705 } elsif ( $line !~ /^[\!abcdhimorutl]/ ) {
2707 } elsif ($line =~ /^a\s/) {
2708 @return = cplx('CPAN::Author',$word);
2709 } elsif ($line =~ /^b\s/) {
2710 @return = cplx('CPAN::Bundle',$word);
2711 } elsif ($line =~ /^d\s/) {
2712 @return = cplx('CPAN::Distribution',$word);
2713 } elsif ($line =~ m/^(
2714 [mru]|make|clean|dump|test|install|readme|look|cvs_import
2716 @return = (cplx('CPAN::Module',$word),cplx('CPAN::Bundle',$word));
2717 } elsif ($line =~ /^i\s/) {
2718 @return = cpl_any($word);
2719 } elsif ($line =~ /^reload\s/) {
2720 @return = cpl_reload($word,$line,$pos);
2721 } elsif ($line =~ /^o\s/) {
2722 @return = cpl_option($word,$line,$pos);
2729 #-> sub CPAN::Complete::cplx ;
2731 my($class, $word) = @_;
2732 # I believed for many years that this was sorted, today I
2733 # realized, it wasn't sorted anymore. Now (rev 1.301 / v 1.55) I
2734 # make it sorted again. Maybe sort was dropped when GNU-readline
2735 # support came in? The RCS file is difficult to read on that:-(
2736 sort grep /^\Q$word\E/, map { $_->id } $CPAN::META->all_objects($class);
2739 #-> sub CPAN::Complete::cpl_any ;
2743 cplx('CPAN::Author',$word),
2744 cplx('CPAN::Bundle',$word),
2745 cplx('CPAN::Distribution',$word),
2746 cplx('CPAN::Module',$word),
2750 #-> sub CPAN::Complete::cpl_reload ;
2752 my($word,$line,$pos) = @_;
2754 my(@words) = split " ", $line;
2755 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2756 my(@ok) = qw(cpan index);
2757 return @ok if @words == 1;
2758 return grep /^\Q$word\E/, @ok if @words == 2 && $word;
2761 #-> sub CPAN::Complete::cpl_option ;
2763 my($word,$line,$pos) = @_;
2765 my(@words) = split " ", $line;
2766 CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
2767 my(@ok) = qw(conf debug);
2768 return @ok if @words == 1;
2769 return grep /^\Q$word\E/, @ok if @words == 2 && length($word);
2771 } elsif ($words[1] eq 'index') {
2773 } elsif ($words[1] eq 'conf') {
2774 return CPAN::Config::cpl(@_);
2775 } elsif ($words[1] eq 'debug') {
2776 return sort grep /^\Q$word\E/, sort keys %CPAN::DEBUG, 'all';
2780 package CPAN::Index;
2782 #-> sub CPAN::Index::force_reload ;
2785 $CPAN::Index::last_time = 0;
2789 #-> sub CPAN::Index::reload ;
2791 my($cl,$force) = @_;
2794 # XXX check if a newer one is available. (We currently read it
2795 # from time to time)
2796 for ($CPAN::Config->{index_expire}) {
2797 $_ = 0.001 unless $_ && $_ > 0.001;
2799 $CPAN::META->{PROTOCOL} ||= "1.0";
2800 if ( $CPAN::META->{PROTOCOL} < PROTOCOL ) {
2801 # warn "Setting last_time to 0";
2802 $last_time = 0; # No warning necessary
2804 return if $last_time + $CPAN::Config->{index_expire}*86400 > $time
2807 # IFF we are developing, it helps to wipe out the memory
2808 # between reloads, otherwise it is not what a user expects.
2809 undef $CPAN::META; # Neue Gruendlichkeit since v1.52(r1.274)
2810 $CPAN::META = CPAN->new;
2814 local $last_time = $time;
2815 local $CPAN::META->{PROTOCOL} = PROTOCOL;
2817 my $needshort = $^O eq "dos";
2819 $cl->rd_authindex($cl
2821 "authors/01mailrc.txt.gz",
2823 File::Spec->catfile('authors', '01mailrc.gz') :
2824 File::Spec->catfile('authors', '01mailrc.txt.gz'),
2827 $debug = "timing reading 01[".($t2 - $time)."]";
2829 return if $CPAN::Signal; # this is sometimes lengthy
2830 $cl->rd_modpacks($cl
2832 "modules/02packages.details.txt.gz",
2834 File::Spec->catfile('modules', '02packag.gz') :
2835 File::Spec->catfile('modules', '02packages.details.txt.gz'),
2838 $debug .= "02[".($t2 - $time)."]";
2840 return if $CPAN::Signal; # this is sometimes lengthy
2843 "modules/03modlist.data.gz",
2845 File::Spec->catfile('modules', '03mlist.gz') :
2846 File::Spec->catfile('modules', '03modlist.data.gz'),
2848 $cl->write_metadata_cache;
2850 $debug .= "03[".($t2 - $time)."]";
2852 CPAN->debug($debug) if $CPAN::DEBUG;
2855 $CPAN::META->{PROTOCOL} = PROTOCOL;
2858 #-> sub CPAN::Index::reload_x ;
2860 my($cl,$wanted,$localname,$force) = @_;
2861 $force |= 2; # means we're dealing with an index here
2862 CPAN::Config->load; # we should guarantee loading wherever we rely
2864 $localname ||= $wanted;
2865 my $abs_wanted = MM->catfile($CPAN::Config->{'keep_source_where'},
2869 -M $abs_wanted < $CPAN::Config->{'index_expire'} &&
2872 my $s = $CPAN::Config->{'index_expire'} == 1 ? "" : "s";
2873 $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} }.
2874 qq{day$s. I\'ll use that.});
2877 $force |= 1; # means we're quite serious about it.
2879 return CPAN::FTP->localize($wanted,$abs_wanted,$force);
2882 #-> sub CPAN::Index::rd_authindex ;
2884 my($cl, $index_target) = @_;
2886 return unless defined $index_target;
2887 $CPAN::Frontend->myprint("Going to read $index_target\n");
2888 # my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
2889 # while ($_ = $fh->READLINE) {
2892 tie *FH, CPAN::Tarzip, $index_target;
2894 push @lines, split /\012/ while <FH>;
2896 my($userid,$fullname,$email) =
2897 m/alias\s+(\S+)\s+\"([^\"\<]+)\s+\<([^\>]+)\>\"/;
2898 next unless $userid && $fullname && $email;
2900 # instantiate an author object
2901 my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
2902 $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
2903 return if $CPAN::Signal;
2908 my($self,$dist) = @_;
2909 $dist = $self->{'id'} unless defined $dist;
2910 my($ret) = $dist =~ m|(?:\w/\w\w/)?([^/]+)/|;
2914 #-> sub CPAN::Index::rd_modpacks ;
2916 my($self, $index_target) = @_;
2918 return unless defined $index_target;
2919 $CPAN::Frontend->myprint("Going to read $index_target\n");
2920 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
2922 while ($_ = $fh->READLINE) {
2924 my @ls = map {"$_\n"} split /\n/, $_;
2925 unshift @ls, "\n" x length($1) if /^(\n+)/;
2931 my $shift = shift(@lines);
2932 $shift =~ /^Line-Count:\s+(\d+)/;
2933 $line_count = $1 if $1;
2934 last if $shift =~ /^\s*$/;
2936 if (not defined $line_count) {
2938 warn qq{Warning: Your $index_target does not contain a Line-Count header.
2939 Please check the validity of the index file by comparing it to more
2940 than one CPAN mirror. I'll continue but problems seem likely to
2945 } elsif ($line_count != scalar @lines) {
2947 warn sprintf qq{Warning: Your %s
2948 contains a Line-Count header of %d but I see %d lines there. Please
2949 check the validity of the index file by comparing it to more than one
2950 CPAN mirror. I'll continue but problems seem likely to happen.\a\n},
2951 $index_target, $line_count, scalar(@lines);
2954 # A necessity since we have metadata_cache: delete what isn't
2956 my $secondtime = $CPAN::META->exists("CPAN::Module","CPAN");
2957 CPAN->debug("secondtime[$secondtime]") if $CPAN::DEBUG;
2961 # before 1.56 we split into 3 and discarded the rest. From
2962 # 1.57 we assign remaining text to $comment thus allowing to
2963 # influence isa_perl
2964 my($mod,$version,$dist,$comment) = split " ", $_, 4;
2965 my($bundle,$id,$userid);
2967 if ($mod eq 'CPAN' &&
2969 CPAN::Queue->exists('Bundle::CPAN') ||
2970 CPAN::Queue->exists('CPAN')
2974 if ($version > $CPAN::VERSION){
2975 $CPAN::Frontend->myprint(qq{
2976 There's a new CPAN.pm version (v$version) available!
2977 [Current version is v$CPAN::VERSION]
2978 You might want to try
2979 install Bundle::CPAN
2981 without quitting the current session. It should be a seamless upgrade
2982 while we are running...
2985 $CPAN::Frontend->myprint(qq{\n});
2987 last if $CPAN::Signal;
2988 } elsif ($mod =~ /^Bundle::(.*)/) {
2993 $id = $CPAN::META->instance('CPAN::Bundle',$mod);
2994 # Let's make it a module too, because bundles have so much
2995 # in common with modules.
2997 # Changed in 1.57_63: seems like memory bloat now without
2998 # any value, so commented out
3000 # $CPAN::META->instance('CPAN::Module',$mod);
3004 # instantiate a module object
3005 $id = $CPAN::META->instance('CPAN::Module',$mod);
3009 if ($id->cpan_file ne $dist){ # update only if file is
3010 # different. CPAN prohibits same
3011 # name with different version
3012 $userid = $self->userid($dist);
3014 'CPAN_USERID' => $userid,
3015 'CPAN_VERSION' => $version,
3016 'CPAN_FILE' => $dist,
3020 # instantiate a distribution object
3021 if ($CPAN::META->exists('CPAN::Distribution',$dist)) {
3022 # we do not need CONTAINSMODS unless we do something with
3023 # this dist, so we better produce it on demand.
3025 ## my $obj = $CPAN::META->instance(
3026 ## 'CPAN::Distribution' => $dist
3028 ## $obj->{CONTAINSMODS}{$mod} = undef; # experimental
3030 $CPAN::META->instance(
3031 'CPAN::Distribution' => $dist
3033 'CPAN_USERID' => $userid,
3034 'CPAN_COMMENT' => $comment,
3038 for my $name ($mod,$dist) {
3039 CPAN->debug("exists name[$name]") if $CPAN::DEBUG;
3040 $exists{$name} = undef;
3043 return if $CPAN::Signal;
3047 for my $class (qw(CPAN::Module CPAN::Bundle CPAN::Distribution)) {
3048 for my $o ($CPAN::META->all_objects($class)) {
3049 next if exists $exists{$o->{ID}};
3050 $CPAN::META->delete($class,$o->{ID});
3051 CPAN->debug("deleting ID[$o->{ID}] in class[$class]")
3058 #-> sub CPAN::Index::rd_modlist ;
3060 my($cl,$index_target) = @_;
3061 return unless defined $index_target;
3062 $CPAN::Frontend->myprint("Going to read $index_target\n");
3063 my $fh = CPAN::Tarzip->TIEHANDLE($index_target);
3066 while ($_ = $fh->READLINE) {
3068 my @ls = map {"$_\n"} split /\n/, $_;
3069 unshift @ls, "\n" x length($1) if /^(\n+)/;
3073 my $shift = shift(@eval);
3074 if ($shift =~ /^Date:\s+(.*)/){
3075 return if $date_of_03 eq $1;
3078 last if $shift =~ /^\s*$/;
3081 push @eval, q{CPAN::Modulelist->data;};
3083 my($comp) = Safe->new("CPAN::Safe1");
3084 my($eval) = join("", @eval);
3085 my $ret = $comp->reval($eval);
3086 Carp::confess($@) if $@;
3087 return if $CPAN::Signal;
3089 my $obj = $CPAN::META->instance(CPAN::Module,$_);
3090 delete $ret->{$_}{modid}; # not needed here, maybe elsewhere
3091 $obj->set(%{$ret->{$_}});
3092 return if $CPAN::Signal;
3096 #-> sub CPAN::Index::write_metadata_cache ;
3097 sub write_metadata_cache {
3099 return unless $CPAN::Config->{'cache_metadata'};
3100 return unless $CPAN::META->has_usable("Storable");
3102 foreach my $k (qw(CPAN::Bundle CPAN::Author CPAN::Module
3103 CPAN::Distribution)) {
3104 $cache->{$k} = $CPAN::META->{readonly}{$k}; # unsafe meta access, ok
3106 my $metadata_file = MM->catfile($CPAN::Config->{cpan_home},"Metadata");
3107 $cache->{last_time} = $last_time;
3108 $cache->{PROTOCOL} = PROTOCOL;
3109 $CPAN::Frontend->myprint("Going to write $metadata_file\n");
3110 eval { Storable::nstore($cache, $metadata_file) };
3111 $CPAN::Frontend->mywarn($@) if $@;
3114 #-> sub CPAN::Index::read_metadata_cache ;
3115 sub read_metadata_cache {
3117 return unless $CPAN::Config->{'cache_metadata'};
3118 return unless $CPAN::META->has_usable("Storable");
3119 my $metadata_file = MM->catfile($CPAN::Config->{cpan_home},"Metadata");
3120 return unless -r $metadata_file and -f $metadata_file;
3121 $CPAN::Frontend->myprint("Going to read $metadata_file\n");
3123 eval { $cache = Storable::retrieve($metadata_file) };
3124 $CPAN::Frontend->mywarn($@) if $@;
3125 if (!$cache || ref $cache ne 'HASH'){
3129 if (exists $cache->{PROTOCOL}) {
3130 if (PROTOCOL > $cache->{PROTOCOL}) {
3131 $CPAN::Frontend->mywarn(sprintf("Ignoring Metadata cache written ".
3132 "with protocol v%s, requiring v%s",
3139 $CPAN::Frontend->mywarn("Ignoring Metadata cache written ".
3140 "with protocol v1.0");
3145 while(my($class,$v) = each %$cache) {
3146 next unless $class =~ /^CPAN::/;
3147 $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok
3148 while (my($id,$ro) = each %$v) {
3149 $CPAN::META->{readwrite}{$class}{$id} ||=
3150 $class->new(ID=>$id, RO=>$ro);
3155 unless ($clcnt) { # sanity check
3156 $CPAN::Frontend->myprint("Warning: Found no data in $metadata_file\n");
3159 if ($idcnt < 1000) {
3160 $CPAN::Frontend->myprint("Warning: Found only $idcnt objects ".
3161 "in $metadata_file\n");
3164 $CPAN::META->{PROTOCOL} ||=
3165 $cache->{PROTOCOL}; # reading does not up or downgrade, but it
3166 # does initialize to some protocol
3167 $last_time = $cache->{last_time};
3170 package CPAN::InfoObj;
3173 sub cpan_userid { shift->{RO}{CPAN_USERID} }
3174 sub id { shift->{ID} }
3176 #-> sub CPAN::InfoObj::new ;
3178 my $this = bless {}, shift;
3183 # The set method may only be used by code that reads index data or
3184 # otherwise "objective" data from the outside world. All session
3185 # related material may do anything else with instance variables but
3186 # must not touch the hash under the RO attribute. The reason is that
3187 # the RO hash gets written to Metadata file and is thus persistent.
3189 #-> sub CPAN::InfoObj::set ;
3191 my($self,%att) = @_;
3192 my $class = ref $self;
3194 # This must be ||=, not ||, because only if we write an empty
3195 # reference, only then the set method will write into the readonly
3196 # area. But for Distributions that spring into existence, maybe
3197 # because of a typo, we do not like it that they are written into
3198 # the readonly area and made permanent (at least for a while) and
3199 # that is why we do not "allow" other places to call ->set.
3200 my $ro = $self->{RO} =
3201 $CPAN::META->{readonly}{$class}{$self->id} ||= {};
3203 while (my($k,$v) = each %att) {
3208 #-> sub CPAN::InfoObj::as_glimpse ;
3212 my $class = ref($self);
3213 $class =~ s/^CPAN:://;
3214 push @m, sprintf "%-15s %s\n", $class, $self->{ID};
3218 #-> sub CPAN::InfoObj::as_string ;
3222 my $class = ref($self);
3223 $class =~ s/^CPAN:://;
3224 push @m, $class, " id = $self->{ID}\n";
3225 for (sort keys %{$self->{RO}}) {
3226 # next if m/^(ID|RO)$/;
3228 if ($_ eq "CPAN_USERID") {
3229 $extra .= " (".$self->author;
3230 my $email; # old perls!
3231 if ($email = $CPAN::META->instance(CPAN::Author,
3234 $extra .= " <$email>";
3236 $extra .= " <no email>";
3240 next unless defined $self->{RO}{$_};
3241 push @m, sprintf " %-12s %s%s\n", $_, $self->{RO}{$_}, $extra;
3243 for (sort keys %$self) {
3244 next if m/^(ID|RO)$/;
3245 if (ref($self->{$_}) eq "ARRAY") {
3246 push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
3247 } elsif (ref($self->{$_}) eq "HASH") {
3251 join(" ",keys %{$self->{$_}}),
3254 push @m, sprintf " %-12s %s\n", $_, $self->{$_};
3260 #-> sub CPAN::InfoObj::author ;
3263 $CPAN::META->instance(CPAN::Author,$self->cpan_userid)->fullname;
3266 #-> sub CPAN::InfoObj::dump ;
3269 require Data::Dumper;
3270 print Data::Dumper::Dumper($self);
3273 package CPAN::Author;
3275 #-> sub CPAN::Author::as_glimpse ;
3279 my $class = ref($self);
3280 $class =~ s/^CPAN:://;
3281 push @m, sprintf "%-15s %s (%s)\n", $class, $self->{ID}, $self->fullname;
3285 #-> sub CPAN::Author::fullname ;
3286 sub fullname { shift->{RO}{FULLNAME} }
3289 #-> sub CPAN::Author::email ;
3290 sub email { shift->{RO}{EMAIL} }
3292 package CPAN::Distribution;
3295 sub cpan_comment { shift->{RO}{CPAN_COMMENT} }
3299 delete $self->{later};
3302 #-> sub CPAN::Distribution::color_cmd_tmps ;
3303 sub color_cmd_tmps {
3305 my($depth) = shift || 0;
3306 my($color) = shift || 0;
3307 # a distribution needs to recurse into its prereq_pms
3309 return if exists $self->{incommandcolor}
3310 && $self->{incommandcolor}==$color;
3311 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
3312 "color_cmd_tmps depth[%s] self[%s] id[%s]",
3317 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
3318 my $prereq_pm = $self->prereq_pm;
3319 if (defined $prereq_pm) {
3320 for my $pre (keys %$prereq_pm) {
3321 my $premo = CPAN::Shell->expand("Module",$pre);
3322 $premo->color_cmd_tmps($depth+1,$color);
3326 delete $self->{sponsored_mods};
3327 delete $self->{badtestcnt};
3329 $self->{incommandcolor} = $color;
3332 #-> sub CPAN::Distribution::as_string ;
3335 $self->containsmods;
3336 $self->SUPER::as_string(@_);
3339 #-> sub CPAN::Distribution::containsmods ;
3342 return if exists $self->{CONTAINSMODS};
3343 for my $mod ($CPAN::META->all_objects("CPAN::Module")) {
3344 my $mod_file = $mod->cpan_file or next;
3345 my $dist_id = $self->{ID} or next;
3346 my $mod_id = $mod->{ID} or next;
3347 # warn "mod_file[$mod_file] dist_id[$dist_id] mod_id[$mod_id]";
3349 $self->{CONTAINSMODS}{$mod_id} = undef if $mod_file eq $dist_id;
3353 #-> sub CPAN::Distribution::called_for ;
3356 $self->{CALLED_FOR} = $id if defined $id;
3357 return $self->{CALLED_FOR};
3360 #-> sub CPAN::Distribution::get ;
3365 exists $self->{'build_dir'} and push @e,
3366 "Is already unwrapped into directory $self->{'build_dir'}";
3367 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3372 $CPAN::Config->{keep_source_where},
3375 split("/",$self->{ID})
3378 $self->debug("Doing localize") if $CPAN::DEBUG;
3380 CPAN::FTP->localize("authors/id/$self->{ID}", $local_wanted)
3381 or $CPAN::Frontend->mydie("Giving up on '$local_wanted'\n");
3382 return if $CPAN::Signal;
3383 $self->{localfile} = $local_file;
3384 $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new(); # unsafe meta access, ok
3385 my $builddir = $CPAN::META->{cachemgr}->dir; # unsafe meta access, ok
3386 $self->debug("doing chdir $builddir") if $CPAN::DEBUG;
3387 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
3390 $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
3391 if ($CPAN::META->has_inst("MD5")) {
3392 $self->debug("MD5 is installed, verifying");
3395 $self->debug("MD5 is NOT installed");
3397 $self->debug("Removing tmp") if $CPAN::DEBUG;
3398 File::Path::rmtree("tmp");
3399 mkdir "tmp", 0755 or Carp::croak "Couldn't mkdir tmp: $!";
3400 chdir "tmp" or $CPAN::Frontend->mydie(qq{Could not chdir to "tmp": $!});;
3401 $self->debug("Changed directory to tmp") if $CPAN::DEBUG;
3402 return if $CPAN::Signal;
3403 if (! $local_file) {
3404 Carp::croak "bad download, can't do anything :-(\n";
3405 } elsif ($local_file =~ /(\.tar\.(gz|Z)|\.tgz)(?!\n)\Z/i){
3406 $self->untar_me($local_file);
3407 } elsif ( $local_file =~ /\.zip(?!\n)\Z/i ) {
3408 $self->unzip_me($local_file);
3409 } elsif ( $local_file =~ /\.pm\.(gz|Z)(?!\n)\Z/) {
3410 $self->pm2dir_me($local_file);
3412 $self->{archived} = "NO";
3414 my $cwd = File::Spec->updir;
3415 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "": $!});
3416 if ($self->{archived} ne 'NO') {
3417 $cwd = File::Spec->catdir(File::Spec->curdir, "tmp");
3418 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
3419 # Let's check if the package has its own directory.
3420 my $dh = DirHandle->new(File::Spec->curdir)
3421 or Carp::croak("Couldn't opendir .: $!");
3422 my @readdir = grep $_ !~ /^\.\.?(?!\n)\Z/s, $dh->read; ### MAC??
3424 my ($distdir,$packagedir);
3425 if (@readdir == 1 && -d $readdir[0]) {
3426 $distdir = $readdir[0];
3427 $packagedir = MM->catdir($builddir,$distdir);
3428 -d $packagedir and $CPAN::Frontend->myprint("Removing previously used ".
3430 File::Path::rmtree($packagedir);
3431 rename($distdir,$packagedir) or
3432 Carp::confess("Couldn't rename $distdir to $packagedir: $!");
3434 my $pragmatic_dir = $self->cpan_userid . '000';
3435 $pragmatic_dir =~ s/\W_//g;
3436 $pragmatic_dir++ while -d "../$pragmatic_dir";
3437 $packagedir = MM->catdir($builddir,$pragmatic_dir);
3438 File::Path::mkpath($packagedir);
3440 for $f (@readdir) { # is already without "." and ".."
3441 my $to = MM->catdir($packagedir,$f);
3442 rename($f,$to) or Carp::confess("Couldn't rename $f to $to: $!");
3445 $self->{'build_dir'} = $packagedir;
3446 $cwd = File::Spec->updir;
3447 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
3449 $self->debug("Changed directory to .. (self[$self]=[".
3450 $self->as_string."])") if $CPAN::DEBUG;
3451 File::Path::rmtree("tmp");
3452 if ($CPAN::Config->{keep_source_where} =~ /^no/i ){
3453 $CPAN::Frontend->myprint("Going to unlink $local_file\n");
3454 unlink $local_file or Carp::carp "Couldn't unlink $local_file";
3456 my($makefilepl) = MM->catfile($packagedir,"Makefile.PL");
3457 unless (-f $makefilepl) {
3458 my($configure) = MM->catfile($packagedir,"Configure");
3459 if (-f $configure) {
3460 # do we have anything to do?
3461 $self->{'configure'} = $configure;
3462 } elsif (-f MM->catfile($packagedir,"Makefile")) {
3463 $CPAN::Frontend->myprint(qq{
3464 Package comes with a Makefile and without a Makefile.PL.
3465 We\'ll try to build it with that Makefile then.
3467 $self->{writemakefile} = "YES";
3470 my $fh = FileHandle->new(">$makefilepl")
3471 or Carp::croak("Could not open >$makefilepl");
3472 my $cf = $self->called_for || "unknown";
3474 qq{# This Makefile.PL has been autogenerated by the module CPAN.pm
3475 # because there was no Makefile.PL supplied.
3476 # Autogenerated on: }.scalar localtime().qq{
3478 use ExtUtils::MakeMaker;
3479 WriteMakefile(NAME => q[$cf]);
3482 $CPAN::Frontend->myprint(qq{Package comes without Makefile.PL.
3483 Writing one on our own (calling it $cf)\n});
3490 # CPAN::Distribution::untar_me ;
3492 my($self,$local_file) = @_;
3493 $self->{archived} = "tar";
3494 if (CPAN::Tarzip->untar($local_file)) {
3495 $self->{unwrapped} = "YES";
3497 $self->{unwrapped} = "NO";
3501 # CPAN::Distribution::unzip_me ;
3503 my($self,$local_file) = @_;
3504 $self->{archived} = "zip";
3505 if (CPAN::Tarzip->unzip($local_file)) {
3506 $self->{unwrapped} = "YES";
3508 $self->{unwrapped} = "NO";
3514 my($self,$local_file) = @_;
3515 $self->{archived} = "pm";
3516 my $to = File::Basename::basename($local_file);
3517 $to =~ s/\.(gz|Z)(?!\n)\Z//;
3518 if (CPAN::Tarzip->gunzip($local_file,$to)) {
3519 $self->{unwrapped} = "YES";
3521 $self->{unwrapped} = "NO";
3525 #-> sub CPAN::Distribution::new ;
3527 my($class,%att) = @_;
3529 # $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
3531 my $this = { %att };
3532 return bless $this, $class;
3535 #-> sub CPAN::Distribution::look ;
3539 if ($^O eq 'MacOS') {
3540 $self->ExtUtils::MM_MacOS::look;
3544 if ( $CPAN::Config->{'shell'} ) {
3545 $CPAN::Frontend->myprint(qq{
3546 Trying to open a subshell in the build directory...
3549 $CPAN::Frontend->myprint(qq{
3550 Your configuration does not define a value for subshells.
3551 Please define it with "o conf shell <your shell>"
3555 my $dist = $self->id;
3556 my $dir = $self->dir or $self->get;
3559 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
3560 my $pwd = CPAN->$getcwd();
3561 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
3562 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
3563 system($CPAN::Config->{'shell'}) == 0
3564 or $CPAN::Frontend->mydie("Subprocess shell error");
3565 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
3568 # CPAN::Distribution::cvs_import ;
3572 my $dir = $self->dir;
3574 my $package = $self->called_for;
3575 my $module = $CPAN::META->instance('CPAN::Module', $package);
3576 my $version = $module->cpan_version;
3578 my $userid = $self->cpan_userid;
3580 my $cvs_dir = (split '/', $dir)[-1];
3581 $cvs_dir =~ s/-\d+[^-]+(?!\n)\Z//;
3583 $CPAN::Config->{cvsroot} || $ENV{CVSROOT};
3585 $CPAN::Config->{cvs_site_perl} || $ENV{CVS_SITE_PERL};
3586 if ($cvs_site_perl) {
3587 $cvs_dir = "$cvs_site_perl/$cvs_dir";
3589 my $cvs_log = qq{"imported $package $version sources"};
3590 $version =~ s/\./_/g;
3591 my @cmd = ('cvs', '-d', $cvs_root, 'import', '-m', $cvs_log,
3592 "$cvs_dir", $userid, "v$version");
3595 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
3596 my $pwd = CPAN->$getcwd();
3597 chdir($dir) or $CPAN::Frontend->mydie(qq{Could not chdir to "$dir": $!});
3599 $CPAN::Frontend->myprint(qq{Working directory is $dir\n});
3601 $CPAN::Frontend->myprint(qq{@cmd\n});
3602 system(@cmd) == 0 or
3603 $CPAN::Frontend->mydie("cvs import failed");
3604 chdir($pwd) or $CPAN::Frontend->mydie(qq{Could not chdir to "$pwd": $!});
3607 #-> sub CPAN::Distribution::readme ;
3610 my($dist) = $self->id;
3611 my($sans,$suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/;
3612 $self->debug("sans[$sans] suffix[$suffix]\n") if $CPAN::DEBUG;
3616 $CPAN::Config->{keep_source_where},
3619 split("/","$sans.readme"),
3621 $self->debug("Doing localize") if $CPAN::DEBUG;
3622 $local_file = CPAN::FTP->localize("authors/id/$sans.readme",
3624 or $CPAN::Frontend->mydie(qq{No $sans.readme found});;
3626 if ($^O eq 'MacOS') {
3627 ExtUtils::MM_MacOS::launch_file($local_file);
3631 my $fh_pager = FileHandle->new;
3632 local($SIG{PIPE}) = "IGNORE";
3633 $fh_pager->open("|$CPAN::Config->{'pager'}")
3634 or die "Could not open pager $CPAN::Config->{'pager'}: $!";
3635 my $fh_readme = FileHandle->new;
3636 $fh_readme->open($local_file)
3637 or $CPAN::Frontend->mydie(qq{Could not open "$local_file": $!});
3638 $CPAN::Frontend->myprint(qq{
3641 with pager "$CPAN::Config->{'pager'}"
3644 $fh_pager->print(<$fh_readme>);
3647 #-> sub CPAN::Distribution::verifyMD5 ;
3652 $self->{MD5_STATUS} ||= "";
3653 $self->{MD5_STATUS} eq "OK" and push @e, "MD5 Checksum was ok";
3654 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3656 my($lc_want,$lc_file,@local,$basename);
3657 @local = split("/",$self->{ID});
3659 push @local, "CHECKSUMS";
3661 MM->catfile($CPAN::Config->{keep_source_where},
3662 "authors", "id", @local);
3667 $self->MD5_check_file($lc_want)
3669 return $self->{MD5_STATUS} = "OK";
3671 $lc_file = CPAN::FTP->localize("authors/id/@local",
3674 $local[-1] .= ".gz";
3675 $lc_file = CPAN::FTP->localize("authors/id/@local",
3678 $lc_file =~ s/\.gz(?!\n)\Z//;
3679 CPAN::Tarzip->gunzip("$lc_file.gz",$lc_file);
3684 $self->MD5_check_file($lc_file);
3687 #-> sub CPAN::Distribution::MD5_check_file ;
3688 sub MD5_check_file {
3689 my($self,$chk_file) = @_;
3690 my($cksum,$file,$basename);
3691 $file = $self->{localfile};
3692 $basename = File::Basename::basename($file);
3693 my $fh = FileHandle->new;
3694 if (open $fh, $chk_file){
3697 $eval =~ s/\015?\012/\n/g;
3699 my($comp) = Safe->new();
3700 $cksum = $comp->reval($eval);
3702 rename $chk_file, "$chk_file.bad";
3703 Carp::confess($@) if $@;
3706 Carp::carp "Could not open $chk_file for reading";
3709 if (exists $cksum->{$basename}{md5}) {
3710 $self->debug("Found checksum for $basename:" .
3711 "$cksum->{$basename}{md5}\n") if $CPAN::DEBUG;
3715 my $eq = $self->eq_MD5($fh,$cksum->{$basename}{'md5'});
3717 $fh = CPAN::Tarzip->TIEHANDLE($file);
3720 # had to inline it, when I tied it, the tiedness got lost on
3721 # the call to eq_MD5. (Jan 1998)
3725 while ($fh->READ($ref, 4096) > 0){
3728 my $hexdigest = $md5->hexdigest;
3729 $eq += $hexdigest eq $cksum->{$basename}{'md5-ungz'};
3733 $CPAN::Frontend->myprint("Checksum for $file ok\n");
3734 return $self->{MD5_STATUS} = "OK";
3736 $CPAN::Frontend->myprint(qq{\nChecksum mismatch for }.
3737 qq{distribution file. }.
3738 qq{Please investigate.\n\n}.
3740 $CPAN::META->instance(
3745 my $wrap = qq{I\'d recommend removing $file. Its MD5
3746 checksum is incorrect. Maybe you have configured your 'urllist' with
3747 a bad URL. Please check this array with 'o conf urllist', and
3750 $CPAN::Frontend->mydie(Text::Wrap::wrap("","",$wrap));
3752 # former versions just returned here but this seems a
3753 # serious threat that deserves a die
3755 # $CPAN::Frontend->myprint("\n\n");
3759 # close $fh if fileno($fh);
3761 $self->{MD5_STATUS} ||= "";
3762 if ($self->{MD5_STATUS} eq "NIL") {
3763 $CPAN::Frontend->myprint(qq{
3764 No md5 checksum for $basename in local $chk_file.
3767 unlink $chk_file or $CPAN::Frontend->myprint("Could not unlink: $!");
3770 $self->{MD5_STATUS} = "NIL";
3775 #-> sub CPAN::Distribution::eq_MD5 ;
3777 my($self,$fh,$expectMD5) = @_;
3780 while (read($fh, $data, 4096)){
3783 # $md5->addfile($fh);
3784 my $hexdigest = $md5->hexdigest;
3785 # warn "fh[$fh] hex[$hexdigest] aexp[$expectMD5]";
3786 $hexdigest eq $expectMD5;
3789 #-> sub CPAN::Distribution::force ;
3791 # Both modules and distributions know if "force" is in effect by
3792 # autoinspection, not by inspecting a global variable. One of the
3793 # reason why this was chosen to work that way was the treatment of
3794 # dependencies. They should not autpomatically inherit the force
3795 # status. But this has the downside that ^C and die() will return to
3796 # the prompt but will not be able to reset the force_update
3797 # attributes. We try to correct for it currently in the read_metadata
3798 # routine, and immediately before we check for a Signal. I hope this
3799 # works out in one of v1.57_53ff
3802 my($self, $method) = @_;
3804 MD5_STATUS archived build_dir localfile make install unwrapped
3807 delete $self->{$att};
3809 if ($method && $method eq "install") {
3810 $self->{"force_update"}++; # name should probably have been force_install
3814 #-> sub CPAN::Distribution::unforce ;
3817 delete $self->{'force_update'};
3820 #-> sub CPAN::Distribution::isa_perl ;
3823 my $file = File::Basename::basename($self->id);
3824 if ($file =~ m{ ^ perl
3837 } elsif ($self->cpan_comment
3839 $self->cpan_comment =~ /isa_perl\(.+?\)/){
3844 #-> sub CPAN::Distribution::perl ;
3847 my($perl) = MM->file_name_is_absolute($^X) ? $^X : "";
3848 my $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
3849 my $pwd = CPAN->$getcwd();
3850 my $candidate = MM->catfile($pwd,$^X);
3851 $perl ||= $candidate if MM->maybe_command($candidate);
3853 my ($component,$perl_name);
3854 DIST_PERLNAME: foreach $perl_name ($^X, 'perl', 'perl5', "perl$]") {
3855 PATH_COMPONENT: foreach $component (MM->path(),
3856 $Config::Config{'binexp'}) {
3857 next unless defined($component) && $component;
3858 my($abs) = MM->catfile($component,$perl_name);
3859 if (MM->maybe_command($abs)) {
3869 #-> sub CPAN::Distribution::make ;
3872 $CPAN::Frontend->myprint(sprintf "Running make for %s\n", $self->id);
3873 # Emergency brake if they said install Pippi and get newest perl
3874 if ($self->isa_perl) {
3876 $self->called_for ne $self->id &&
3877 ! $self->{force_update}
3879 # if we die here, we break bundles
3880 $CPAN::Frontend->mywarn(sprintf qq{
3881 The most recent version "%s" of the module "%s"
3882 comes with the current version of perl (%s).
3883 I\'ll build that only if you ask for something like
3888 $CPAN::META->instance(
3902 $self->{archived} eq "NO" and push @e,
3903 "Is neither a tar nor a zip archive.";
3905 $self->{unwrapped} eq "NO" and push @e,
3906 "had problems unarchiving. Please build manually";
3908 exists $self->{writemakefile} &&
3909 $self->{writemakefile} =~ m/ ^ NO\s* ( .* ) /sx and push @e,
3910 $1 || "Had some problem writing Makefile";
3912 defined $self->{'make'} and push @e,
3913 "Has already been processed within this session";
3915 exists $self->{later} and length($self->{later}) and
3916 push @e, $self->{later};
3918 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
3920 $CPAN::Frontend->myprint("\n CPAN.pm: Going to build ".$self->id."\n\n");
3921 my $builddir = $self->dir;
3922 chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
3923 $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
3925 if ($^O eq 'MacOS') {
3926 ExtUtils::MM_MacOS::make($self);
3931 if ($self->{'configure'}) {
3932 $system = $self->{'configure'};
3934 my($perl) = $self->perl or die "Couldn\'t find executable perl\n";
3936 # This needs a handler that can be turned on or off:
3937 # $switch = "-MExtUtils::MakeMaker ".
3938 # "-Mops=:default,:filesys_read,:filesys_open,require,chdir"
3940 $system = "$perl $switch Makefile.PL $CPAN::Config->{makepl_arg}";
3942 unless (exists $self->{writemakefile}) {
3943 local($SIG{ALRM}) = sub { die "inactivity_timeout reached\n" };
3946 if ($CPAN::Config->{inactivity_timeout}) {
3948 alarm $CPAN::Config->{inactivity_timeout};
3949 local $SIG{CHLD}; # = sub { wait };
3950 if (defined($pid = fork)) {
3955 # note, this exec isn't necessary if
3956 # inactivity_timeout is 0. On the Mac I'd
3957 # suggest, we set it always to 0.
3961 $CPAN::Frontend->myprint("Cannot fork: $!");
3969 $CPAN::Frontend->myprint($@);
3970 $self->{writemakefile} = "NO $@";
3975 $ret = system($system);
3977 $self->{writemakefile} = "NO Makefile.PL returned status $ret";
3981 if (-f "Makefile") {
3982 $self->{writemakefile} = "YES";
3983 delete $self->{make_clean}; # if cleaned before, enable next
3985 $self->{writemakefile} =
3986 qq{NO Makefile.PL refused to write a Makefile.};
3987 # It's probably worth to record the reason, so let's retry
3989 # my $fh = IO::File->new("$system |"); # STDERR? STDIN?
3990 # $self->{writemakefile} .= <$fh>;
3994 delete $self->{force_update};
3997 if (my @prereq = $self->unsat_prereq){
3998 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4000 $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
4001 if (system($system) == 0) {
4002 $CPAN::Frontend->myprint(" $system -- OK\n");
4003 $self->{'make'} = "YES";
4005 $self->{writemakefile} ||= "YES";
4006 $self->{'make'} = "NO";
4007 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4011 sub follow_prereqs {
4015 $CPAN::Frontend->myprint("---- Unsatisfied dependencies detected ".
4016 "during [$id] -----\n");
4018 for my $p (@prereq) {
4019 $CPAN::Frontend->myprint(" $p\n");
4022 if ($CPAN::Config->{prerequisites_policy} eq "follow") {
4024 } elsif ($CPAN::Config->{prerequisites_policy} eq "ask") {
4025 require ExtUtils::MakeMaker;
4026 my $answer = ExtUtils::MakeMaker::prompt(
4027 "Shall I follow them and prepend them to the queue
4028 of modules we are processing right now?", "yes");
4029 $follow = $answer =~ /^\s*y/i;
4033 myprint(" Ignoring dependencies on modules @prereq\n");
4036 # color them as dirty
4037 for my $p (@prereq) {
4038 CPAN::Shell->expandany($p)->color_cmd_tmps(0,1);
4040 CPAN::Queue->jumpqueue(@prereq,$id); # queue them and requeue yourself
4041 $self->{later} = "Delayed until after prerequisites";
4042 return 1; # signal success to the queuerunner
4046 #-> sub CPAN::Distribution::unsat_prereq ;
4049 my $prereq_pm = $self->prereq_pm or return;
4051 NEED: while (my($need_module, $need_version) = each %$prereq_pm) {
4052 my $nmo = $CPAN::META->instance("CPAN::Module",$need_module);
4053 # we were too demanding:
4054 next if $nmo->uptodate;
4056 # if they have not specified a version, we accept any installed one
4057 if (not defined $need_version or
4058 $need_version == 0 or
4059 $need_version eq "undef") {
4060 next if defined $nmo->inst_file;
4063 # We only want to install prereqs if either they're not installed
4064 # or if the installed version is too old. We cannot omit this
4065 # check, because if 'force' is in effect, nobody else will check.
4069 defined $nmo->inst_file &&
4070 ! CPAN::Version->vgt($need_version, $nmo->inst_version)
4072 CPAN->debug(sprintf "id[%s]inst_file[%s]inst_version[%s]need_version[%s]",
4076 CPAN::Version->readable($need_version)
4082 if ($self->{sponsored_mods}{$need_module}++){
4083 # We have already sponsored it and for some reason it's still
4084 # not available. So we do nothing. Or what should we do?
4085 # if we push it again, we have a potential infinite loop
4088 push @need, $need_module;
4093 #-> sub CPAN::Distribution::prereq_pm ;
4096 return $self->{prereq_pm} if
4097 exists $self->{prereq_pm_detected} && $self->{prereq_pm_detected};
4098 return unless $self->{writemakefile}; # no need to have succeeded
4099 # but we must have run it
4100 my $build_dir = $self->{build_dir} or die "Panic: no build_dir?";
4101 my $makefile = File::Spec->catfile($build_dir,"Makefile");
4106 $fh = FileHandle->new("<$makefile\0")) {
4110 # A.Speer @p -> %p, where %p is $p{Module::Name}=Required_Version
4112 last if /MakeMaker post_initialize section/;
4114 \s+PREREQ_PM\s+=>\s+(.+)
4117 # warn "Found prereq expr[$p]";
4119 # Regexp modified by A.Speer to remember actual version of file
4120 # PREREQ_PM hash key wants, then add to
4121 while ( $p =~ m/(?:\s)([\w\:]+)=>q\[(.*?)\],?/g ){
4122 # In case a prereq is mentioned twice, complain.
4123 if ( defined $p{$1} ) {
4124 warn "Warning: PREREQ_PM mentions $1 more than once, last mention wins";
4131 $self->{prereq_pm_detected}++;
4132 return $self->{prereq_pm} = \%p;
4135 #-> sub CPAN::Distribution::test ;
4140 delete $self->{force_update};
4143 $CPAN::Frontend->myprint("Running make test\n");
4144 if (my @prereq = $self->unsat_prereq){
4145 return 1 if $self->follow_prereqs(@prereq); # signal success to the queuerunner
4149 exists $self->{make} or exists $self->{later} or push @e,
4150 "Make had some problems, maybe interrupted? Won't test";
4152 exists $self->{'make'} and
4153 $self->{'make'} eq 'NO' and
4154 push @e, "Can't test without successful make";
4156 exists $self->{build_dir} or push @e, "Has no own directory";
4157 $self->{badtestcnt} ||= 0;
4158 $self->{badtestcnt} > 0 and
4159 push @e, "Won't repeat unsuccessful test during this command";
4161 exists $self->{later} and length($self->{later}) and
4162 push @e, $self->{later};
4164 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4166 chdir $self->{'build_dir'} or
4167 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4168 $self->debug("Changed directory to $self->{'build_dir'}")
4171 if ($^O eq 'MacOS') {
4172 ExtUtils::MM_MacOS::make_test($self);
4176 my $system = join " ", $CPAN::Config->{'make'}, "test";
4177 if (system($system) == 0) {
4178 $CPAN::Frontend->myprint(" $system -- OK\n");
4179 $self->{make_test} = "YES";
4181 $self->{make_test} = "NO";
4182 $self->{badtestcnt}++;
4183 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4187 #-> sub CPAN::Distribution::clean ;
4190 $CPAN::Frontend->myprint("Running make clean\n");
4193 exists $self->{make_clean} and $self->{make_clean} eq "YES" and
4194 push @e, "make clean already called once";
4195 exists $self->{build_dir} or push @e, "Has no own directory";
4196 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4198 chdir $self->{'build_dir'} or
4199 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4200 $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
4202 if ($^O eq 'MacOS') {
4203 ExtUtils::MM_MacOS::make_clean($self);
4207 my $system = join " ", $CPAN::Config->{'make'}, "clean";
4208 if (system($system) == 0) {
4209 $CPAN::Frontend->myprint(" $system -- OK\n");
4213 # Jost Krieger pointed out that this "force" was wrong because
4214 # it has the effect that the next "install" on this distribution
4215 # will untar everything again. Instead we should bring the
4216 # object's state back to where it is after untarring.
4218 delete $self->{force_update};
4219 delete $self->{install};
4220 delete $self->{writemakefile};
4221 delete $self->{make};
4222 delete $self->{make_test}; # no matter if yes or no, tests must be redone
4223 $self->{make_clean} = "YES";
4226 # Hmmm, what to do if make clean failed?
4228 $CPAN::Frontend->myprint(qq{ $system -- NOT OK
4230 make clean did not succeed, marking directory as unusable for further work.
4232 $self->force("make"); # so that this directory won't be used again
4237 #-> sub CPAN::Distribution::install ;
4242 delete $self->{force_update};
4245 $CPAN::Frontend->myprint("Running make install\n");
4248 exists $self->{build_dir} or push @e, "Has no own directory";
4250 exists $self->{make} or exists $self->{later} or push @e,
4251 "Make had some problems, maybe interrupted? Won't install";
4253 exists $self->{'make'} and
4254 $self->{'make'} eq 'NO' and
4255 push @e, "make had returned bad status, install seems impossible";
4257 push @e, "make test had returned bad status, ".
4258 "won't install without force"
4259 if exists $self->{'make_test'} and
4260 $self->{'make_test'} eq 'NO' and
4261 ! $self->{'force_update'};
4263 exists $self->{'install'} and push @e,
4264 $self->{'install'} eq "YES" ?
4265 "Already done" : "Already tried without success";
4267 exists $self->{later} and length($self->{later}) and
4268 push @e, $self->{later};
4270 $CPAN::Frontend->myprint(join "", map {" $_\n"} @e) and return if @e;
4272 chdir $self->{'build_dir'} or
4273 Carp::croak("Couldn't chdir to $self->{'build_dir'}");
4274 $self->debug("Changed directory to $self->{'build_dir'}")
4277 if ($^O eq 'MacOS') {
4278 ExtUtils::MM_MacOS::make_install($self);
4282 my $system = join(" ", $CPAN::Config->{'make'},
4283 "install", $CPAN::Config->{make_install_arg});
4284 my($stderr) = $^O =~ /Win/i ? "" : " 2>&1 ";
4285 my($pipe) = FileHandle->new("$system $stderr |");
4288 $CPAN::Frontend->myprint($_);
4293 $CPAN::Frontend->myprint(" $system -- OK\n");
4294 return $self->{'install'} = "YES";
4296 $self->{'install'} = "NO";
4297 $CPAN::Frontend->myprint(" $system -- NOT OK\n");
4298 if ($makeout =~ /permission/s && $> > 0) {
4299 $CPAN::Frontend->myprint(qq{ You may have to su }.
4300 qq{to root to install the package\n});
4303 delete $self->{force_update};
4306 #-> sub CPAN::Distribution::dir ;
4308 shift->{'build_dir'};
4311 package CPAN::Bundle;
4315 delete $self->{later};
4316 for my $c ( $self->contains ) {
4317 my $obj = CPAN::Shell->expandany($c) or next;
4322 #-> sub CPAN::Bundle::color_cmd_tmps ;
4323 sub color_cmd_tmps {
4325 my($depth) = shift || 0;
4326 my($color) = shift || 0;
4327 # a module needs to recurse to its cpan_file, a distribution needs
4328 # to recurse into its prereq_pms, a bundle needs to recurse into its modules
4330 return if exists $self->{incommandcolor}
4331 && $self->{incommandcolor}==$color;
4332 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
4333 "color_cmd_tmps depth[%s] self[%s] id[%s]",
4338 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
4340 for my $c ( $self->contains ) {
4341 my $obj = CPAN::Shell->expandany($c) or next;
4342 CPAN->debug("c[$c]obj[$obj]") if $CPAN::DEBUG;
4343 $obj->color_cmd_tmps($depth+1,$color);
4346 delete $self->{badtestcnt};
4348 $self->{incommandcolor} = $color;
4351 #-> sub CPAN::Bundle::as_string ;
4355 # following line must be "=", not "||=" because we have a moving target
4356 $self->{INST_VERSION} = $self->inst_version;
4357 return $self->SUPER::as_string;
4360 #-> sub CPAN::Bundle::contains ;
4363 my($parsefile) = $self->inst_file;
4364 my($id) = $self->id;
4365 $self->debug("parsefile[$parsefile]id[$id]") if $CPAN::DEBUG;
4366 unless ($parsefile) {
4367 # Try to get at it in the cpan directory
4368 $self->debug("no parsefile") if $CPAN::DEBUG;
4369 Carp::confess "I don't know a $id" unless $self->cpan_file;
4370 my $dist = $CPAN::META->instance('CPAN::Distribution',
4373 $self->debug($dist->as_string) if $CPAN::DEBUG;
4374 my($todir) = $CPAN::Config->{'cpan_home'};
4375 my(@me,$from,$to,$me);
4376 @me = split /::/, $self->id;
4378 $me = MM->catfile(@me);
4379 $from = $self->find_bundle_file($dist->{'build_dir'},$me);
4380 $to = MM->catfile($todir,$me);
4381 File::Path::mkpath(File::Basename::dirname($to));
4382 File::Copy::copy($from, $to)
4383 or Carp::confess("Couldn't copy $from to $to: $!");
4387 my $fh = FileHandle->new;
4389 open($fh,$parsefile) or die "Could not open '$parsefile': $!";
4391 $self->debug("parsefile[$parsefile]") if $CPAN::DEBUG;
4393 $in_cont = m/^=(?!head1\s+CONTENTS)/ ? 0 :
4394 m/^=head1\s+CONTENTS/ ? 1 : $in_cont;
4395 next unless $in_cont;
4400 push @result, (split " ", $_, 2)[0];
4403 delete $self->{STATUS};
4404 $self->{CONTAINS} = \@result;
4405 $self->debug("CONTAINS[@result]") if $CPAN::DEBUG;
4407 $CPAN::Frontend->mywarn(qq{
4408 The bundle file "$parsefile" may be a broken
4409 bundlefile. It seems not to contain any bundle definition.
4410 Please check the file and if it is bogus, please delete it.
4411 Sorry for the inconvenience.
4417 #-> sub CPAN::Bundle::find_bundle_file
4418 sub find_bundle_file {
4419 my($self,$where,$what) = @_;
4420 $self->debug("where[$where]what[$what]") if $CPAN::DEBUG;
4421 ### The following two lines let CPAN.pm become Bundle/CPAN.pm :-(
4422 ### my $bu = MM->catfile($where,$what);
4423 ### return $bu if -f $bu;
4424 my $manifest = MM->catfile($where,"MANIFEST");
4425 unless (-f $manifest) {
4426 require ExtUtils::Manifest;
4427 my $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
4428 my $cwd = CPAN->$getcwd();
4429 chdir $where or $CPAN::Frontend->mydie(qq{Could not chdir to "$where": $!});
4430 ExtUtils::Manifest::mkmanifest();
4431 chdir $cwd or $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd": $!});
4433 my $fh = FileHandle->new($manifest)
4434 or Carp::croak("Couldn't open $manifest: $!");
4437 if ($^O eq 'MacOS') {
4440 $what2 =~ s/:Bundle://;
4443 $what2 =~ s|Bundle[/\\]||;
4448 my($file) = /(\S+)/;
4449 if ($file =~ m|\Q$what\E$|) {
4451 # return MM->catfile($where,$bu); # bad
4454 # retry if she managed to
4455 # have no Bundle directory
4456 $bu = $file if $file =~ m|\Q$what2\E$|;
4458 $bu =~ tr|/|:| if $^O eq 'MacOS';
4459 return MM->catfile($where, $bu) if $bu;
4460 Carp::croak("Couldn't find a Bundle file in $where");
4463 # needs to work slightly different from Module::inst_file because of
4464 # cpan_home/Bundle/ directory.
4466 #-> sub CPAN::Bundle::inst_file ;
4469 return $self->{INST_FILE} if
4470 exists $self->{INST_FILE} && $self->{INST_FILE};
4473 @me = split /::/, $self->id;
4475 $inst_file = MM->catfile($CPAN::Config->{'cpan_home'}, @me);
4476 return $self->{INST_FILE} = $inst_file if -f $inst_file;
4477 $self->SUPER::inst_file;
4480 #-> sub CPAN::Bundle::rematein ;
4482 my($self,$meth) = @_;
4483 $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
4484 my($id) = $self->id;
4485 Carp::croak "Can't $meth $id, don't have an associated bundle file. :-(\n"
4486 unless $self->inst_file || $self->cpan_file;
4488 for $s ($self->contains) {
4489 my($type) = $s =~ m|/| ? 'CPAN::Distribution' :
4490 $s =~ m|^Bundle::| ? 'CPAN::Bundle' : 'CPAN::Module';
4491 if ($type eq 'CPAN::Distribution') {
4492 $CPAN::Frontend->mywarn(qq{
4493 The Bundle }.$self->id.qq{ contains
4494 explicitly a file $s.
4498 # possibly noisy action:
4499 $self->debug("type[$type] s[$s]") if $CPAN::DEBUG;
4500 my $obj = $CPAN::META->instance($type,$s);
4502 if ($obj->isa(CPAN::Bundle)
4504 exists $obj->{install_failed}
4506 ref($obj->{install_failed}) eq "HASH"
4508 for (keys %{$obj->{install_failed}}) {
4509 $self->{install_failed}{$_} = undef; # propagate faiure up
4512 $fail{$s} = 1; # the bundle itself may have succeeded but
4517 $success = $obj->can("uptodate") ? $obj->uptodate : 0;
4518 $success ||= $obj->{'install'} && $obj->{'install'} eq "YES";
4520 delete $self->{install_failed}{$s};
4527 # recap with less noise
4528 if ( $meth eq "install" ) {
4531 my $raw = sprintf(qq{Bundle summary:
4532 The following items in bundle %s had installation problems:},
4535 $CPAN::Frontend->myprint(Text::Wrap::fill("","",$raw));
4536 $CPAN::Frontend->myprint("\n");
4539 for $s ($self->contains) {
4541 $paragraph .= "$s ";
4542 $self->{install_failed}{$s} = undef;
4543 $reported{$s} = undef;
4546 my $report_propagated;
4547 for $s (sort keys %{$self->{install_failed}}) {
4548 next if exists $reported{$s};
4549 $paragraph .= "and the following items had problems
4550 during recursive bundle calls: " unless $report_propagated++;
4551 $paragraph .= "$s ";
4553 $CPAN::Frontend->myprint(Text::Wrap::fill(" "," ",$paragraph));
4554 $CPAN::Frontend->myprint("\n");
4556 $self->{'install'} = 'YES';
4561 #sub CPAN::Bundle::xs_file
4563 # If a bundle contains another that contains an xs_file we have
4564 # here, we just don't bother I suppose
4568 #-> sub CPAN::Bundle::force ;
4569 sub force { shift->rematein('force',@_); }
4570 #-> sub CPAN::Bundle::get ;
4571 sub get { shift->rematein('get',@_); }
4572 #-> sub CPAN::Bundle::make ;
4573 sub make { shift->rematein('make',@_); }
4574 #-> sub CPAN::Bundle::test ;
4577 $self->{badtestcnt} ||= 0;
4578 $self->rematein('test',@_);
4580 #-> sub CPAN::Bundle::install ;
4583 $self->rematein('install',@_);
4585 #-> sub CPAN::Bundle::clean ;
4586 sub clean { shift->rematein('clean',@_); }
4588 #-> sub CPAN::Bundle::readme ;
4591 my($file) = $self->cpan_file or $CPAN::Frontend->myprint(qq{
4592 No File found for bundle } . $self->id . qq{\n}), return;
4593 $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
4594 $CPAN::META->instance('CPAN::Distribution',$file)->readme;
4597 package CPAN::Module;
4600 # sub cpan_userid { shift->{RO}{CPAN_USERID} }
4603 return unless exists $self->{RO}{userid};
4604 $self->{RO}{userid};
4606 sub description { shift->{RO}{description} }
4610 delete $self->{later};
4611 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
4616 #-> sub CPAN::Module::color_cmd_tmps ;
4617 sub color_cmd_tmps {
4619 my($depth) = shift || 0;
4620 my($color) = shift || 0;
4621 # a module needs to recurse to its cpan_file
4623 return if exists $self->{incommandcolor}
4624 && $self->{incommandcolor}==$color;
4625 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: deep recursion in ".
4626 "color_cmd_tmps depth[%s] self[%s] id[%s]",
4631 ##### warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
4633 if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
4634 $dist->color_cmd_tmps($depth+1,$color);
4637 delete $self->{badtestcnt};
4639 $self->{incommandcolor} = $color;
4642 #-> sub CPAN::Module::as_glimpse ;
4646 my $class = ref($self);
4647 $class =~ s/^CPAN:://;
4648 push @m, sprintf("%-15s %-15s (%s)\n", $class, $self->{ID},
4653 #-> sub CPAN::Module::as_string ;
4657 CPAN->debug($self) if $CPAN::DEBUG;
4658 my $class = ref($self);
4659 $class =~ s/^CPAN:://;
4661 push @m, $class, " id = $self->{ID}\n";
4662 my $sprintf = " %-12s %s\n";
4663 push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
4664 if $self->description;
4665 my $sprintf2 = " %-12s %s (%s)\n";
4667 if ($userid = $self->cpan_userid || $self->userid){
4669 if ($author = CPAN::Shell->expand('Author',$userid)) {
4672 if ($m = $author->email) {
4679 $author->fullname . $email
4683 push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
4684 if $self->cpan_version;
4685 push @m, sprintf($sprintf, 'CPAN_FILE', $self->cpan_file)
4686 if $self->cpan_file;
4687 my $sprintf3 = " %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
4688 my(%statd,%stats,%statl,%stati);
4689 @statd{qw,? i c a b R M S,} = qw,unknown idea
4690 pre-alpha alpha beta released mature standard,;
4691 @stats{qw,? m d u n,} = qw,unknown mailing-list
4692 developer comp.lang.perl.* none,;
4693 @statl{qw,? p c + o h,} = qw,unknown perl C C++ other hybrid,;
4694 @stati{qw,? f r O h,} = qw,unknown functions
4695 references+ties object-oriented hybrid,;
4696 $statd{' '} = 'unknown';
4697 $stats{' '} = 'unknown';
4698 $statl{' '} = 'unknown';
4699 $stati{' '} = 'unknown';
4707 $statd{$self->{RO}{statd}},
4708 $stats{$self->{RO}{stats}},
4709 $statl{$self->{RO}{statl}},
4710 $stati{$self->{RO}{stati}}
4711 ) if $self->{RO}{statd};
4712 my $local_file = $self->inst_file;
4714 $self->{MANPAGE} ||= $self->manpage_headline($local_file);
4717 for $item (qw/MANPAGE/) {
4718 push @m, sprintf($sprintf, $item, $self->{$item})
4719 if exists $self->{$item};
4721 for $item (qw/CONTAINS/) {
4722 push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
4723 if exists $self->{$item} && @{$self->{$item}};
4725 push @m, sprintf($sprintf, 'INST_FILE',
4726 $local_file || "(not installed)");
4727 push @m, sprintf($sprintf, 'INST_VERSION',
4728 $self->inst_version) if $local_file;
4732 sub manpage_headline {
4733 my($self,$local_file) = @_;
4734 my(@local_file) = $local_file;
4735 $local_file =~ s/\.pm(?!\n)\Z/.pod/;
4736 push @local_file, $local_file;
4738 for $locf (@local_file) {
4739 next unless -f $locf;
4740 my $fh = FileHandle->new($locf)
4741 or $Carp::Frontend->mydie("Couldn't open $locf: $!");
4745 $inpod = m/^=(?!head1\s+NAME)/ ? 0 :
4746 m/^=head1\s+NAME/ ? 1 : $inpod;
4759 #-> sub CPAN::Module::cpan_file ;
4762 CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
4763 unless (defined $self->{RO}{CPAN_FILE}) {
4764 CPAN::Index->reload;
4766 if (exists $self->{RO}{CPAN_FILE} && defined $self->{RO}{CPAN_FILE}){
4767 return $self->{RO}{CPAN_FILE};
4768 } elsif ( defined $self->userid ) {
4769 my $fullname = $CPAN::META->instance("CPAN::Author",
4770 $self->userid)->fullname;
4771 my $email = $CPAN::META->instance("CPAN::Author",
4772 $self->userid)->email;
4773 unless (defined $fullname && defined $email) {
4774 my $userid = $self->userid;
4775 return sprintf("Contact Author %s (Try 'a %s')",
4780 return "Contact Author $fullname <$email>";
4786 *name = \&cpan_file;
4788 #-> sub CPAN::Module::cpan_version ;
4792 $self->{RO}{CPAN_VERSION} = 'undef'
4793 unless defined $self->{RO}{CPAN_VERSION};
4794 # I believe this is always a bug in the index and should be reported
4795 # as such, but usually I find out such an error and do not want to
4796 # provoke too many bugreports
4798 $self->{RO}{CPAN_VERSION};
4801 #-> sub CPAN::Module::force ;
4804 $self->{'force_update'}++;
4807 #-> sub CPAN::Module::rematein ;
4809 my($self,$meth) = @_;
4810 $CPAN::Frontend->myprint(sprintf("Running %s for module %s\n",
4813 my $cpan_file = $self->cpan_file;
4814 if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/){
4815 $CPAN::Frontend->mywarn(sprintf qq{
4816 The module %s isn\'t available on CPAN.
4818 Either the module has not yet been uploaded to CPAN, or it is
4819 temporary unavailable. Please contact the author to find out
4820 more about the status. Try 'i %s'.
4827 my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
4828 $pack->called_for($self->id);
4829 $pack->force($meth) if exists $self->{'force_update'};
4831 $pack->unforce if $pack->can("unforce") && exists $self->{'force_update'};
4832 delete $self->{'force_update'};
4835 #-> sub CPAN::Module::readme ;
4836 sub readme { shift->rematein('readme') }
4837 #-> sub CPAN::Module::look ;
4838 sub look { shift->rematein('look') }
4839 #-> sub CPAN::Module::cvs_import ;
4840 sub cvs_import { shift->rematein('cvs_import') }
4841 #-> sub CPAN::Module::get ;
4842 sub get { shift->rematein('get',@_); }
4843 #-> sub CPAN::Module::make ;
4846 $self->rematein('make');
4848 #-> sub CPAN::Module::test ;
4851 $self->{badtestcnt} ||= 0;
4852 $self->rematein('test',@_);
4854 #-> sub CPAN::Module::uptodate ;
4857 my($latest) = $self->cpan_version;
4859 my($inst_file) = $self->inst_file;
4861 if (defined $inst_file) {
4862 $have = $self->inst_version;
4867 ! CPAN::Version->vgt($latest, $have)
4869 CPAN->debug("returning uptodate. inst_file[$inst_file] ".
4870 "latest[$latest] have[$have]") if $CPAN::DEBUG;
4875 #-> sub CPAN::Module::install ;
4881 not exists $self->{'force_update'}
4883 $CPAN::Frontend->myprint( $self->id. " is up to date.\n");
4887 $self->rematein('install') if $doit;
4889 #-> sub CPAN::Module::clean ;
4890 sub clean { shift->rematein('clean') }
4892 #-> sub CPAN::Module::inst_file ;
4896 @packpath = split /::/, $self->{ID};
4897 $packpath[-1] .= ".pm";
4898 foreach $dir (@INC) {
4899 my $pmfile = MM->catfile($dir,@packpath);
4907 #-> sub CPAN::Module::xs_file ;
4911 @packpath = split /::/, $self->{ID};
4912 push @packpath, $packpath[-1];
4913 $packpath[-1] .= "." . $Config::Config{'dlext'};
4914 foreach $dir (@INC) {
4915 my $xsfile = MM->catfile($dir,'auto',@packpath);
4923 #-> sub CPAN::Module::inst_version ;
4926 my $parsefile = $self->inst_file or return;
4927 local($^W) = 0 if $] < 5.00303 && $ExtUtils::MakeMaker::VERSION < 5.38;
4930 # there was a bug in 5.6.0 that let lots of unini warnings out of
4931 # parse_version. Fixed shortly after 5.6.0 by PMQS. We can remove
4932 # the following workaround after 5.6.1 is out.
4933 local($SIG{__WARN__}) = sub { my $w = shift;
4934 return if $w =~ /uninitialized/i;
4938 $have = MM->parse_version($parsefile) || "undef";
4939 $have =~ s/^ //; # since the %vd hack these two lines here are needed
4940 $have =~ s/ $//; # trailing whitespace happens all the time
4942 # My thoughts about why %vd processing should happen here
4944 # Alt1 maintain it as string with leading v:
4945 # read index files do nothing
4946 # compare it use utility for compare
4947 # print it do nothing
4949 # Alt2 maintain it as what is is
4950 # read index files convert
4951 # compare it use utility because there's still a ">" vs "gt" issue
4952 # print it use CPAN::Version for print
4954 # Seems cleaner to hold it in memory as a string starting with a "v"
4956 # If the author of this module made a mistake and wrote a quoted
4957 # "v1.13" instead of v1.13, we simply leave it at that with the
4958 # effect that *we* will treat it like a v-tring while the rest of
4959 # perl won't. Seems sensible when we consider that any action we
4960 # could take now would just add complexity.
4962 $have = CPAN::Version->readable($have);
4964 $have =~ s/\s*//g; # stringify to float around floating point issues
4965 $have; # no stringify needed, \s* above matches always
4968 package CPAN::Tarzip;
4970 # CPAN::Tarzip::gzip
4972 my($class,$read,$write) = @_;
4973 if ($CPAN::META->has_inst("Compress::Zlib")) {
4975 $fhw = FileHandle->new($read)
4976 or $CPAN::Frontend->mydie("Could not open $read: $!");
4977 my $gz = Compress::Zlib::gzopen($write, "wb")
4978 or $CPAN::Frontend->mydie("Cannot gzopen $write: $!\n");
4979 $gz->gzwrite($buffer)
4980 while read($fhw,$buffer,4096) > 0 ;
4985 system("$CPAN::Config->{'gzip'} -c $read > $write")==0;
4990 # CPAN::Tarzip::gunzip
4992 my($class,$read,$write) = @_;
4993 if ($CPAN::META->has_inst("Compress::Zlib")) {
4995 $fhw = FileHandle->new(">$write")
4996 or $CPAN::Frontend->mydie("Could not open >$write: $!");
4997 my $gz = Compress::Zlib::gzopen($read, "rb")
4998 or $CPAN::Frontend->mydie("Cannot gzopen $read: $!\n");
4999 $fhw->print($buffer)
5000 while $gz->gzread($buffer) > 0 ;
5001 $CPAN::Frontend->mydie("Error reading from $read: $!\n")
5002 if $gz->gzerror != Compress::Zlib::Z_STREAM_END();
5007 system("$CPAN::Config->{'gzip'} -dc $read > $write")==0;
5012 # CPAN::Tarzip::gtest
5014 my($class,$read) = @_;
5015 if ($CPAN::META->has_inst("Compress::Zlib")) {
5017 my $gz = Compress::Zlib::gzopen($read, "rb")
5018 or $CPAN::Frontend->mydie("Cannot open $read: $!\n");
5019 1 while $gz->gzread($buffer) > 0 ;
5020 my $err = $gz->gzerror;
5021 my $success = ! $err || $err == Compress::Zlib::Z_STREAM_END();
5023 $class->debug("err[$err]success[$success]") if $CPAN::DEBUG;
5026 return system("$CPAN::Config->{'gzip'} -dt $read")==0;
5031 # CPAN::Tarzip::TIEHANDLE
5033 my($class,$file) = @_;
5035 $class->debug("file[$file]");
5036 if ($CPAN::META->has_inst("Compress::Zlib")) {
5037 my $gz = Compress::Zlib::gzopen($file,"rb") or
5038 die "Could not gzopen $file";
5039 $ret = bless {GZ => $gz}, $class;
5041 my $pipe = "$CPAN::Config->{'gzip'} --decompress --stdout $file |";
5042 my $fh = FileHandle->new($pipe) or die "Could pipe[$pipe]: $!";
5044 $ret = bless {FH => $fh}, $class;
5050 # CPAN::Tarzip::READLINE
5053 if (exists $self->{GZ}) {
5054 my $gz = $self->{GZ};
5055 my($line,$bytesread);
5056 $bytesread = $gz->gzreadline($line);
5057 return undef if $bytesread <= 0;
5060 my $fh = $self->{FH};
5061 return scalar <$fh>;
5066 # CPAN::Tarzip::READ
5068 my($self,$ref,$length,$offset) = @_;
5069 die "read with offset not implemented" if defined $offset;
5070 if (exists $self->{GZ}) {
5071 my $gz = $self->{GZ};
5072 my $byteread = $gz->gzread($$ref,$length);# 30eaf79e8b446ef52464b5422da328a8
5075 my $fh = $self->{FH};
5076 return read($fh,$$ref,$length);
5081 # CPAN::Tarzip::DESTROY
5084 if (exists $self->{GZ}) {
5085 my $gz = $self->{GZ};
5088 my $fh = $self->{FH};
5089 $fh->close if defined $fh;
5095 # CPAN::Tarzip::untar
5097 my($class,$file) = @_;
5098 if (0) { # makes changing order easier
5099 } elsif (MM->maybe_command($CPAN::Config->{'gzip'})
5101 MM->maybe_command($CPAN::Config->{'tar'})) {
5102 my $system = "$CPAN::Config->{'gzip'} --decompress --stdout " .
5103 "< $file | $CPAN::Config->{tar} xvf -";
5104 if (system($system) != 0) {
5105 # people find the most curious tar binaries that cannot handle
5107 my $system = "$CPAN::Config->{'gzip'} --decompress $file";
5108 if (system($system)==0) {
5109 $CPAN::Frontend->myprint(qq{Uncompressed $file successfully\n});
5111 $CPAN::Frontend->mydie(
5112 qq{Couldn\'t uncompress $file\n}
5115 $file =~ s/\.gz(?!\n)\Z//;
5116 $system = "$CPAN::Config->{tar} xvf $file";
5117 $CPAN::Frontend->myprint(qq{Using Tar:$system:\n});
5118 if (system($system)==0) {
5119 $CPAN::Frontend->myprint(qq{Untarred $file successfully\n});
5121 $CPAN::Frontend->mydie(qq{Couldn\'t untar $file\n});
5127 } elsif ($CPAN::META->has_inst("Archive::Tar")
5129 $CPAN::META->has_inst("Compress::Zlib") ) {
5130 my $tar = Archive::Tar->new($file,1);
5131 my $af; # archive file
5132 for $af ($tar->list_files) {
5133 if ($af =~ m!^(/|\.\./)!) {
5134 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5135 "illegal member [$af]");
5137 $CPAN::Frontend->myprint("$af\n");
5139 return if $CPAN::Signal;
5142 ExtUtils::MM_MacOS::convert_files([$tar->list_files], 1)
5143 if ($^O eq 'MacOS');
5147 $CPAN::Frontend->mydie(qq{
5148 CPAN.pm needs either both external programs tar and gzip installed or
5149 both the modules Archive::Tar and Compress::Zlib. Neither prerequisite
5150 is available. Can\'t continue.
5156 my($class,$file) = @_;
5157 if ($CPAN::META->has_inst("Archive::Zip")) {
5158 # blueprint of the code from Archive::Zip::Tree::extractTree();
5159 my $zip = Archive::Zip->new();
5161 $status = $zip->read($file);
5162 die "Read of file[$file] failed\n" if $status != Archive::Zip::AZ_OK();
5163 $CPAN::META->debug("Successfully read file[$file]") if $CPAN::DEBUG;
5164 my @members = $zip->members();
5165 for my $member ( @members ) {
5166 my $af = $member->fileName();
5167 if ($af =~ m!^(/|\.\./)!) {
5168 $CPAN::Frontend->mydie("ALERT: Archive contains ".
5169 "illegal member [$af]");
5171 my $status = $member->extractToFileNamed( $af );
5172 $CPAN::META->debug("af[$af]status[$status]") if $CPAN::DEBUG;
5173 die "Extracting of file[$af] from zipfile[$file] failed\n" if
5174 $status != Archive::Zip::AZ_OK();
5175 return if $CPAN::Signal;
5179 my $unzip = $CPAN::Config->{unzip} or
5180 $CPAN::Frontend->mydie("Cannot unzip, no unzip program available");
5181 my @system = ($unzip, $file);
5182 return system(@system) == 0;
5187 package CPAN::Version;
5188 # CPAN::Version::vcmp courtesy Jost Krieger
5190 my($self,$l,$r) = @_;
5192 CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG;
5194 return 0 if $l eq $r; # short circuit for quicker success
5196 if ($l=~/^v/ <=> $r=~/^v/) {
5199 $_ = $self->float2vv($_);
5204 ($l ne "undef") <=> ($r ne "undef") ||
5208 $self->vstring($l) cmp $self->vstring($r)) ||
5214 my($self,$l,$r) = @_;
5215 $self->vcmp($l,$r) > 0;
5220 $n =~ s/^v// or die "CPAN::Version::vstring() called with invalid arg [$n]";
5221 pack "U*", split /\./, $n;
5224 # vv => visible vstring
5229 my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits so that
5230 # architecture cannot
5233 $mantissa .= "0" while length($mantissa)%3;
5234 my $ret = "v" . $rev;
5236 $mantissa =~ s/(\d{1,3})// or
5237 die "Panic: length>0 but not a digit? mantissa[$mantissa]";
5238 $ret .= ".".int($1);
5240 # warn "n[$n]ret[$ret]";
5246 $n =~ /^([\w\-\+\.]+)/;
5248 return $1 if defined $1 && length($1)>0;
5249 # if the first user reaches version v43, he will be treated as "+".
5250 # We'll have to decide about a new rule here then, depending on what
5251 # will be the prevailing versioning behavior then.
5253 if ($] < 5.006) { # or whenever v-strings were introduced
5254 # we get them wrong anyway, whatever we do, because 5.005 will
5255 # have already interpreted 0.2.4 to be "0.24". So even if he
5256 # indexer sends us something like "v0.2.4" we compare wrongly.
5258 # And if they say v1.2, then the old perl takes it as "v12"
5260 $CPAN::Frontend->mywarn("Suspicious version string seen [$n]");
5263 my $better = sprintf "v%vd", $n;
5264 CPAN->debug("n[$n] better[$better]") if $CPAN::DEBUG;
5276 CPAN - query, download and build perl modules from CPAN sites
5282 perl -MCPAN -e shell;
5288 autobundle, clean, install, make, recompile, test
5292 The CPAN module is designed to automate the make and install of perl
5293 modules and extensions. It includes some searching capabilities and
5294 knows how to use Net::FTP or LWP (or lynx or an external ftp client)
5295 to fetch the raw data from the net.
5297 Modules are fetched from one or more of the mirrored CPAN
5298 (Comprehensive Perl Archive Network) sites and unpacked in a dedicated
5301 The CPAN module also supports the concept of named and versioned
5302 I<bundles> of modules. Bundles simplify the handling of sets of
5303 related modules. See Bundles below.
5305 The package contains a session manager and a cache manager. There is
5306 no status retained between sessions. The session manager keeps track
5307 of what has been fetched, built and installed in the current
5308 session. The cache manager keeps track of the disk space occupied by
5309 the make processes and deletes excess space according to a simple FIFO
5312 For extended searching capabilities there's a plugin for CPAN available,
5313 L<CPAN::WAIT>. C<CPAN::WAIT> is a full-text search engine that indexes
5314 all documents available in CPAN authors directories. If C<CPAN::WAIT>
5315 is installed on your system, the interactive shell of <CPAN.pm> will
5316 enable the C<wq>, C<wr>, C<wd>, C<wl>, and C<wh> commands which send
5317 queries to the WAIT server that has been configured for your
5320 All other methods provided are accessible in a programmer style and in an
5321 interactive shell style.
5323 =head2 Interactive Mode
5325 The interactive mode is entered by running
5327 perl -MCPAN -e shell
5329 which puts you into a readline interface. You will have the most fun if
5330 you install Term::ReadKey and Term::ReadLine to enjoy both history and
5333 Once you are on the command line, type 'h' and the rest should be
5336 The most common uses of the interactive modes are
5340 =item Searching for authors, bundles, distribution files and modules
5342 There are corresponding one-letter commands C<a>, C<b>, C<d>, and C<m>
5343 for each of the four categories and another, C<i> for any of the
5344 mentioned four. Each of the four entities is implemented as a class
5345 with slightly differing methods for displaying an object.
5347 Arguments you pass to these commands are either strings exactly matching
5348 the identification string of an object or regular expressions that are
5349 then matched case-insensitively against various attributes of the
5350 objects. The parser recognizes a regular expression only if you
5351 enclose it between two slashes.
5353 The principle is that the number of found objects influences how an
5354 item is displayed. If the search finds one item, the result is
5355 displayed with the rather verbose method C<as_string>, but if we find
5356 more than one, we display each object with the terse method
5359 =item make, test, install, clean modules or distributions
5361 These commands take any number of arguments and investigate what is
5362 necessary to perform the action. If the argument is a distribution
5363 file name (recognized by embedded slashes), it is processed. If it is
5364 a module, CPAN determines the distribution file in which this module
5365 is included and processes that, following any dependencies named in
5366 the module's Makefile.PL (this behavior is controlled by
5367 I<prerequisites_policy>.)
5369 Any C<make> or C<test> are run unconditionally. An
5371 install <distribution_file>
5373 also is run unconditionally. But for
5377 CPAN checks if an install is actually needed for it and prints
5378 I<module up to date> in the case that the distribution file containing
5379 the module doesn't need to be updated.
5381 CPAN also keeps track of what it has done within the current session
5382 and doesn't try to build a package a second time regardless if it
5383 succeeded or not. The C<force> command takes as a first argument the
5384 method to invoke (currently: C<make>, C<test>, or C<install>) and executes the
5385 command from scratch.
5389 cpan> install OpenGL
5390 OpenGL is up to date.
5391 cpan> force install OpenGL
5394 OpenGL-0.4/COPYRIGHT
5397 A C<clean> command results in a
5401 being executed within the distribution file's working directory.
5403 =item get, readme, look module or distribution
5405 C<get> downloads a distribution file without further action. C<readme>
5406 displays the README file of the associated distribution. C<Look> gets
5407 and untars (if not yet done) the distribution file, changes to the
5408 appropriate directory and opens a subshell process in that directory.
5412 CPAN.pm installs signal handlers for SIGINT and SIGTERM. While you are
5413 in the cpan-shell it is intended that you can press C<^C> anytime and
5414 return to the cpan-shell prompt. A SIGTERM will cause the cpan-shell
5415 to clean up and leave the shell loop. You can emulate the effect of a
5416 SIGTERM by sending two consecutive SIGINTs, which usually means by
5417 pressing C<^C> twice.
5419 CPAN.pm ignores a SIGPIPE. If the user sets inactivity_timeout, a
5420 SIGALRM is used during the run of the C<perl Makefile.PL> subprocess.
5426 The commands that are available in the shell interface are methods in
5427 the package CPAN::Shell. If you enter the shell command, all your
5428 input is split by the Text::ParseWords::shellwords() routine which
5429 acts like most shells do. The first word is being interpreted as the
5430 method to be called and the rest of the words are treated as arguments
5431 to this method. Continuation lines are supported if a line ends with a
5436 C<autobundle> writes a bundle file into the
5437 C<$CPAN::Config-E<gt>{cpan_home}/Bundle> directory. The file contains
5438 a list of all modules that are both available from CPAN and currently
5439 installed within @INC. The name of the bundle file is based on the
5440 current date and a counter.
5444 recompile() is a very special command in that it takes no argument and
5445 runs the make/test/install cycle with brute force over all installed
5446 dynamically loadable extensions (aka XS modules) with 'force' in
5447 effect. The primary purpose of this command is to finish a network
5448 installation. Imagine, you have a common source tree for two different
5449 architectures. You decide to do a completely independent fresh
5450 installation. You start on one architecture with the help of a Bundle
5451 file produced earlier. CPAN installs the whole Bundle for you, but
5452 when you try to repeat the job on the second architecture, CPAN
5453 responds with a C<"Foo up to date"> message for all modules. So you
5454 invoke CPAN's recompile on the second architecture and you're done.
5456 Another popular use for C<recompile> is to act as a rescue in case your
5457 perl breaks binary compatibility. If one of the modules that CPAN uses
5458 is in turn depending on binary compatibility (so you cannot run CPAN
5459 commands), then you should try the CPAN::Nox module for recovery.
5461 =head2 The four C<CPAN::*> Classes: Author, Bundle, Module, Distribution
5463 Although it may be considered internal, the class hierarchy does matter
5464 for both users and programmer. CPAN.pm deals with above mentioned four
5465 classes, and all those classes share a set of methods. A classical
5466 single polymorphism is in effect. A metaclass object registers all
5467 objects of all kinds and indexes them with a string. The strings
5468 referencing objects have a separated namespace (well, not completely
5473 words containing a "/" (slash) Distribution
5474 words starting with Bundle:: Bundle
5475 everything else Module or Author
5477 Modules know their associated Distribution objects. They always refer
5478 to the most recent official release. Developers may mark their releases
5479 as unstable development versions (by inserting an underbar into the
5480 visible version number), so the really hottest and newest distribution
5481 file is not always the default. If a module Foo circulates on CPAN in
5482 both version 1.23 and 1.23_90, CPAN.pm offers a convenient way to
5483 install version 1.23 by saying
5487 This would install the complete distribution file (say
5488 BAR/Foo-1.23.tar.gz) with all accompanying material. But if you would
5489 like to install version 1.23_90, you need to know where the
5490 distribution file resides on CPAN relative to the authors/id/
5491 directory. If the author is BAR, this might be BAR/Foo-1.23_90.tar.gz;
5492 so you would have to say
5494 install BAR/Foo-1.23_90.tar.gz
5496 The first example will be driven by an object of the class
5497 CPAN::Module, the second by an object of class CPAN::Distribution.
5499 =head2 Programmer's interface
5501 If you do not enter the shell, the available shell commands are both
5502 available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
5503 functions in the calling package (C<install(...)>).
5505 There's currently only one class that has a stable interface -
5506 CPAN::Shell. All commands that are available in the CPAN shell are
5507 methods of the class CPAN::Shell. Each of the commands that produce
5508 listings of modules (C<r>, C<autobundle>, C<u>) also return a list of
5509 the IDs of all modules within the list.
5513 =item expand($type,@things)
5515 The IDs of all objects available within a program are strings that can
5516 be expanded to the corresponding real objects with the
5517 C<CPAN::Shell-E<gt>expand("Module",@things)> method. Expand returns a
5518 list of CPAN::Module objects according to the C<@things> arguments
5519 given. In scalar context it only returns the first element of the
5522 =item Programming Examples
5524 This enables the programmer to do operations that combine
5525 functionalities that are available in the shell.
5527 # install everything that is outdated on my disk:
5528 perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'
5530 # install my favorite programs if necessary:
5531 for $mod (qw(Net::FTP MD5 Data::Dumper)){
5532 my $obj = CPAN::Shell->expand('Module',$mod);
5536 # list all modules on my disk that have no VERSION number
5537 for $mod (CPAN::Shell->expand("Module","/./")){
5538 next unless $mod->inst_file;
5539 # MakeMaker convention for undefined $VERSION:
5540 next unless $mod->inst_version eq "undef";
5541 print "No VERSION in ", $mod->id, "\n";
5544 # find out which distribution on CPAN contains a module:
5545 print CPAN::Shell->expand("Module","Apache::Constants")->cpan_file
5547 Or if you want to write a cronjob to watch The CPAN, you could list
5548 all modules that need updating. First a quick and dirty way:
5550 perl -e 'use CPAN; CPAN::Shell->r;'
5552 If you don't want to get any output if all modules are up to date, you
5553 can parse the output of above command for the regular expression
5554 //modules are up to date// and decide to mail the output only if it
5557 If you prefer to do it more in a programmer style in one single
5558 process, maybe something like this suites you better:
5560 # list all modules on my disk that have newer versions on CPAN
5561 for $mod (CPAN::Shell->expand("Module","/./")){
5562 next unless $mod->inst_file;
5563 next if $mod->uptodate;
5564 printf "Module %s is installed as %s, could be updated to %s from CPAN\n",
5565 $mod->id, $mod->inst_version, $mod->cpan_version;
5568 If that gives you too much output every day, you maybe only want to
5569 watch for three modules. You can write
5571 for $mod (CPAN::Shell->expand("Module","/Apache|LWP|CGI/")){
5573 as the first line instead. Or you can combine some of the above
5576 # watch only for a new mod_perl module
5577 $mod = CPAN::Shell->expand("Module","mod_perl");
5578 exit if $mod->uptodate;
5579 # new mod_perl arrived, let me know all update recommendations
5584 =head2 Methods in the four Classes
5586 =head2 Cache Manager
5588 Currently the cache manager only keeps track of the build directory
5589 ($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
5590 deletes complete directories below C<build_dir> as soon as the size of
5591 all directories there gets bigger than $CPAN::Config->{build_cache}
5592 (in MB). The contents of this cache may be used for later
5593 re-installations that you intend to do manually, but will never be
5594 trusted by CPAN itself. This is due to the fact that the user might
5595 use these directories for building modules on different architectures.
5597 There is another directory ($CPAN::Config->{keep_source_where}) where
5598 the original distribution files are kept. This directory is not
5599 covered by the cache manager and must be controlled by the user. If
5600 you choose to have the same directory as build_dir and as
5601 keep_source_where directory, then your sources will be deleted with
5602 the same fifo mechanism.
5606 A bundle is just a perl module in the namespace Bundle:: that does not
5607 define any functions or methods. It usually only contains documentation.
5609 It starts like a perl module with a package declaration and a $VERSION
5610 variable. After that the pod section looks like any other pod with the
5611 only difference being that I<one special pod section> exists starting with
5616 In this pod section each line obeys the format
5618 Module_Name [Version_String] [- optional text]
5620 The only required part is the first field, the name of a module
5621 (e.g. Foo::Bar, ie. I<not> the name of the distribution file). The rest
5622 of the line is optional. The comment part is delimited by a dash just
5623 as in the man page header.
5625 The distribution of a bundle should follow the same convention as
5626 other distributions.
5628 Bundles are treated specially in the CPAN package. If you say 'install
5629 Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
5630 the modules in the CONTENTS section of the pod. You can install your
5631 own Bundles locally by placing a conformant Bundle file somewhere into
5632 your @INC path. The autobundle() command which is available in the
5633 shell interface does that for you by including all currently installed
5634 modules in a snapshot bundle file.
5636 =head2 Prerequisites
5638 If you have a local mirror of CPAN and can access all files with
5639 "file:" URLs, then you only need a perl better than perl5.003 to run
5640 this module. Otherwise Net::FTP is strongly recommended. LWP may be
5641 required for non-UNIX systems or if your nearest CPAN site is
5642 associated with an URL that is not C<ftp:>.
5644 If you have neither Net::FTP nor LWP, there is a fallback mechanism
5645 implemented for an external ftp command or for an external lynx
5648 =head2 Finding packages and VERSION
5650 This module presumes that all packages on CPAN
5656 declare their $VERSION variable in an easy to parse manner. This
5657 prerequisite can hardly be relaxed because it consumes far too much
5658 memory to load all packages into the running program just to determine
5659 the $VERSION variable. Currently all programs that are dealing with
5660 version use something like this
5662 perl -MExtUtils::MakeMaker -le \
5663 'print MM->parse_version(shift)' filename
5665 If you are author of a package and wonder if your $VERSION can be
5666 parsed, please try the above method.
5670 come as compressed or gzipped tarfiles or as zip files and contain a
5671 Makefile.PL (well, we try to handle a bit more, but without much
5678 The debugging of this module is a bit complex, because we have
5679 interferences of the software producing the indices on CPAN, of the
5680 mirroring process on CPAN, of packaging, of configuration, of
5681 synchronicity, and of bugs within CPAN.pm.
5683 For code debugging in interactive mode you can try "o debug" which
5684 will list options for debugging the various parts of the code. You
5685 should know that "o debug" has built-in completion support.
5687 For data debugging there is the C<dump> command which takes the same
5688 arguments as make/test/install and outputs the object's Data::Dumper
5691 =head2 Floppy, Zip, Offline Mode
5693 CPAN.pm works nicely without network too. If you maintain machines
5694 that are not networked at all, you should consider working with file:
5695 URLs. Of course, you have to collect your modules somewhere first. So
5696 you might use CPAN.pm to put together all you need on a networked
5697 machine. Then copy the $CPAN::Config->{keep_source_where} (but not
5698 $CPAN::Config->{build_dir}) directory on a floppy. This floppy is kind
5699 of a personal CPAN. CPAN.pm on the non-networked machines works nicely
5700 with this floppy. See also below the paragraph about CD-ROM support.
5702 =head1 CONFIGURATION
5704 When the CPAN module is installed, a site wide configuration file is
5705 created as CPAN/Config.pm. The default values defined there can be
5706 overridden in another configuration file: CPAN/MyConfig.pm. You can
5707 store this file in $HOME/.cpan/CPAN/MyConfig.pm if you want, because
5708 $HOME/.cpan is added to the search path of the CPAN module before the
5709 use() or require() statements.
5711 Currently the following keys in the hash reference $CPAN::Config are
5714 build_cache size of cache for directories to build modules
5715 build_dir locally accessible directory to build modules
5716 index_expire after this many days refetch index files
5717 cache_metadata use serializer to cache metadata
5718 cpan_home local directory reserved for this package
5719 dontload_hash anonymous hash: modules in the keys will not be
5720 loaded by the CPAN::has_inst() routine
5721 gzip location of external program gzip
5722 inactivity_timeout breaks interactive Makefile.PLs after this
5723 many seconds inactivity. Set to 0 to never break.
5724 inhibit_startup_message
5725 if true, does not print the startup message
5726 keep_source_where directory in which to keep the source (if we do)
5727 make location of external make program
5728 make_arg arguments that should always be passed to 'make'
5729 make_install_arg same as make_arg for 'make install'
5730 makepl_arg arguments passed to 'perl Makefile.PL'
5731 pager location of external program more (or any pager)
5732 prerequisites_policy
5733 what to do if you are missing module prerequisites
5734 ('follow' automatically, 'ask' me, or 'ignore')
5735 scan_cache controls scanning of cache ('atstart' or 'never')
5736 tar location of external program tar
5737 unzip location of external program unzip
5738 urllist arrayref to nearby CPAN sites (or equivalent locations)
5739 wait_list arrayref to a wait server to try (See CPAN::WAIT)
5740 ftp_proxy, } the three usual variables for configuring
5741 http_proxy, } proxy requests. Both as CPAN::Config variables
5742 no_proxy } and as environment variables configurable.
5744 You can set and query each of these options interactively in the cpan
5745 shell with the command set defined within the C<o conf> command:
5749 =item C<o conf E<lt>scalar optionE<gt>>
5751 prints the current value of the I<scalar option>
5753 =item C<o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>>
5755 Sets the value of the I<scalar option> to I<value>
5757 =item C<o conf E<lt>list optionE<gt>>
5759 prints the current value of the I<list option> in MakeMaker's
5762 =item C<o conf E<lt>list optionE<gt> [shift|pop]>
5764 shifts or pops the array in the I<list option> variable
5766 =item C<o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>>
5768 works like the corresponding perl commands.
5772 =head2 Note on urllist parameter's format
5774 urllist parameters are URLs according to RFC 1738. We do a little
5775 guessing if your URL is not compliant, but if you have problems with
5776 file URLs, please try the correct format. Either:
5778 file://localhost/whatever/ftp/pub/CPAN/
5782 file:///home/ftp/pub/CPAN/
5784 =head2 urllist parameter has CD-ROM support
5786 The C<urllist> parameter of the configuration table contains a list of
5787 URLs that are to be used for downloading. If the list contains any
5788 C<file> URLs, CPAN always tries to get files from there first. This
5789 feature is disabled for index files. So the recommendation for the
5790 owner of a CD-ROM with CPAN contents is: include your local, possibly
5791 outdated CD-ROM as a C<file> URL at the end of urllist, e.g.
5793 o conf urllist push file://localhost/CDROM/CPAN
5795 CPAN.pm will then fetch the index files from one of the CPAN sites
5796 that come at the beginning of urllist. It will later check for each
5797 module if there is a local copy of the most recent version.
5799 Another peculiarity of urllist is that the site that we could
5800 successfully fetch the last file from automatically gets a preference
5801 token and is tried as the first site for the next request. So if you
5802 add a new site at runtime it may happen that the previously preferred
5803 site will be tried another time. This means that if you want to disallow
5804 a site for the next transfer, it must be explicitly removed from
5809 There's no strong security layer in CPAN.pm. CPAN.pm helps you to
5810 install foreign, unmasked, unsigned code on your machine. We compare
5811 to a checksum that comes from the net just as the distribution file
5812 itself. If somebody has managed to tamper with the distribution file,
5813 they may have as well tampered with the CHECKSUMS file. Future
5814 development will go towards strong authentication.
5818 Most functions in package CPAN are exported per default. The reason
5819 for this is that the primary use is intended for the cpan shell or for
5822 =head1 POPULATE AN INSTALLATION WITH LOTS OF MODULES
5824 To populate a freshly installed perl with my favorite modules is pretty
5825 easiest by maintaining a private bundle definition file. To get a useful
5826 blueprint of a bundle definition file, the command autobundle can be used
5827 on the CPAN shell command line. This command writes a bundle definition
5828 file for all modules that are installed for the currently running perl
5829 interpreter. It's recommended to run this command only once and from then
5830 on maintain the file manually under a private name, say
5831 Bundle/my_bundle.pm. With a clever bundle file you can then simply say
5833 cpan> install Bundle::my_bundle
5835 then answer a few questions and then go out for a coffee.
5837 Maintaining a bundle definition file means to keep track of two
5838 things: dependencies and interactivity. CPAN.pm sometimes fails on
5839 calculating dependencies because not all modules define all MakeMaker
5840 attributes correctly, so a bundle definition file should specify
5841 prerequisites as early as possible. On the other hand, it's a bit
5842 annoying that many distributions need some interactive configuring. So
5843 what I try to accomplish in my private bundle file is to have the
5844 packages that need to be configured early in the file and the gentle
5845 ones later, so I can go out after a few minutes and leave CPAN.pm
5848 =head1 WORKING WITH CPAN.pm BEHIND FIREWALLS
5850 Thanks to Graham Barr for contributing the following paragraphs about
5851 the interaction between perl, and various firewall configurations. For
5852 further informations on firewalls, it is recommended to consult the
5853 documentation that comes with the ncftp program. If you are unable to
5854 go through the firewall with a simple Perl setup, it is very likely
5855 that you can configure ncftp so that it works for your firewall.
5857 =head2 Three basic types of firewalls
5859 Firewalls can be categorized into three basic types.
5865 This is where the firewall machine runs a web server and to access the
5866 outside world you must do it via the web server. If you set environment
5867 variables like http_proxy or ftp_proxy to a values beginning with http://
5868 or in your web browser you have to set proxy information then you know
5869 you are running a http firewall.
5871 To access servers outside these types of firewalls with perl (even for
5872 ftp) you will need to use LWP.
5876 This where the firewall machine runs a ftp server. This kind of
5877 firewall will only let you access ftp servers outside the firewall.
5878 This is usually done by connecting to the firewall with ftp, then
5879 entering a username like "user@outside.host.com"
5881 To access servers outside these type of firewalls with perl you
5882 will need to use Net::FTP.
5884 =item One way visibility
5886 I say one way visibility as these firewalls try to make themselve look
5887 invisible to the users inside the firewall. An FTP data connection is
5888 normally created by sending the remote server your IP address and then
5889 listening for the connection. But the remote server will not be able to
5890 connect to you because of the firewall. So for these types of firewall
5891 FTP connections need to be done in a passive mode.
5893 There are two that I can think off.
5899 If you are using a SOCKS firewall you will need to compile perl and link
5900 it with the SOCKS library, this is what is normally called a 'socksified'
5901 perl. With this executable you will be able to connect to servers outside
5902 the firewall as if it is not there.
5906 This is the firewall implemented in the Linux kernel, it allows you to
5907 hide a complete network behind one IP address. With this firewall no
5908 special compiling is need as you can access hosts directly.
5914 =head2 Configuring lynx or ncftp for going through a firewall
5916 If you can go through your firewall with e.g. lynx, presumably with a
5919 /usr/local/bin/lynx -pscott:tiger
5921 then you would configure CPAN.pm with the command
5923 o conf lynx "/usr/local/bin/lynx -pscott:tiger"
5925 That's all. Similarly for ncftp or ftp, you would configure something
5928 o conf ncftp "/usr/bin/ncftp -f /home/scott/ncftplogin.cfg"
5930 Your milage may vary...
5936 =item I installed a new version of module X but CPAN keeps saying, I
5937 have the old version installed
5939 Most probably you B<do> have the old version installed. This can
5940 happen if a module installs itself into a different directory in the
5941 @INC path than it was previously installed. This is not really a
5942 CPAN.pm problem, you would have the same problem when installing the
5943 module manually. The easiest way to prevent this behaviour is to add
5944 the argument C<UNINST=1> to the C<make install> call, and that is why
5945 many people add this argument permanently by configuring
5947 o conf make_install_arg UNINST=1
5949 =item So why is UNINST=1 not the default?
5951 Because there are people who have their precise expectations about who
5952 may install where in the @INC path and who uses which @INC array. In
5953 fine tuned environments C<UNINST=1> can cause damage.
5955 =item When I install bundles or multiple modules with one command
5956 there is too much output to keep track of
5958 You may want to configure something like
5960 o conf make_arg "| tee -ai /root/.cpan/logs/make.out"
5961 o conf make_install_arg "| tee -ai /root/.cpan/logs/make_install.out"
5963 so that STDOUT is captured in a file for later inspection.
5966 =item I am not root, how can I install a module in a personal directory?
5968 You will most probably like something like this:
5970 o conf makepl_arg "LIB=~/myperl/lib \
5971 INSTALLMAN1DIR=~/myperl/man/man1 \
5972 INSTALLMAN3DIR=~/myperl/man/man3"
5973 install Sybase::Sybperl
5975 You can make this setting permanent like all C<o conf> settings with
5978 You will have to add ~/myperl/man to the MANPATH environment variable
5979 and also tell your perl programs to look into ~/myperl/lib, e.g. by
5982 use lib "$ENV{HOME}/myperl/lib";
5984 or setting the PERL5LIB environment variable.
5986 Another thing you should bear in mind is that the UNINST parameter
5987 should never be set if you are not root.
5989 =item How to get a package, unwrap it, and make a change before building it?
5991 look Sybase::Sybperl
5993 =item I installed a Bundle and had a couple of fails. When I retried,
5994 everything resolved nicely. Can this be fixed to work on first
5997 The reason for this is that CPAN does not know the dependencies of all
5998 modules when it starts out. To decide about the additional items to
5999 install, it just uses data found in the generated Makefile. An
6000 undetected missing piece breaks the process. But it may well be that
6001 your Bundle installs some prerequisite later than some depending item
6002 and thus your second try is able to resolve everything. Please note,
6003 CPAN.pm does not know the dependency tree in advance and cannot sort
6004 the queue of things to install in a topologically correct order.
6005 For bundles which you need to install often, it is recommended to do
6006 the sorting manually. It is planned to improve the metadata situation
6007 for dependencies on CPAN in general, but this will still take some
6014 We should give coverage for B<all> of the CPAN and not just the PAUSE
6015 part, right? In this discussion CPAN and PAUSE have become equal --
6016 but they are not. PAUSE is authors/, modules/ and scripts/. CPAN is
6017 PAUSE plus the clpa/, doc/, misc/, ports/, and src/.
6019 Future development should be directed towards a better integration of
6022 If a Makefile.PL requires special customization of libraries, prompts
6023 the user for special input, etc. then you may find CPAN is not able to
6024 build the distribution. In that case, you should attempt the
6025 traditional method of building a Perl module package from a shell.
6029 Andreas Koenig E<lt>andreas.koenig@anima.deE<gt>
6033 perl(1), CPAN::Nox(3)