File Coverage

blib/lib/CPAN.pm
Criterion Covered Total %
statement 289 830 34.8
branch 67 400 16.7
condition 29 170 17.0
subroutine 71 109 65.1
pod 13 27 48.1
total 469 1536 30.5


line stmt bran cond sub pod time code
1             # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
2             # vim: ts=4 sts=4 sw=4:
3 22     22   1325264 use strict;
  22         51  
  22         2105  
4             package CPAN;
5             $CPAN::VERSION = '2.39';
6             $CPAN::VERSION =~ s/_//;
7              
8             # we need to run chdir all over and we would get at wrong libraries
9             # there
10 22     22   175 use File::Spec ();
  22         53  
  22         2272  
11             BEGIN {
12 22 50   22   491 if (File::Spec->can("rel2abs")) {
13 22         71 for my $inc (@INC) {
14 198 50       2059 $inc = File::Spec->rel2abs($inc) unless ref $inc;
15             }
16             }
17 22 50       1088 $SIG{WINCH} = 'IGNORE' if exists $SIG{WINCH};
18             }
19 22     22   10641 use CPAN::Author;
  22         64  
  22         837  
20 22     22   11541 use CPAN::HandleConfig;
  22         68  
  22         857  
21 22     22   9982 use CPAN::Version;
  22         63  
  22         775  
22 22     22   8689 use CPAN::Bundle;
  22         105  
  22         778  
23 22     22   10390 use CPAN::CacheMgr;
  22         55  
  22         758  
24 22     22   9293 use CPAN::Complete;
  22         76  
  22         774  
25 22     22   125 use CPAN::Debug;
  22         34  
  22         395  
26 22     22   20816 use CPAN::Distribution;
  22         102  
  22         1081  
27 22     22   11094 use CPAN::Distrostatus;
  22         64  
  22         634  
28 22     22   11944 use CPAN::FTP;
  22         160  
  22         1038  
29 22     22   11193 use CPAN::Index 1.93; # https://rt.cpan.org/Ticket/Display.html?id=43349
  22         524  
  22         895  
30 22     22   128 use CPAN::InfoObj;
  22         78  
  22         419  
31 22     22   81 use CPAN::Module;
  22         218  
  22         519  
32 22     22   9595 use CPAN::Prompt;
  22         49  
  22         743  
33 22     22   14451 use CPAN::URL;
  22         50  
  22         587  
34 22     22   8819 use CPAN::Queue;
  22         56  
  22         647  
35 22     22   10046 use CPAN::Tarzip;
  22         65  
  22         831  
36 22     22   8351 use CPAN::DeferredCode;
  22         52  
  22         617  
37 22     22   13720 use CPAN::Shell;
  22         99  
  22         958  
38 22     22   9145 use CPAN::LWP::UserAgent;
  22         60  
  22         705  
39 22     22   8685 use CPAN::Exception::RecursiveDependency;
  22         59  
  22         690  
40 22     22   8391 use CPAN::Exception::yaml_not_installed;
  22         53  
  22         682  
41 22     22   8488 use CPAN::Exception::yaml_process_error;
  22         55  
  22         615  
42              
43 22     22   119 use Carp ();
  22         32  
  22         315  
44 22     22   72 use Config ();
  22         31  
  22         411  
45 22     22   73 use Cwd qw(chdir);
  22         28  
  22         1342  
46 22     22   107 use DirHandle ();
  22         27  
  22         306  
47 22     22   68 use Exporter ();
  22         45  
  22         530  
48 22     22   17404 use ExtUtils::MakeMaker qw(prompt); # for some unknown reason,
  22         2287206  
  22         1577  
49             # 5.005_04 does not work without
50             # this
51 22     22   202 use File::Basename ();
  22         63  
  22         310  
52 22     22   8487 use File::Copy ();
  22         64813  
  22         568  
53 22     22   122 use File::Find;
  22         39  
  22         976  
54 22     22   84 use File::Path ();
  22         32  
  22         257  
55 22     22   8042 use FileHandle ();
  22         149146  
  22         950  
56 22     22   136 use Fcntl qw(:flock);
  22         36  
  22         3758  
57 22     22   11002 use Safe ();
  22         210576  
  22         740  
58 22     22   9293 use Sys::Hostname qw(hostname);
  22         22503  
  22         1388  
59 22     22   9989 use Text::ParseWords ();
  22         38398  
  22         605  
60 22     22   8776 use Text::Wrap ();
  22         58251  
  22         1149  
61              
62             # protect against "called too early"
63             sub find_perl ();
64             sub anycwd ();
65             sub _uniq;
66              
67 22     22   8694 no lib ".";
  22         12869  
  22         169  
68              
69             if ($ENV{PERL5_CPAN_IS_RUNNING} && $$ != $ENV{PERL5_CPAN_IS_RUNNING}) {
70             $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION} ||= $ENV{PERL5_CPAN_IS_RUNNING};
71             my @rec = _uniq split(/,/, $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION}), $$;
72             $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION} = join ",", @rec;
73             # warn "# Note: Recursive call of CPAN.pm detected\n";
74             my $w = sprintf "# Note: CPAN.pm is running in process %d now", pop @rec;
75             my %sleep = (
76             5 => 30,
77             6 => 60,
78             7 => 120,
79             );
80             my $sleep = @rec > 7 ? 300 : ($sleep{scalar @rec}||0);
81             my $verbose = @rec >= 4;
82             while (@rec) {
83             $w .= sprintf " which has been called by process %d", pop @rec;
84             }
85             if ($sleep) {
86             $w .= ".\n\n# Sleeping $sleep seconds to protect other processes\n";
87             }
88             if ($verbose) {
89             warn $w;
90             }
91             local $| = 1;
92             my $have_been_sleeping = 0;
93             while ($sleep > 0) {
94             printf "\r#%5d", --$sleep;
95             sleep 1;
96             ++$have_been_sleeping;
97             }
98             print "\n" if $have_been_sleeping;
99             }
100             $ENV{PERL5_CPAN_IS_RUNNING}=$$;
101             $ENV{PERL5_CPANPLUS_IS_RUNNING}=$$; # https://rt.cpan.org/Ticket/Display.html?id=23735
102              
103 22     22   69222446 END { $CPAN::End++; &cleanup; }
  22         344  
104              
105             $CPAN::Signal ||= 0;
106             $CPAN::Frontend ||= "CPAN::Shell";
107             unless (@CPAN::Defaultsites) {
108             @CPAN::Defaultsites = map {
109             CPAN::URL->new(TEXT => $_, FROM => "DEF")
110             }
111             "http://www.perl.org/CPAN/",
112             "ftp://ftp.perl.org/pub/CPAN/";
113             }
114             # $CPAN::iCwd (i for initial)
115             $CPAN::iCwd ||= CPAN::anycwd();
116             $CPAN::Perl ||= CPAN::find_perl();
117             $CPAN::Defaultdocs ||= "http://search.cpan.org/perldoc?";
118             $CPAN::Defaultrecent ||= "http://search.cpan.org/uploads.rdf";
119             $CPAN::Defaultrecent ||= "http://cpan.uwinnipeg.ca/htdocs/cpan.xml";
120              
121             # our globals are getting a mess
122 22         37192 use vars qw(
123             $AUTOLOAD
124             $Be_Silent
125             $CONFIG_DIRTY
126             $Defaultdocs
127             $Echo_readline
128             $Frontend
129             $GOTOSHELL
130             $HAS_USABLE
131             $Have_warned
132             $MAX_RECURSION
133             $META
134             $RUN_DEGRADED
135             $Signal
136             $SQLite
137             $Suppress_readline
138             $VERSION
139             $autoload_recursion
140             $term
141             @Defaultsites
142             @EXPORT
143 22     22   8947 );
  22         45  
144              
145             $MAX_RECURSION = 32;
146              
147             @CPAN::ISA = qw(CPAN::Debug Exporter);
148              
149             # note that these functions live in CPAN::Shell and get executed via
150             # AUTOLOAD when called directly
151             @EXPORT = qw(
152             autobundle
153             bundle
154             clean
155             cvs_import
156             expand
157             force
158             fforce
159             get
160             install
161             install_tested
162             is_tested
163             make
164             mkmyconfig
165             notest
166             perldoc
167             readme
168             recent
169             recompile
170             report
171             shell
172             smoke
173             test
174             upgrade
175             );
176              
177             sub soft_chdir_with_alternatives ($);
178              
179             {
180             $autoload_recursion ||= 0;
181              
182             #-> sub CPAN::AUTOLOAD ;
183             sub AUTOLOAD { ## no critic
184 1     1   12 $autoload_recursion++;
185 1         2 my($l) = $AUTOLOAD;
186 1         10 $l =~ s/.*:://;
187 1 50       5 if ($CPAN::Signal) {
188 0         0 warn "Refusing to autoload '$l' while signal pending";
189 0         0 $autoload_recursion--;
190 0         0 return;
191             }
192 1 50       3 if ($autoload_recursion > 1) {
193 0         0 my $fullcommand = join " ", map { "'$_'" } $l, @_;
  0         0  
194 0         0 warn "Refusing to autoload $fullcommand in recursion\n";
195 0         0 $autoload_recursion--;
196 0         0 return;
197             }
198 1         4 my(%export);
199 1         50 @export{@EXPORT} = '';
200 1 50       21 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
201 1 50       3 if (exists $export{$l}) {
202 0         0 CPAN::Shell->$l(@_);
203             } else {
204 1         12 die(qq{Unknown CPAN command "$AUTOLOAD". }.
205             qq{Type ? for help.\n});
206             }
207 0         0 $autoload_recursion--;
208             }
209             }
210              
211             {
212             my $x = *SAVEOUT; # avoid warning
213             open($x,">&STDOUT") or die "dup failed";
214             my $redir = 0;
215             sub _redirect(@) {
216             #die if $redir;
217 0     0   0 local $_;
218 0         0 push(@_,undef);
219 0         0 while(defined($_=shift)) {
220 0 0       0 if (s/^\s*>//){
    0          
221 0 0       0 my ($m) = s/^>// ? ">" : "";
222 0         0 s/\s+//;
223 0 0       0 $_=shift unless length;
224 0 0       0 die "no dest" unless defined;
225 0 0       0 open(STDOUT,">$m$_") or die "open:$_:$!\n";
226 0         0 $redir=1;
227             } elsif ( s/^\s*\|\s*// ) {
228 0         0 my $pipe="| $_";
229 0         0 while(defined($_[0])){
230 0         0 $pipe .= ' ' . shift;
231             }
232 0 0       0 open(STDOUT,$pipe) or die "open:$pipe:$!\n";
233 0         0 $redir=1;
234             } else {
235 0         0 push(@_,$_);
236             }
237             }
238 0         0 return @_;
239             }
240             sub _unredirect {
241 0 0   0   0 return unless $redir;
242 0         0 $redir = 0;
243             ## redirect: unredirect and propagate errors. explicit close to wait for pipe.
244 0         0 close(STDOUT);
245 0         0 open(STDOUT,">&SAVEOUT");
246 0 0       0 die "$@" if "$@";
247             ## redirect: done
248             }
249             }
250              
251             sub _uniq {
252 8     8   42 my(@list) = @_;
253 8         16 my %seen;
254 8         19 return grep { !$seen{$_}++ } @list;
  16         97  
255             }
256              
257             #-> sub CPAN::shell ;
258             sub shell {
259 0     0 1 0 my($self) = @_;
260 0 0       0 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
261 0 0       0 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
262              
263 0   0     0 my $oprompt = shift || CPAN::Prompt->new;
264 0         0 my $prompt = $oprompt;
265 0   0     0 my $commandline = shift || "";
266 0   0     0 $CPAN::CurrentCommandId ||= 1;
267              
268 0         0 local($^W) = 1;
269 0 0       0 unless ($Suppress_readline) {
270 0         0 require Term::ReadLine;
271 0 0 0     0 if (! $term
272             or
273             $term->ReadLine eq "Term::ReadLine::Stub"
274             ) {
275 0         0 $term = Term::ReadLine->new('CPAN Monitor');
276             }
277 0 0       0 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
278 0         0 my $attribs = $term->Attribs;
279             $attribs->{attempted_completion_function} = sub {
280 0     0   0 &CPAN::Complete::gnu_cpl;
281             }
282 0         0 } else {
283 0         0 $readline::rl_completion_function =
284             $readline::rl_completion_function = 'CPAN::Complete::cpl';
285             }
286 0 0       0 if (my $histfile = $CPAN::Config->{'histfile'}) {{
287 0 0       0 unless ($term->can("AddHistory")) {
  0         0  
288 0         0 $CPAN::Frontend->mywarn("Terminal does not support AddHistory.\n");
289 0 0       0 unless ($CPAN::META->has_inst('Term::ReadLine::Perl')) {
290 0         0 $CPAN::Frontend->mywarn("\nTo fix that, maybe try> install Term::ReadLine::Perl\n\n");
291             }
292 0         0 last;
293             }
294 0         0 $META->readhist($term,$histfile);
295             }}
296 0         0 for ($CPAN::Config->{term_ornaments}) { # alias
297 0         0 local $Term::ReadLine::termcap_nowarn = 1;
298 0 0       0 $term->ornaments($_) if defined;
299             }
300             # $term->OUT is autoflushed anyway
301 0         0 my $odef = select STDERR;
302 0         0 $| = 1;
303 0         0 select STDOUT;
304 0         0 $| = 1;
305 0         0 select $odef;
306             }
307              
308 0         0 $META->checklock();
309 0 0       0 my @cwd = grep { defined $_ and length $_ }
  0 0       0  
310             CPAN::anycwd(),
311             File::Spec->can("tmpdir") ? File::Spec->tmpdir() : (),
312             File::Spec->rootdir();
313 0         0 my $try_detect_readline;
314 0 0       0 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
315 0 0       0 unless ($CPAN::Config->{inhibit_startup_message}) {
316 0 0       0 my $rl_avail = $Suppress_readline ? "suppressed" :
    0          
317             ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
318             "available (maybe install Bundle::CPAN or Bundle::CPANxxl?)";
319 0         0 $CPAN::Frontend->myprint(
320             sprintf qq{
321             cpan shell -- CPAN exploration and modules installation (v%s)
322             Enter 'h' for help.
323              
324             },
325             $CPAN::VERSION,
326             )
327             }
328 0         0 my($continuation) = "";
329 0         0 my $last_term_ornaments;
330 0         0 SHELLCOMMAND: while () {
331 0 0       0 if ($Suppress_readline) {
332 0 0       0 if ($Echo_readline) {
333 0         0 $|=1;
334             }
335 0         0 print $prompt;
336 0 0       0 last SHELLCOMMAND unless defined ($_ = <> );
337 0 0       0 if ($Echo_readline) {
338             # backdoor: I could not find a way to record sessions
339 0         0 print $_;
340             }
341 0         0 chomp;
342             } else {
343             last SHELLCOMMAND unless
344 0 0       0 defined ($_ = $term->readline($prompt, $commandline));
345             }
346 0 0       0 $_ = "$continuation$_" if $continuation;
347 0         0 s/^\s+//;
348 0 0       0 next SHELLCOMMAND if /^$/;
349 0         0 s/^\s*\?\s*/help /;
350 0 0       0 if (/^(?:q(?:uit)?|bye|exit)\s*$/i) {
    0          
    0          
    0          
351 0         0 last SHELLCOMMAND;
352             } elsif (s/\\$//s) {
353 0         0 chomp;
354 0         0 $continuation = $_;
355 0         0 $prompt = " > ";
356             } elsif (/^\!/) {
357 0         0 s/^\!//;
358 0         0 my($eval) = $_;
359             package
360             CPAN::Eval; # hide from the indexer
361 22     22   162 use strict;
  22         39  
  22         765  
362 22     22   107 use vars qw($import_done);
  22         31  
  22         32083  
363 0 0       0 CPAN->import(':DEFAULT') unless $import_done++;
364 0 0       0 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
365 0         0 eval($eval);
366 0 0       0 warn $@ if $@;
367 0         0 $continuation = "";
368 0         0 $prompt = $oprompt;
369             } elsif (/./) {
370 0         0 my(@line);
371 0         0 eval { @line = Text::ParseWords::shellwords($_) };
  0         0  
372 0 0       0 warn($@), next SHELLCOMMAND if $@;
373 0 0       0 warn("Text::Parsewords could not parse the line [$_]"),
374             next SHELLCOMMAND unless @line;
375 0 0       0 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
376 0         0 my $command = shift @line;
377 0         0 eval {
378 0         0 local (*STDOUT)=*STDOUT;
379 0         0 @line = _redirect(@line);
380 0         0 CPAN::Shell->$command(@line)
381             };
382 0         0 my $command_error = $@;
383 0         0 _unredirect;
384 0         0 my $reported_error;
385 0 0       0 if ($command_error) {
386 0         0 my $err = $command_error;
387 0 0 0     0 if (ref $err and $err->isa('CPAN::Exception::blocked_urllist')) {
388 0         0 $CPAN::Frontend->mywarn("Client not fully configured, please proceed with configuring.$err");
389 0         0 $reported_error = ref $err;
390             } else {
391             # I'd prefer never to arrive here and make all errors exception objects
392 0 0       0 if ($err =~ /\S/) {
393 0         0 require Carp;
394 0         0 require Dumpvalue;
395 0         0 my $dv = Dumpvalue->new(tick => '"');
396 0         0 Carp::cluck(sprintf "Catching error: %s", $dv->stringify($err));
397             }
398             }
399             }
400 0 0       0 if ($command =~ /^(
401             # classic commands
402             make
403             |test
404             |install
405             |clean
406              
407             # pragmas for classic commands
408             |ff?orce
409             |notest
410              
411             # compounds
412             |report
413             |smoke
414             |upgrade
415             )$/x) {
416             # only commands that tell us something about failed distros
417             # eval necessary for people without an urllist
418 0         0 eval {CPAN::Shell->failed($CPAN::CurrentCommandId,1);};
  0         0  
419 0 0       0 if (my $err = $@) {
420 0 0 0     0 unless (ref $err and $reported_error eq ref $err) {
421 0         0 die $@;
422             }
423             }
424             }
425 0         0 soft_chdir_with_alternatives(\@cwd);
426 0         0 $CPAN::Frontend->myprint("\n");
427 0         0 $continuation = "";
428 0         0 $CPAN::CurrentCommandId++;
429 0         0 $prompt = $oprompt;
430             }
431             } continue {
432 0         0 $commandline = ""; # I do want to be able to pass a default to
433             # shell, but on the second command I see no
434             # use in that
435 0         0 $Signal=0;
436 0         0 CPAN::Queue->nullify_queue;
437 0 0       0 if ($try_detect_readline) {
438 0 0 0     0 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
439             ||
440             $CPAN::META->has_inst("Term::ReadLine::Perl")
441             ) {
442 0         0 delete $INC{"Term/ReadLine.pm"};
443 0         0 my $redef = 0;
444 0         0 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
445 0         0 require Term::ReadLine;
446 0         0 $CPAN::Frontend->myprint("\n$redef subroutines in ".
447             "Term::ReadLine redefined\n");
448 0         0 $GOTOSHELL = 1;
449             }
450             }
451 0 0 0     0 if ($term and $term->can("ornaments")) {
452 0         0 for ($CPAN::Config->{term_ornaments}) { # alias
453 0 0       0 if (defined $_) {
454 0 0 0     0 if (not defined $last_term_ornaments
455             or $_ != $last_term_ornaments
456             ) {
457 0         0 local $Term::ReadLine::termcap_nowarn = 1;
458 0         0 $term->ornaments($_);
459 0         0 $last_term_ornaments = $_;
460             }
461             } else {
462 0         0 undef $last_term_ornaments;
463             }
464             }
465             }
466 0         0 for my $class (qw(Module Distribution)) {
467             # again unsafe meta access?
468 0         0 for my $dm (sort keys %{$CPAN::META->{readwrite}{"CPAN::$class"}}) {
  0         0  
469 0 0       0 next unless $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor};
470 0         0 CPAN->debug("BUG: $class '$dm' was in command state, resetting");
471 0         0 delete $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor};
472             }
473             }
474 0 0       0 if ($GOTOSHELL) {
475 0         0 $GOTOSHELL = 0; # not too often
476 0 0 0     0 $META->savehist if $CPAN::term && $CPAN::term->can("GetHistory");
477 0         0 @_ = ($oprompt,"");
478 0         0 goto &shell;
479             }
480             }
481 0         0 soft_chdir_with_alternatives(\@cwd);
482             }
483              
484             #-> CPAN::soft_chdir_with_alternatives ;
485             sub soft_chdir_with_alternatives ($) {
486 0     0 0 0 my($cwd) = @_;
487 0 0       0 unless (@$cwd) {
488 0         0 my $root = File::Spec->rootdir();
489 0         0 $CPAN::Frontend->mywarn(qq{Warning: no good directory to chdir to!
490             Trying '$root' as temporary haven.
491             });
492 0         0 push @$cwd, $root;
493             }
494 0         0 while () {
495 0 0       0 if (chdir "$cwd->[0]") {
496 0         0 return;
497             } else {
498 0 0       0 if (@$cwd>1) {
499 0         0 $CPAN::Frontend->mywarn(qq{Could not chdir to "$cwd->[0]": $!
500             Trying to chdir to "$cwd->[1]" instead.
501             });
502 0         0 shift @$cwd;
503             } else {
504 0         0 $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd->[0]": $!});
505             }
506             }
507             }
508             }
509              
510             sub _flock {
511 14     14   43 my($fh,$mode) = @_;
512 14 50 33     262 if ( $Config::Config{d_flock} || $Config::Config{d_fcntl_can_lock} ) {
    0          
513 14         183 return flock $fh, $mode;
514             } elsif (!$Have_warned->{"d_flock"}++) {
515 0         0 $CPAN::Frontend->mywarn("Your OS does not seem to support locking; continuing and ignoring all locking issues\n");
516 0         0 $CPAN::Frontend->mysleep(5);
517 0         0 return 1;
518             } else {
519 0         0 return 1;
520             }
521             }
522              
523             sub _yaml_module () {
524 59   50 59   587 my $yaml_module = $CPAN::Config->{yaml_module} || "YAML";
525 59 50 33     199 if (
526             $yaml_module ne "YAML"
527             &&
528             !$CPAN::META->has_inst($yaml_module)
529             ) {
530             # $CPAN::Frontend->mywarn("'$yaml_module' not installed, falling back to 'YAML'\n");
531 0         0 $yaml_module = "YAML";
532             }
533 59 0 33     570 if ($yaml_module eq "YAML"
      33        
      33        
534             &&
535             $CPAN::META->has_inst($yaml_module)
536             &&
537             $YAML::VERSION < 0.60
538             &&
539             !$Have_warned->{"YAML"}++
540             ) {
541 0         0 $CPAN::Frontend->mywarn("Warning: YAML version '$YAML::VERSION' is too low, please upgrade!\n".
542             "I'll continue but problems are *very* likely to happen.\n"
543             );
544 0         0 $CPAN::Frontend->mysleep(5);
545             }
546 59         208 return $yaml_module;
547             }
548              
549             # CPAN::_yaml_loadfile
550             sub _yaml_loadfile {
551 7     7   21 my($self,$local_file,$opt) = @_;
552 7 50       135 return +[] unless -s $local_file;
553 0   0     0 my $opt_loadblessed = $opt->{loadblessed} || $CPAN::Config->{yaml_load_code} || 0;
554 0         0 my $yaml_module = _yaml_module;
555 0 0       0 if ($CPAN::META->has_inst($yaml_module)) {
556             # temporarily enable yaml code deserialisation
557 22     22   160 no strict 'refs';
  22         41  
  22         79944  
558             # 5.6.2 could not do the local() with the reference
559             # so we do it manually instead
560 0         0 my $old_loadcode = ${"$yaml_module\::LoadCode"};
  0         0  
561 0         0 my $old_loadblessed = ${"$yaml_module\::LoadBlessed"};
  0         0  
562 0   0     0 ${ "$yaml_module\::LoadCode" } = $CPAN::Config->{yaml_load_code} || 0;
  0         0  
563 0 0       0 ${ "$yaml_module\::LoadBlessed" } = $opt_loadblessed ? 1 : 0;
  0         0  
564              
565 0         0 my ($code, @yaml);
566 0 0       0 if ($code = UNIVERSAL::can($yaml_module, "LoadFile")) {
    0          
567 0         0 eval { @yaml = $code->($local_file); };
  0         0  
568 0 0       0 if ($@) {
569             # this shall not be done by the frontend
570 0         0 die CPAN::Exception::yaml_process_error->new($yaml_module,$local_file,"parse",$@);
571             }
572             } elsif ($code = UNIVERSAL::can($yaml_module, "Load")) {
573 0         0 local *FH;
574 0 0       0 if (open FH, $local_file) {
575 0         0 local $/;
576 0         0 my $ystream = ;
577 0         0 eval { @yaml = $code->($ystream); };
  0         0  
578 0 0       0 if ($@) {
579             # this shall not be done by the frontend
580 0         0 die CPAN::Exception::yaml_process_error->new($yaml_module,$local_file,"parse",$@);
581             }
582             } else {
583 0         0 $CPAN::Frontend->mywarn("Could not open '$local_file': $!");
584             }
585             }
586 0         0 ${"$yaml_module\::LoadCode"} = $old_loadcode;
  0         0  
587 0         0 ${"$yaml_module\::LoadBlessed"} = $old_loadblessed;
  0         0  
588 0         0 return \@yaml;
589             } else {
590             # this shall not be done by the frontend
591 0         0 die CPAN::Exception::yaml_not_installed->new($yaml_module, $local_file, "parse");
592             }
593 0         0 return +[];
594             }
595              
596             # CPAN::_yaml_dumpfile
597             sub _yaml_dumpfile {
598 0     0   0 my($self,$local_file,@what) = @_;
599 0         0 my $yaml_module = _yaml_module;
600 0 0       0 if ($CPAN::META->has_inst($yaml_module)) {
601 0         0 my $code;
602 0 0       0 if (UNIVERSAL::isa($local_file, "FileHandle")) {
    0          
    0          
603 0         0 $code = UNIVERSAL::can($yaml_module, "Dump");
604 0         0 eval { print $local_file $code->(@what) };
  0         0  
605             } elsif ($code = UNIVERSAL::can($yaml_module, "DumpFile")) {
606 0         0 eval { $code->($local_file,@what); };
  0         0  
607             } elsif ($code = UNIVERSAL::can($yaml_module, "Dump")) {
608 0         0 local *FH;
609 0 0       0 open FH, ">$local_file" or die "Could not open '$local_file': $!";
610 0         0 print FH $code->(@what);
611             }
612 0 0       0 if ($@) {
613 0         0 die CPAN::Exception::yaml_process_error->new($yaml_module,$local_file,"dump",$@);
614             }
615             } else {
616 0 0       0 if (UNIVERSAL::isa($local_file, "FileHandle")) {
617             # I think this case does not justify a warning at all
618             } else {
619 0         0 die CPAN::Exception::yaml_not_installed->new($yaml_module, $local_file, "dump");
620             }
621             }
622             }
623              
624             sub _init_sqlite () {
625 0 0   0   0 unless ($CPAN::META->has_inst("CPAN::SQLite")) {
626             $CPAN::Frontend->mywarn(qq{CPAN::SQLite not installed, trying to work without\n})
627 0 0       0 unless $Have_warned->{"CPAN::SQLite"}++;
628 0         0 return;
629             }
630 0         0 require CPAN::SQLite::META; # not needed since CVS version of 2006-12-17
631 0   0     0 $CPAN::SQLite ||= CPAN::SQLite::META->new($CPAN::META);
632             }
633              
634             {
635             my $negative_cache = {};
636             sub _sqlite_running {
637 513 100 66 513   1810 if ($negative_cache->{time} && time < $negative_cache->{time} + 60) {
638             # need to cache the result, otherwise too slow
639 505         1258 return $negative_cache->{fact};
640             } else {
641 8         41 $negative_cache = {}; # reset
642             }
643 8   33     114 my $ret = $CPAN::Config->{use_sqlite} && ($CPAN::SQLite || _init_sqlite());
644 8 50       28 return $ret if $ret; # fast anyway
645 8         41 $negative_cache->{time} = time;
646 8         53 return $negative_cache->{fact} = $ret;
647             }
648             }
649              
650             $META ||= CPAN->new; # In case we re-eval ourselves we need the ||
651              
652             # from here on only subs.
653             ################################################################################
654              
655             sub _perl_fingerprint {
656 0     0   0 my($self,$other_fingerprint) = @_;
657 0         0 my $dll = eval {OS2::DLLname()};
  0         0  
658 0         0 my $mtime_dll = 0;
659 0 0       0 if (defined $dll) {
660 0 0       0 $mtime_dll = (-f $dll ? (stat(_))[9] : '-1');
661             }
662 0 0       0 my $mtime_perl = (-f CPAN::find_perl ? (stat(_))[9] : '-1');
663             my $this_fingerprint = {
664             '$^X' => CPAN::find_perl,
665             sitearchexp => $Config::Config{sitearchexp},
666 0         0 'mtime_$^X' => $mtime_perl,
667             'mtime_dll' => $mtime_dll,
668             };
669 0 0       0 if ($other_fingerprint) {
670 0 0       0 if (exists $other_fingerprint->{'stat($^X)'}) { # repair fp from rev. 1.88_57
671 0         0 $other_fingerprint->{'mtime_$^X'} = $other_fingerprint->{'stat($^X)'}[9];
672             }
673             # mandatory keys since 1.88_57
674 0         0 for my $key (qw($^X sitearchexp mtime_dll mtime_$^X)) {
675 0 0       0 return unless $other_fingerprint->{$key} eq $this_fingerprint->{$key};
676             }
677 0         0 return 1;
678             } else {
679 0         0 return $this_fingerprint;
680             }
681             }
682              
683             sub suggest_myconfig () {
684 0 0   0 0 0 SUGGEST_MYCONFIG: if(!$INC{'CPAN/MyConfig.pm'}) {
685 0         0 $CPAN::Frontend->myprint("You don't seem to have a user ".
686             "configuration (MyConfig.pm) yet.\n");
687 0         0 my $new = CPAN::Shell::colorable_makemaker_prompt("Do you want to create a ".
688             "user configuration now? (Y/n)",
689             "yes");
690 0 0       0 if($new =~ m{^y}i) {
691 0         0 CPAN::Shell->mkmyconfig();
692 0         0 return &checklock;
693             } else {
694 0         0 $CPAN::Frontend->mydie("OK, giving up.");
695             }
696             }
697             }
698              
699             #-> sub CPAN::all_objects ;
700             sub all_objects {
701 0     0 0 0 my($mgr,$class) = @_;
702 0 0       0 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
703 0 0       0 CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
704 0         0 CPAN::Index->reload;
705 0         0 values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok
  0         0  
706             }
707              
708             # Called by shell, not in batch mode. In batch mode I see no risk in
709             # having many processes updating something as installations are
710             # continually checked at runtime. In shell mode I suspect it is
711             # unintentional to open more than one shell at a time
712              
713             #-> sub CPAN::checklock ;
714             sub checklock {
715 0     0 0 0 my($self) = @_;
716 0         0 my $lockfile = File::Spec->catfile($CPAN::Config->{cpan_home},".lock");
717 0 0 0     0 if (-f $lockfile && -M _ > 0) {
718 0 0       0 my $fh = FileHandle->new($lockfile) or
719             $CPAN::Frontend->mydie("Could not open lockfile '$lockfile': $!");
720 0         0 my $otherpid = <$fh>;
721 0         0 my $otherhost = <$fh>;
722 0         0 $fh->close;
723 0 0 0     0 if (defined $otherpid && length $otherpid) {
724 0         0 chomp $otherpid;
725             }
726 0 0 0     0 if (defined $otherhost && length $otherhost) {
727 0         0 chomp $otherhost;
728             }
729 0         0 my $thishost = hostname();
730 0         0 my $ask_if_degraded_wanted = 0;
731 0 0 0     0 if (defined $otherhost && defined $thishost &&
    0 0        
    0 0        
    0 0        
      0        
732             $otherhost ne '' && $thishost ne '' &&
733             $otherhost ne $thishost) {
734 0         0 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Lockfile '$lockfile'\n".
735             "reports other host $otherhost and other ".
736             "process $otherpid.\n".
737             "Cannot proceed.\n"));
738             } elsif ($RUN_DEGRADED) {
739 0         0 $CPAN::Frontend->mywarn("Running in downgraded mode (experimental)\n");
740             } elsif (defined $otherpid && $otherpid) {
741 0 0       0 return if $$ == $otherpid; # should never happen
742 0         0 $CPAN::Frontend->mywarn(
743             qq{
744             There seems to be running another CPAN process (pid $otherpid). Contacting...
745             });
746 0 0 0     0 if (kill 0, $otherpid or $!{EPERM}) {
    0          
747 0         0 $CPAN::Frontend->mywarn(qq{Other job is running.\n});
748 0         0 $ask_if_degraded_wanted = 1;
749             } elsif (-w $lockfile) {
750 0         0 my($ans) =
751             CPAN::Shell::colorable_makemaker_prompt
752             (qq{Other job not responding. Shall I overwrite }.
753             qq{the lockfile '$lockfile'? (Y/n)},"y");
754 0 0       0 $CPAN::Frontend->myexit("Ok, bye\n")
755             unless $ans =~ /^y/i;
756             } else {
757 0         0 Carp::croak(
758             qq{Lockfile '$lockfile' not writable by you. }.
759             qq{Cannot proceed.\n}.
760             qq{ On UNIX try:\n}.
761             qq{ rm '$lockfile'\n}.
762             qq{ and then rerun us.\n}
763             );
764             }
765             } elsif ($^O eq "MSWin32") {
766 0         0 $CPAN::Frontend->mywarn(
767             qq{
768             There seems to be running another CPAN process according to '$lockfile'.
769             });
770 0         0 $ask_if_degraded_wanted = 1;
771             } else {
772 0         0 $CPAN::Frontend->mydie(sprintf("CPAN.pm panic: Found invalid lockfile ".
773             "'$lockfile', please remove. Cannot proceed.\n"));
774             }
775 0 0       0 if ($ask_if_degraded_wanted) {
776 0         0 my($ans) =
777             CPAN::Shell::colorable_makemaker_prompt
778             (qq{Shall I try to run in downgraded }.
779             qq{mode? (Y/n)},"y");
780 0 0       0 if ($ans =~ /^y/i) {
781 0         0 $CPAN::Frontend->mywarn("Running in downgraded mode (experimental).
782             Please report if something unexpected happens\n");
783 0         0 $RUN_DEGRADED = 1;
784 0         0 for ($CPAN::Config) {
785             # XXX
786             # $_->{build_dir_reuse} = 0; # 2006-11-17 akoenig Why was that?
787 0         0 $_->{commandnumber_in_prompt} = 0; # visibility
788 0         0 $_->{histfile} = ""; # who should win otherwise?
789 0         0 $_->{cache_metadata} = 0; # better would be a lock?
790 0         0 $_->{use_sqlite} = 0; # better would be a write lock!
791 0         0 $_->{auto_commit} = 0; # we are violent, do not persist
792 0         0 $_->{test_report} = 0; # Oliver Paukstadt had sent wrong reports in degraded mode
793             }
794             } else {
795 0         0 my $msg = "You may want to kill the other job and delete the lockfile.";
796 0 0       0 if (defined $otherpid) {
797 0         0 $msg .= " Something like:
798             kill $otherpid
799             rm $lockfile
800             ";
801             }
802 0         0 $CPAN::Frontend->mydie("\n$msg");
803             }
804             }
805             }
806 0         0 my $dotcpan = $CPAN::Config->{cpan_home};
807 0         0 eval { File::Path::mkpath($dotcpan);};
  0         0  
808 0 0       0 if ($@) {
809             # A special case at least for Jarkko.
810 0         0 my $firsterror = $@;
811 0         0 my $seconderror;
812             my $symlinkcpan;
813 0 0       0 if (-l $dotcpan) {
814 0         0 $symlinkcpan = readlink $dotcpan;
815 0 0       0 die "readlink $dotcpan failed: $!" unless defined $symlinkcpan;
816 0         0 eval { File::Path::mkpath($symlinkcpan); };
  0         0  
817 0 0       0 if ($@) {
818 0         0 $seconderror = $@;
819             } else {
820 0         0 $CPAN::Frontend->mywarn(qq{
821             Working directory $symlinkcpan created.
822             });
823             }
824             }
825 0 0       0 unless (-d $dotcpan) {
826 0         0 my $mess = qq{
827             Your configuration suggests "$dotcpan" as your
828             CPAN.pm working directory. I could not create this directory due
829             to this error: $firsterror\n};
830 0 0       0 $mess .= qq{
831             As "$dotcpan" is a symlink to "$symlinkcpan",
832             I tried to create that, but I failed with this error: $seconderror
833             } if $seconderror;
834 0         0 $mess .= qq{
835             Please make sure the directory exists and is writable.
836             };
837 0         0 $CPAN::Frontend->mywarn($mess);
838 0         0 return suggest_myconfig;
839             }
840             } # $@ after eval mkpath $dotcpan
841 0         0 if (0) { # to test what happens when a race condition occurs
842             for (reverse 1..10) {
843             print $_, "\n";
844             sleep 1;
845             }
846             }
847             # locking
848 0 0 0     0 if (!$RUN_DEGRADED && !$self->{LOCKFH}) {
849 0         0 my $fh;
850 0 0       0 unless ($fh = FileHandle->new("+>>$lockfile")) {
851 0         0 $CPAN::Frontend->mywarn(qq{
852              
853             Your configuration suggests that CPAN.pm should use a working
854             directory of
855             $CPAN::Config->{cpan_home}
856             Unfortunately we could not create the lock file
857             $lockfile
858             due to '$!'.
859              
860             Please make sure that the configuration variable
861             \$CPAN::Config->{cpan_home}
862             points to a directory where you can write a .lock file. You can set
863             this variable in either a CPAN/MyConfig.pm or a CPAN/Config.pm in your
864             \@INC path;
865             });
866 0         0 return suggest_myconfig;
867             }
868 0         0 my $sleep = 1;
869 0         0 while (!CPAN::_flock($fh, LOCK_EX|LOCK_NB)) {
870 0   0     0 my $err = $! || "unknown error";
871 0 0       0 if ($sleep>3) {
872 0         0 $CPAN::Frontend->mydie("Could not lock '$lockfile' with flock: $err; giving up\n");
873             }
874 0         0 $CPAN::Frontend->mysleep($sleep+=0.1);
875 0         0 $CPAN::Frontend->mywarn("Could not lock '$lockfile' with flock: $err; retrying\n");
876             }
877              
878 0         0 seek $fh, 0, 0;
879 0         0 truncate $fh, 0;
880 0         0 $fh->autoflush(1);
881 0         0 $fh->print($$, "\n");
882 0         0 $fh->print(hostname(), "\n");
883 0         0 $self->{LOCK} = $lockfile;
884 0         0 $self->{LOCKFH} = $fh;
885             }
886             $SIG{TERM} = sub {
887 0     0   0 my $sig = shift;
888 0         0 &cleanup;
889 0         0 $CPAN::Frontend->mydie("Got SIG$sig, leaving");
890 0         0 };
891             $SIG{INT} = sub {
892             # no blocks!!!
893 0     0   0 my $sig = shift;
894 0 0       0 &cleanup if $Signal;
895 0 0       0 die "Got yet another signal" if $Signal > 1;
896 0 0       0 $CPAN::Frontend->mydie("Got another SIG$sig") if $Signal;
897 0         0 $CPAN::Frontend->mywarn("Caught SIG$sig, trying to continue\n");
898 0         0 $Signal++;
899 0         0 };
900              
901             # From: Larry Wall
902             # Subject: Re: deprecating SIGDIE
903             # To: perl5-porters@perl.org
904             # Date: Thu, 30 Sep 1999 14:58:40 -0700 (PDT)
905             #
906             # The original intent of __DIE__ was only to allow you to substitute one
907             # kind of death for another on an application-wide basis without respect
908             # to whether you were in an eval or not. As a global backstop, it should
909             # not be used any more lightly (or any more heavily :-) than class
910             # UNIVERSAL. Any attempt to build a general exception model on it should
911             # be politely squashed. Any bug that causes every eval {} to have to be
912             # modified should be not so politely squashed.
913             #
914             # Those are my current opinions. It is also my opinion that polite
915             # arguments degenerate to personal arguments far too frequently, and that
916             # when they do, it's because both people wanted it to, or at least didn't
917             # sufficiently want it not to.
918             #
919             # Larry
920              
921             # global backstop to cleanup if we should really die
922 0         0 $SIG{__DIE__} = \&cleanup;
923 0 0       0 $self->debug("Signal handler set.") if $CPAN::DEBUG;
924             }
925              
926             #-> sub CPAN::DESTROY ;
927             sub DESTROY {
928 0     0   0 &cleanup; # need an eval?
929             }
930              
931             #-> sub CPAN::anycwd ;
932             sub anycwd () {
933 29     29 1 48 my $getcwd;
934 29   100     139 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
935 29         183 CPAN->$getcwd();
936             }
937              
938             #-> sub CPAN::cwd ;
939 29     29 1 175874 sub cwd {Cwd::cwd();}
940              
941             #-> sub CPAN::getcwd ;
942 0     0 1 0 sub getcwd {Cwd::getcwd();}
943              
944             #-> sub CPAN::fastcwd ;
945 0     0 1 0 sub fastcwd {Cwd::fastcwd();}
946              
947             #-> sub CPAN::getdcwd ;
948 0     0 1 0 sub getdcwd {Cwd::getdcwd();}
949              
950             #-> sub CPAN::backtickcwd ;
951 0     0 1 0 sub backtickcwd {my $cwd = `cwd`; chomp $cwd; $cwd}
  0         0  
  0         0  
952              
953             # Adapted from Probe::Perl
954             #-> sub CPAN::_perl_is_same
955             sub _perl_is_same {
956 0     0   0 my ($perl) = @_;
957 0   0     0 return MM->maybe_command($perl)
958             && `$perl -MConfig=myconfig -e print -e myconfig` eq Config->myconfig;
959             }
960              
961             # Adapted in part from Probe::Perl
962             #-> sub CPAN::find_perl ;
963             sub find_perl () {
964 22 50   22 0 1331 if ( File::Spec->file_name_is_absolute($^X) ) {
965 22         259 return $^X;
966             }
967             else {
968 0         0 my $exe = $Config::Config{exe_ext};
969             my @candidates = (
970             File::Spec->catfile($CPAN::iCwd,$^X),
971 0         0 $Config::Config{'perlpath'},
972             );
973 0         0 for my $perl_name ($^X, 'perl', 'perl5', "perl$]") {
974 0         0 for my $path (File::Spec->path(), $Config::Config{'binexp'}) {
975 0 0 0     0 if ( defined($path) && length $path && -d $path ) {
      0        
976 0         0 my $perl = File::Spec->catfile($path,$perl_name);
977 0         0 push @candidates, $perl;
978             # try with extension if not provided already
979 0 0 0     0 if ($^O eq 'VMS') {
    0          
980             # VMS might have a file version at the end
981 0 0       0 push @candidates, $perl . $exe
982             unless $perl =~ m/$exe(;\d+)?$/i;
983             } elsif (defined $exe && length $exe) {
984 0 0       0 push @candidates, $perl . $exe
985             unless $perl =~ m/$exe$/i;
986             }
987             }
988             }
989             }
990 0         0 for my $perl ( @candidates ) {
991 0 0 0     0 if (MM->maybe_command($perl) && _perl_is_same($perl)) {
992 0         0 $^X = $perl;
993 0         0 return $perl;
994             }
995             }
996             }
997 0         0 return $^X; # default fall back
998             }
999              
1000             #-> sub CPAN::exists ;
1001             sub exists {
1002 143     143 0 394 my($mgr,$class,$id) = @_;
1003 143 50       386 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
1004 143         763 CPAN::Index->reload;
1005             ### Carp::croak "exists called without class argument" unless $class;
1006 143   50     270 $id ||= "";
1007 143 100       684 $id =~ s/:+/::/g if $class eq "CPAN::Module";
1008 143         178 my $exists;
1009 143 50       202 if (CPAN::_sqlite_running) {
1010 0   0     0 $exists = (exists $META->{readonly}{$class}{$id} or
1011             $CPAN::SQLite->set($class, $id));
1012             } else {
1013 143         393 $exists = exists $META->{readonly}{$class}{$id};
1014             }
1015 143   100     678 $exists ||= exists $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
1016             }
1017              
1018             #-> sub CPAN::delete ;
1019             sub delete {
1020 0     0 0 0 my($mgr,$class,$id) = @_;
1021 0         0 delete $META->{readonly}{$class}{$id}; # unsafe meta access, ok
1022 0         0 delete $META->{readwrite}{$class}{$id}; # unsafe meta access, ok
1023             }
1024              
1025             #-> sub CPAN::has_usable
1026             # has_inst is sometimes too optimistic, we should replace it with this
1027             # has_usable whenever a case is given
1028             sub has_usable {
1029 253     253 1 882 my($self,$mod,$message) = @_;
1030 253 100       977 return 1 if $HAS_USABLE->{$mod};
1031 66         303 my $has_inst = $self->has_inst($mod,$message);
1032 66 100       260 return unless $has_inst;
1033 53         97 my $usable;
1034             $usable = {
1035              
1036             #
1037             # most of these subroutines warn on the frontend, then
1038             # die if the installed version is unusable for some
1039             # reason; has_usable() then returns false when it caught
1040             # an exception, otherwise returns true and caches that;
1041             #
1042             'CPAN::Meta' => [
1043             sub {
1044 8     8   62 require CPAN::Meta;
1045 8 50       214 unless (CPAN::Version->vge(CPAN::Meta->VERSION, 2.110350)) {
1046 0         0 for ("Will not use CPAN::Meta, need version 2.110350\n") {
1047 0         0 $CPAN::Frontend->mywarn($_);
1048 0         0 die $_;
1049             }
1050             }
1051             },
1052             ],
1053              
1054             'CPAN::Meta::Requirements' => [
1055             sub {
1056 7 50 33 7   181 if (defined $CPAN::Meta::Requirements::VERSION
1057             && CPAN::Version->vlt($CPAN::Meta::Requirements::VERSION, "2.120920")
1058             ) {
1059 0         0 delete $INC{"CPAN/Meta/Requirements.pm"};
1060             }
1061 7         50 require CPAN::Meta::Requirements;
1062 7 50       209 unless (CPAN::Version->vge(CPAN::Meta::Requirements->VERSION, 2.120920)) {
1063 0         0 for ("Will not use CPAN::Meta::Requirements, need version 2.120920\n") {
1064 0         0 $CPAN::Frontend->mywarn($_);
1065 0         0 die $_;
1066             }
1067             }
1068             },
1069             ],
1070              
1071             'CPAN::Reporter' => [
1072             sub {
1073 0 0 0 0   0 if (defined $CPAN::Reporter::VERSION
1074             && CPAN::Version->vlt($CPAN::Reporter::VERSION, "1.2011")
1075             ) {
1076 0         0 delete $INC{"CPAN/Reporter.pm"};
1077             }
1078 0         0 require CPAN::Reporter;
1079 0 0       0 unless (CPAN::Version->vge(CPAN::Reporter->VERSION, "1.2011")) {
1080 0         0 for ("Will not use CPAN::Reporter, need version 1.2011\n") {
1081 0         0 $CPAN::Frontend->mywarn($_);
1082 0         0 die $_;
1083             }
1084             }
1085             },
1086             ],
1087              
1088             LWP => [ # we frequently had "Can't locate object
1089             # method "new" via package "LWP::UserAgent" at
1090             # (eval 69) line 2006
1091 0     0   0 sub {require LWP},
1092 0     0   0 sub {require LWP::UserAgent},
1093 0     0   0 sub {require HTTP::Request},
1094 0     0   0 sub {require URI::URL;
1095 0 0       0 unless (CPAN::Version->vge(URI::URL::->VERSION,0.08)) {
1096 0         0 for ("Will not use URI::URL, need 0.08\n") {
1097 0         0 $CPAN::Frontend->mywarn($_);
1098 0         0 die $_;
1099             }
1100             }
1101             },
1102             ],
1103             'Net::FTP' => [
1104             sub {
1105 0   0 0   0 my $var = $CPAN::Config->{ftp_proxy} || $ENV{ftp_proxy};
1106 0 0 0     0 if ($var and $var =~ /^http:/i) {
1107             # rt #110833
1108 0         0 for ("Net::FTP cannot handle http proxy") {
1109 0         0 $CPAN::Frontend->mywarn($_);
1110 0         0 die $_;
1111             }
1112             }
1113             },
1114 0     0   0 sub {require Net::FTP},
1115 0     0   0 sub {require Net::Config},
1116             ],
1117             'IO::Socket::SSL' => [
1118             sub {
1119 0     0   0 require IO::Socket::SSL;
1120 0 0       0 unless (CPAN::Version->vge(IO::Socket::SSL::->VERSION,1.56)) {
1121 0         0 for ("Will not use IO::Socket::SSL, need 1.56\n") {
1122 0         0 $CPAN::Frontend->mywarn($_);
1123 0         0 die $_;
1124             }
1125             }
1126             }
1127             ],
1128             'Net::SSLeay' => [
1129             sub {
1130 0     0   0 require Net::SSLeay;
1131 0 0       0 unless (CPAN::Version->vge(Net::SSLeay::->VERSION,1.49)) {
1132 0         0 for ("Will not use Net::SSLeay, need 1.49\n") {
1133 0         0 $CPAN::Frontend->mywarn($_);
1134 0         0 die $_;
1135             }
1136             }
1137             }
1138             ],
1139             'HTTP::Tiny' => [
1140             sub {
1141 0     0   0 require HTTP::Tiny;
1142 0 0       0 unless (CPAN::Version->vge(HTTP::Tiny->VERSION, 0.005)) {
1143 0         0 for ("Will not use HTTP::Tiny, need version 0.005\n") {
1144 0         0 $CPAN::Frontend->mywarn($_);
1145 0         0 die $_;
1146             }
1147             }
1148             },
1149             ],
1150             'File::HomeDir' => [
1151 0     0   0 sub {require File::HomeDir;
1152 0 0       0 unless (CPAN::Version->vge(File::HomeDir::->VERSION, 0.52)) {
1153 0         0 for ("Will not use File::HomeDir, need 0.52\n") {
1154 0         0 $CPAN::Frontend->mywarn($_);
1155 0         0 die $_;
1156             }
1157             }
1158             },
1159             ],
1160             'Archive::Tar' => [
1161 8     8   147 sub {require Archive::Tar;
1162 8         24 my $demand = "1.50";
1163 8 50       249 unless (CPAN::Version->vge(Archive::Tar::->VERSION, $demand)) {
1164 0         0 my $atv = Archive::Tar->VERSION;
1165 0         0 for ("You have Archive::Tar $atv, but $demand or later is recommended. Please upgrade.\n") {
1166 0         0 $CPAN::Frontend->mywarn($_);
1167             # don't die, because we may need
1168             # Archive::Tar to upgrade
1169             }
1170              
1171             }
1172             },
1173             ],
1174             'File::Temp' => [
1175             # XXX we should probably delete from
1176             # %INC too so we can load after we
1177             # installed a new enough version --
1178             # I'm not sure.
1179 0     0   0 sub {require File::Temp;
1180 0 0       0 unless (CPAN::Version->vge(File::Temp::->VERSION,0.16)) {
1181 0         0 for ("Will not use File::Temp, need 0.16\n") {
1182 0         0 $CPAN::Frontend->mywarn($_);
1183 0         0 die $_;
1184             }
1185             }
1186             },
1187 53         3525 ]
1188             };
1189 53 100       297 if ($usable->{$mod}) {
1190 23         123 local @INC = @INC;
1191 23 50       68 pop @INC if $INC[-1] eq '.';
1192 23         42 for my $c (0..$#{$usable->{$mod}}) {
  23         136  
1193 23         63 my $code = $usable->{$mod}[$c];
1194 23         39 my $ret = eval { &$code() };
  23         191  
1195 23 50       76 $ret = "" unless defined $ret;
1196 23 50       135 if ($@) {
1197             # warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
1198 0         0 return;
1199             }
1200             }
1201             }
1202 53         2166 return $HAS_USABLE->{$mod} = 1;
1203             }
1204              
1205             sub frontend {
1206 0     0 1 0 shift;
1207 0 0       0 $CPAN::Frontend = shift if @_;
1208 0         0 $CPAN::Frontend;
1209             }
1210              
1211             sub use_inst {
1212 14     14 1 55 my ($self, $module) = @_;
1213              
1214 14 50       54 unless ($self->has_inst($module)) {
1215 0         0 $self->frontend->mydie("$module not installed, cannot continue");
1216             }
1217             }
1218              
1219             #-> sub CPAN::has_inst
1220             sub has_inst {
1221 489     489 1 5012 my($self,$mod,$message) = @_;
1222 489 50       1005 Carp::croak("CPAN->has_inst() called without an argument")
1223             unless defined $mod;
1224 15 100       43 my %dont = map { $_ => 1 } keys %{$CPAN::META->{dontload_hash}||{}},
  489         2813  
1225 489 100       1435 keys %{$CPAN::Config->{dontload_hash}||{}},
1226 489 50       640 @{$CPAN::Config->{dontload_list}||[]};
  489         2146  
1227 489 100 66     2307 if (defined $message && $message eq "no" # as far as I remember only used by Nox
      100        
1228             ||
1229             $dont{$mod}
1230             ) {
1231 9   100     7630 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
1232 9         44 return 0;
1233             }
1234 480         3671 local @INC = @INC;
1235 480 50       1013 pop @INC if $INC[-1] eq '.';
1236 480         710 my $file = $mod;
1237 480         607 my $obj;
1238 480         1965 $file =~ s|::|/|g;
1239 480         823 $file .= ".pm";
1240 480 100       1390 if ($INC{$file}) {
    100          
    50          
    50          
    50          
1241             # checking %INC is wrong, because $INC{LWP} may be true
1242             # although $INC{"URI/URL.pm"} may have failed. But as
1243             # I really want to say "blah loaded OK", I have to somehow
1244             # cache results.
1245             ### warn "$file in %INC"; #debug
1246 295         1233 return 1;
1247 185         71398 } elsif (eval { require $file }) {
1248             # eval is good: if we haven't yet read the database it's
1249             # perfect and if we have installed the module in the meantime,
1250             # it tries again. The second require is only a NOOP returning
1251             # 1 if we had success, otherwise it's retrying
1252              
1253 54         1933101 my $mtime = (stat $INC{$file})[9];
1254             # privileged files loaded by has_inst; Note: we use $mtime
1255             # as a proxy for a checksum.
1256 54         539 $CPAN::Shell::reload->{$file} = $mtime;
1257 54         11126 my $v = eval "\$$mod\::VERSION";
1258 54 50       426 $v = $v ? " (v$v)" : "";
1259 54         912 CPAN::Shell->optprint("load_module","CPAN: $mod loaded ok$v\n");
1260 54 50       252 if ($mod eq "CPAN::WAIT") {
1261 0         0 push @CPAN::Shell::ISA, 'CPAN::WAIT';
1262             }
1263 54         599 return 1;
1264             } elsif ($mod eq "Net::FTP") {
1265             $CPAN::Frontend->mywarn(qq{
1266             Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
1267             if you just type
1268             install Bundle::libnet
1269              
1270 0 0       0 }) unless $Have_warned->{"Net::FTP"}++;
1271 0         0 $CPAN::Frontend->mysleep(3);
1272             } elsif ($mod eq "Digest::SHA") {
1273 0 0       0 if ($Have_warned->{"Digest::SHA"}++) {
1274 0         0 $CPAN::Frontend->mywarn(qq{CPAN: checksum security checks disabled }.
1275             qq{because Digest::SHA not installed.\n});
1276             } else {
1277 0         0 $CPAN::Frontend->mywarn(qq{
1278             CPAN: checksum security checks disabled because Digest::SHA not installed.
1279             Please consider installing the Digest::SHA module.
1280              
1281             });
1282 0         0 $CPAN::Frontend->mysleep(2);
1283             }
1284             } elsif ($mod eq "Module::Signature") {
1285             # NOT prefs_lookup, we are not a distro
1286 0         0 my $check_sigs = $CPAN::Config->{check_sigs};
1287 0 0       0 if (not $check_sigs) {
    0          
1288             # they do not want us:-(
1289             } elsif (not $Have_warned->{"Module::Signature"}++) {
1290             # No point in complaining unless the user can
1291             # reasonably install and use it.
1292 0 0 0     0 if (eval { require Crypt::OpenPGP; 1 } ||
  0   0     0  
  0         0  
1293             (
1294             defined $CPAN::Config->{'gpg'}
1295             &&
1296             $CPAN::Config->{'gpg'} =~ /\S/
1297             )
1298             ) {
1299 0         0 $CPAN::Frontend->mywarn(qq{
1300             CPAN: Module::Signature security checks disabled because Module::Signature
1301             not installed. Please consider installing the Module::Signature module.
1302             You may also need to be able to connect over the Internet to the public
1303             key servers like pool.sks-keyservers.net or pgp.mit.edu.
1304              
1305             });
1306 0         0 $CPAN::Frontend->mysleep(2);
1307             }
1308             }
1309             } else {
1310 131         358 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
1311             }
1312 131         736 return 0;
1313             }
1314              
1315             #-> sub CPAN::instance ;
1316             sub instance {
1317 157     157 1 344 my($mgr,$class,$id) = @_;
1318 157         604 CPAN::Index->reload;
1319 157   50     329 $id ||= "";
1320             # unsafe meta access, ok?
1321 157 100       574 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
1322 60   33     597 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
1323             }
1324              
1325             #-> sub CPAN::new ;
1326             sub new {
1327 22     22 0 335 bless {}, shift;
1328             }
1329              
1330             #-> sub CPAN::_exit_messages ;
1331             sub _exit_messages {
1332 0     0   0 my ($self) = @_;
1333 0   0     0 $self->{exit_messages} ||= [];
1334             }
1335              
1336             #-> sub CPAN::cleanup ;
1337             sub cleanup {
1338             # warn "cleanup called with arg[@_] End[$CPAN::End] Signal[$Signal]";
1339 22     22 0 407 local $SIG{__DIE__} = '';
1340 22         126 my($message) = @_;
1341 22         89 my $i = 0;
1342 22         225 my $ineval = 0;
1343 22         124 my($subroutine);
1344 22         483 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
1345 44 100       270 $ineval = 1, last if
1346             $subroutine eq '(eval)';
1347             }
1348 22 50 33     442 return if $ineval && !$CPAN::End;
1349 22 50       511 return unless defined $META->{LOCK};
1350 0 0       0 return unless -f $META->{LOCK};
1351 0         0 $META->savehist;
1352 0   0     0 $META->{cachemgr} ||= CPAN::CacheMgr->new('atexit');
1353 0         0 close $META->{LOCKFH};
1354 0         0 unlink $META->{LOCK};
1355             # require Carp;
1356             # Carp::cluck("DEBUGGING");
1357 0 0       0 if ( $CPAN::CONFIG_DIRTY ) {
1358 0         0 $CPAN::Frontend->mywarn("Warning: Configuration not saved.\n");
1359             }
1360 0         0 $CPAN::Frontend->myprint("Lockfile removed.\n");
1361 0         0 for my $msg ( @{ $META->_exit_messages } ) {
  0         0  
1362 0         0 $CPAN::Frontend->myprint($msg);
1363             }
1364             }
1365              
1366             #-> sub CPAN::readhist
1367             sub readhist {
1368 0     0 0 0 my($self,$term,$histfile) = @_;
1369 0   0     0 my $histsize = $CPAN::Config->{'histsize'} || 100;
1370 0 0       0 $term->Attribs->{'MaxHistorySize'} = $histsize if (defined($term->Attribs->{'MaxHistorySize'}));
1371 0         0 my($fh) = FileHandle->new;
1372 0 0       0 open $fh, "<$histfile" or return;
1373 0         0 local $/ = "\n";
1374 0         0 while (<$fh>) {
1375 0         0 chomp;
1376 0         0 $term->AddHistory($_);
1377             }
1378 0         0 close $fh;
1379             }
1380              
1381             #-> sub CPAN::savehist
1382             sub savehist {
1383 0     0 0 0 my($self) = @_;
1384 0         0 my($histfile,$histsize);
1385 0 0       0 unless ($histfile = $CPAN::Config->{'histfile'}) {
1386 0         0 $CPAN::Frontend->mywarn("No history written (no histfile specified).\n");
1387 0         0 return;
1388             }
1389 0   0     0 $histsize = $CPAN::Config->{'histsize'} || 100;
1390 0 0       0 if ($CPAN::term) {
1391 0 0       0 unless ($CPAN::term->can("GetHistory")) {
1392 0         0 $CPAN::Frontend->mywarn("Terminal does not support GetHistory.\n");
1393 0         0 return;
1394             }
1395             } else {
1396 0         0 return;
1397             }
1398 0         0 my @h = $CPAN::term->GetHistory;
1399 0 0       0 splice @h, 0, @h-$histsize if @h>$histsize;
1400 0         0 my($fh) = FileHandle->new;
1401 0 0       0 open $fh, ">$histfile" or $CPAN::Frontend->mydie("Couldn't open >$histfile: $!");
1402 0         0 local $\ = local $, = "\n";
1403 0         0 print $fh @h;
1404 0         0 close $fh;
1405             }
1406              
1407             #-> sub CPAN::is_tested
1408             sub is_tested {
1409 1     1 1 10 my($self,$what,$when) = @_;
1410 1 50       37 unless ($what) {
1411 0         0 Carp::cluck("DEBUG: empty what");
1412 0         0 return;
1413             }
1414 1         33 $self->{is_tested}{$what} = $when;
1415             }
1416              
1417             #-> sub CPAN::reset_tested
1418             # forget all distributions tested -- resets what gets included in PERL5LIB
1419             sub reset_tested {
1420 0     0 0 0 my ($self) = @_;
1421 0         0 $self->{is_tested} = {};
1422             }
1423              
1424             #-> sub CPAN::is_installed
1425             # unsets the is_tested flag: as soon as the thing is installed, it is
1426             # not needed in set_perl5lib anymore
1427             sub is_installed {
1428 1     1 0 30 my($self,$what) = @_;
1429 1         24 delete $self->{is_tested}{$what};
1430             }
1431              
1432             sub _list_sorted_descending_is_tested {
1433 1     1   2 my($self) = @_;
1434 1         7 my $foul = 0;
1435             my @sorted = sort
1436 0   0     0 { ($self->{is_tested}{$b}||0) <=> ($self->{is_tested}{$a}||0) }
      0        
1437             grep
1438 1 50       77 { if ($foul){ 0 } elsif (-e) { 1 } else { $foul = $_; 0 } }
  0 50       0  
  1         8  
  0         0  
  0         0  
1439 1         2 keys %{$self->{is_tested}};
  1         9  
1440 1 50       9 if ($foul) {
1441 0         0 $CPAN::Frontend->mywarn("Lost build_dir detected ($foul), giving up all cached test results of currently running session.\n");
1442 0         0 for my $dbd (sort keys %{$self->{is_tested}}) { # distro-build-dir
  0         0  
1443 0         0 SEARCH: for my $d (sort { $a->id cmp $b->id } $CPAN::META->all_objects("CPAN::Distribution")) {
  0         0  
1444 0 0 0     0 if ($d->{build_dir} && $d->{build_dir} eq $dbd) {
1445 0         0 $CPAN::Frontend->mywarn(sprintf "Flushing cache for %s\n", $d->pretty_id);
1446 0         0 $d->fforce("");
1447 0         0 last SEARCH;
1448             }
1449             }
1450 0         0 delete $self->{is_tested}{$dbd};
1451             }
1452 0         0 return ();
1453             } else {
1454 1         11 return @sorted;
1455             }
1456             }
1457              
1458             #-> sub CPAN::set_perl5lib
1459             # Notes on max environment variable length:
1460             # - Win32 : XP or later, 8191; Win2000 or NT4, 2047
1461             {
1462             my $fh;
1463             sub set_perl5lib {
1464 23     23 0 88 my($self,$for) = @_;
1465 23 50       66 unless ($for) {
1466 23         296 (undef,undef,undef,$for) = caller(1);
1467 23         280 $for =~ s/.*://;
1468             }
1469 23   100     182 $self->{is_tested} ||= {};
1470 23 100       44 return unless %{$self->{is_tested}};
  23         142  
1471 1         7 my $env = $ENV{PERL5LIB};
1472 1 50       8 $env = $ENV{PERLLIB} unless defined $env;
1473 1         2 my @env;
1474 1 50 33     66 push @env, split /\Q$Config::Config{path_sep}\E/, $env if defined $env and length $env;
1475             #my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}};
1476             #$CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
1477              
1478 1         15 my @dirs = map {("$_/blib/arch", "$_/blib/lib")} $self->_list_sorted_descending_is_tested;
  1         25  
1479 1 50       8 return if !@dirs;
1480              
1481 1 50       7 if (@dirs < 12) {
    0          
1482 1         21 $CPAN::Frontend->optprint('perl5lib', "Prepending @dirs to PERL5LIB for '$for'\n");
1483 1         34 $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1484             } elsif (@dirs < 24 ) {
1485 0           my @d = map {my $cp = $_;
  0            
1486 0           $cp =~ s/^\Q$CPAN::Config->{build_dir}\E/%BUILDDIR%/;
1487 0           $cp
1488             } @dirs;
1489 0           $CPAN::Frontend->optprint('perl5lib', "Prepending @d to PERL5LIB; ".
1490             "%BUILDDIR%=$CPAN::Config->{build_dir} ".
1491             "for '$for'\n"
1492             );
1493 0           $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1494             } else {
1495 0           my $cnt = keys %{$self->{is_tested}};
  0            
1496 0           my $newenv = join $Config::Config{path_sep}, @dirs, @env;
1497 0           $CPAN::Frontend->optprint('perl5lib', sprintf ("Prepending blib/arch and blib/lib of ".
1498             "%d build dirs to PERL5LIB, reaching size %d; ".
1499             "for '%s'\n", $cnt, length($newenv), $for)
1500             );
1501 0           $ENV{PERL5LIB} = $newenv;
1502             }
1503             }}
1504              
1505              
1506             1;
1507              
1508              
1509             __END__