File Coverage

blib/lib/CPAN.pm
Criterion Covered Total %
statement 247 819 30.1
branch 51 394 12.9
condition 23 168 13.6
subroutine 63 107 58.8
pod 13 27 48.1
total 397 1515 26.2


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 13     13   113438 use strict;
  13         80  
  13         1070  
4             package CPAN;
5             $CPAN::VERSION = '2.28';
6             $CPAN::VERSION =~ s/_//;
7              
8             # we need to run chdir all over and we would get at wrong libraries
9             # there
10 13     13   92 use File::Spec ();
  13         38  
  13         1276  
11             BEGIN {
12 13 50   13   353 if (File::Spec->can("rel2abs")) {
13 13         48 for my $inc (@INC) {
14 148 50       1828 $inc = File::Spec->rel2abs($inc) unless ref $inc;
15             }
16             }
17 13 50       830 $SIG{WINCH} = 'IGNORE' if exists $SIG{WINCH};
18             }
19 13     13   5649 use CPAN::Author;
  13         29  
  13         430  
20 13     13   6391 use CPAN::HandleConfig;
  13         36  
  13         506  
21 13     13   4973 use CPAN::Version;
  13         30  
  13         418  
22 13     13   5510 use CPAN::Bundle;
  13         36  
  13         407  
23 13     13   5569 use CPAN::CacheMgr;
  13         38  
  13         506  
24 13     13   5561 use CPAN::Complete;
  13         31  
  13         414  
25 13     13   85 use CPAN::Debug;
  13         20  
  13         252  
26 13     13   11654 use CPAN::Distribution;
  13         40  
  13         649  
27 13     13   6747 use CPAN::Distrostatus;
  13         30  
  13         752  
28 13     13   6936 use CPAN::FTP;
  13         37  
  13         521  
29 13     13   6334 use CPAN::Index 1.93; # https://rt.cpan.org/Ticket/Display.html?id=43349
  13         370  
  13         421  
30 13     13   87 use CPAN::InfoObj;
  13         27  
  13         248  
31 13     13   65 use CPAN::Module;
  13         23  
  13         240  
32 13     13   5323 use CPAN::Prompt;
  13         31  
  13         448  
33 13     13   5175 use CPAN::URL;
  13         33  
  13         367  
34 13     13   5229 use CPAN::Queue;
  13         32  
  13         375  
35 13     13   5874 use CPAN::Tarzip;
  13         34  
  13         490  
36 13     13   5163 use CPAN::DeferredCode;
  13         34  
  13         490  
37 13     13   8342 use CPAN::Shell;
  13         35  
  13         483  
38 13     13   5855 use CPAN::LWP::UserAgent;
  13         34  
  13         392  
39 13     13   5516 use CPAN::Exception::RecursiveDependency;
  13         31  
  13         392  
40 13     13   5248 use CPAN::Exception::yaml_not_installed;
  13         36  
  13         371  
41 13     13   5267 use CPAN::Exception::yaml_process_error;
  13         32  
  13         345  
42              
43 13     13   76 use Carp ();
  13         28  
  13         186  
44 13     13   55 use Config ();
  13         30  
  13         266  
45 13     13   56 use Cwd qw(chdir);
  13         23  
  13         575  
46 13     13   65 use DirHandle ();
  13         23  
  13         174  
47 13     13   51 use Exporter ();
  13         21  
  13         287  
48 13     13   9916 use ExtUtils::MakeMaker qw(prompt); # for some unknown reason,
  13         1256851  
  13         860  
49             # 5.005_04 does not work without
50             # this
51 13     13   111 use File::Basename ();
  13         39  
  13         208  
52 13     13   4988 use File::Copy ();
  13         22377  
  13         330  
53 13     13   78 use File::Find;
  13         25  
  13         721  
54 13     13   83 use File::Path ();
  13         31  
  13         182  
55 13     13   5401 use FileHandle ();
  13         94590  
  13         430  
56 13     13   131 use Fcntl qw(:flock);
  13         26  
  13         1585  
57 13     13   6981 use Safe ();
  13         456140  
  13         725  
58 13     13   5695 use Sys::Hostname qw(hostname);
  13         13002  
  13         880  
59 13     13   5823 use Text::ParseWords ();
  13         14404  
  13         356  
60 13     13   5683 use Text::Wrap ();
  13         29410  
  13         676  
61              
62             # protect against "called too early"
63             sub find_perl ();
64             sub anycwd ();
65             sub _uniq;
66              
67 13     13   5152 no lib ".";
  13         6469  
  13         83  
68              
69             require Mac::BuildTools if $^O eq 'MacOS';
70             if ($ENV{PERL5_CPAN_IS_RUNNING} && $$ != $ENV{PERL5_CPAN_IS_RUNNING}) {
71             $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION} ||= $ENV{PERL5_CPAN_IS_RUNNING};
72             my @rec = _uniq split(/,/, $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION}), $$;
73             $ENV{PERL5_CPAN_IS_RUNNING_IN_RECURSION} = join ",", @rec;
74             # warn "# Note: Recursive call of CPAN.pm detected\n";
75             my $w = sprintf "# Note: CPAN.pm is running in process %d now", pop @rec;
76             my %sleep = (
77             5 => 30,
78             6 => 60,
79             7 => 120,
80             );
81             my $sleep = @rec > 7 ? 300 : ($sleep{scalar @rec}||0);
82             my $verbose = @rec >= 4;
83             while (@rec) {
84             $w .= sprintf " which has been called by process %d", pop @rec;
85             }
86             if ($sleep) {
87             $w .= ".\n\n# Sleeping $sleep seconds to protect other processes\n";
88             }
89             if ($verbose) {
90             warn $w;
91             }
92             local $| = 1;
93             my $have_been_sleeping = 0;
94             while ($sleep > 0) {
95             printf "\r#%5d", --$sleep;
96             sleep 1;
97             ++$have_been_sleeping;
98             }
99             print "\n" if $have_been_sleeping;
100             }
101             $ENV{PERL5_CPAN_IS_RUNNING}=$$;
102             $ENV{PERL5_CPANPLUS_IS_RUNNING}=$$; # https://rt.cpan.org/Ticket/Display.html?id=23735
103              
104 13     13   7501080 END { $CPAN::End++; &cleanup; }
  13         89  
105              
106             $CPAN::Signal ||= 0;
107             $CPAN::Frontend ||= "CPAN::Shell";
108             unless (@CPAN::Defaultsites) {
109             @CPAN::Defaultsites = map {
110             CPAN::URL->new(TEXT => $_, FROM => "DEF")
111             }
112             "http://www.perl.org/CPAN/",
113             "ftp://ftp.perl.org/pub/CPAN/";
114             }
115             # $CPAN::iCwd (i for initial)
116             $CPAN::iCwd ||= CPAN::anycwd();
117             $CPAN::Perl ||= CPAN::find_perl();
118             $CPAN::Defaultdocs ||= "http://search.cpan.org/perldoc?";
119             $CPAN::Defaultrecent ||= "http://search.cpan.org/uploads.rdf";
120             $CPAN::Defaultrecent ||= "http://cpan.uwinnipeg.ca/htdocs/cpan.xml";
121              
122             # our globals are getting a mess
123 13         16820 use vars qw(
124             $AUTOLOAD
125             $Be_Silent
126             $CONFIG_DIRTY
127             $Defaultdocs
128             $Echo_readline
129             $Frontend
130             $GOTOSHELL
131             $HAS_USABLE
132             $Have_warned
133             $MAX_RECURSION
134             $META
135             $RUN_DEGRADED
136             $Signal
137             $SQLite
138             $Suppress_readline
139             $VERSION
140             $autoload_recursion
141             $term
142             @Defaultsites
143             @EXPORT
144 13     13   5205 );
  13         27  
145              
146             $MAX_RECURSION = 32;
147              
148             @CPAN::ISA = qw(CPAN::Debug Exporter);
149              
150             # note that these functions live in CPAN::Shell and get executed via
151             # AUTOLOAD when called directly
152             @EXPORT = qw(
153             autobundle
154             bundle
155             clean
156             cvs_import
157             expand
158             force
159             fforce
160             get
161             install
162             install_tested
163             is_tested
164             make
165             mkmyconfig
166             notest
167             perldoc
168             readme
169             recent
170             recompile
171             report
172             shell
173             smoke
174             test
175             upgrade
176             );
177              
178             sub soft_chdir_with_alternatives ($);
179              
180             {
181             $autoload_recursion ||= 0;
182              
183             #-> sub CPAN::AUTOLOAD ;
184             sub AUTOLOAD { ## no critic
185 1     1   17 $autoload_recursion++;
186 1         11 my($l) = $AUTOLOAD;
187 1         17 $l =~ s/.*:://;
188 1 50       11 if ($CPAN::Signal) {
189 0         0 warn "Refusing to autoload '$l' while signal pending";
190 0         0 $autoload_recursion--;
191 0         0 return;
192             }
193 1 50       6 if ($autoload_recursion > 1) {
194 0         0 my $fullcommand = join " ", map { "'$_'" } $l, @_;
  0         0  
195 0         0 warn "Refusing to autoload $fullcommand in recursion\n";
196 0         0 $autoload_recursion--;
197 0         0 return;
198             }
199 1         10 my(%export);
200 1         88 @export{@EXPORT} = '';
201 1 50       35 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
202 1 50       4 if (exists $export{$l}) {
203 0         0 CPAN::Shell->$l(@_);
204             } else {
205 1         22 die(qq{Unknown CPAN command "$AUTOLOAD". }.
206             qq{Type ? for help.\n});
207             }
208 0         0 $autoload_recursion--;
209             }
210             }
211              
212             {
213             my $x = *SAVEOUT; # avoid warning
214             open($x,">&STDOUT") or die "dup failed";
215             my $redir = 0;
216             sub _redirect(@) {
217             #die if $redir;
218 0     0   0 local $_;
219 0         0 push(@_,undef);
220 0         0 while(defined($_=shift)) {
221 0 0       0 if (s/^\s*>//){
    0          
222 0 0       0 my ($m) = s/^>// ? ">" : "";
223 0         0 s/\s+//;
224 0 0       0 $_=shift unless length;
225 0 0       0 die "no dest" unless defined;
226 0 0       0 open(STDOUT,">$m$_") or die "open:$_:$!\n";
227 0         0 $redir=1;
228             } elsif ( s/^\s*\|\s*// ) {
229 0         0 my $pipe="| $_";
230 0         0 while(defined($_[0])){
231 0         0 $pipe .= ' ' . shift;
232             }
233 0 0       0 open(STDOUT,$pipe) or die "open:$pipe:$!\n";
234 0         0 $redir=1;
235             } else {
236 0         0 push(@_,$_);
237             }
238             }
239 0         0 return @_;
240             }
241             sub _unredirect {
242 0 0   0   0 return unless $redir;
243 0         0 $redir = 0;
244             ## redirect: unredirect and propagate errors. explicit close to wait for pipe.
245 0         0 close(STDOUT);
246 0         0 open(STDOUT,">&SAVEOUT");
247 0 0       0 die "$@" if "$@";
248             ## redirect: done
249             }
250             }
251              
252             sub _uniq {
253 0     0   0 my(@list) = @_;
254 0         0 my %seen;
255 0         0 return grep { !$seen{$_}++ } @list;
  0         0  
256             }
257              
258             #-> sub CPAN::shell ;
259             sub shell {
260 0     0 1 0 my($self) = @_;
261 0 0       0 $Suppress_readline = ! -t STDIN unless defined $Suppress_readline;
262 0 0       0 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
263              
264 0   0     0 my $oprompt = shift || CPAN::Prompt->new;
265 0         0 my $prompt = $oprompt;
266 0   0     0 my $commandline = shift || "";
267 0   0     0 $CPAN::CurrentCommandId ||= 1;
268              
269 0         0 local($^W) = 1;
270 0 0       0 unless ($Suppress_readline) {
271 0         0 require Term::ReadLine;
272 0 0 0     0 if (! $term
273             or
274             $term->ReadLine eq "Term::ReadLine::Stub"
275             ) {
276 0         0 $term = Term::ReadLine->new('CPAN Monitor');
277             }
278 0 0       0 if ($term->ReadLine eq "Term::ReadLine::Gnu") {
279 0         0 my $attribs = $term->Attribs;
280             $attribs->{attempted_completion_function} = sub {
281 0     0   0 &CPAN::Complete::gnu_cpl;
282             }
283 0         0 } else {
284 0         0 $readline::rl_completion_function =
285             $readline::rl_completion_function = 'CPAN::Complete::cpl';
286             }
287 0 0       0 if (my $histfile = $CPAN::Config->{'histfile'}) {{
288 0 0       0 unless ($term->can("AddHistory")) {
  0         0  
289 0         0 $CPAN::Frontend->mywarn("Terminal does not support AddHistory.\n");
290 0 0       0 unless ($CPAN::META->has_inst('Term::ReadLine::Perl')) {
291 0         0 $CPAN::Frontend->mywarn("\nTo fix that, maybe try> install Term::ReadLine::Perl\n\n");
292             }
293 0         0 last;
294             }
295 0         0 $META->readhist($term,$histfile);
296             }}
297 0         0 for ($CPAN::Config->{term_ornaments}) { # alias
298 0         0 local $Term::ReadLine::termcap_nowarn = 1;
299 0 0       0 $term->ornaments($_) if defined;
300             }
301             # $term->OUT is autoflushed anyway
302 0         0 my $odef = select STDERR;
303 0         0 $| = 1;
304 0         0 select STDOUT;
305 0         0 $| = 1;
306 0         0 select $odef;
307             }
308              
309 0         0 $META->checklock();
310 0 0       0 my @cwd = grep { defined $_ and length $_ }
  0 0       0  
311             CPAN::anycwd(),
312             File::Spec->can("tmpdir") ? File::Spec->tmpdir() : (),
313             File::Spec->rootdir();
314 0         0 my $try_detect_readline;
315 0 0       0 $try_detect_readline = $term->ReadLine eq "Term::ReadLine::Stub" if $term;
316 0 0       0 unless ($CPAN::Config->{inhibit_startup_message}) {
317 0 0       0 my $rl_avail = $Suppress_readline ? "suppressed" :
    0          
318             ($term->ReadLine ne "Term::ReadLine::Stub") ? "enabled" :
319             "available (maybe install Bundle::CPAN or Bundle::CPANxxl?)";
320 0         0 $CPAN::Frontend->myprint(
321             sprintf qq{
322             cpan shell -- CPAN exploration and modules installation (v%s)
323             Enter 'h' for help.
324              
325             },
326             $CPAN::VERSION,
327             )
328             }
329 0         0 my($continuation) = "";
330 0         0 my $last_term_ornaments;
331 0         0 SHELLCOMMAND: while () {
332 0 0       0 if ($Suppress_readline) {
333 0 0       0 if ($Echo_readline) {
334 0         0 $|=1;
335             }
336 0         0 print $prompt;
337 0 0       0 last SHELLCOMMAND unless defined ($_ = <> );
338 0 0       0 if ($Echo_readline) {
339             # backdoor: I could not find a way to record sessions
340 0         0 print $_;
341             }
342 0         0 chomp;
343             } else {
344             last SHELLCOMMAND unless
345 0 0       0 defined ($_ = $term->readline($prompt, $commandline));
346             }
347 0 0       0 $_ = "$continuation$_" if $continuation;
348 0         0 s/^\s+//;
349 0 0       0 next SHELLCOMMAND if /^$/;
350 0         0 s/^\s*\?\s*/help /;
351 0 0       0 if (/^(?:q(?:uit)?|bye|exit)\s*$/i) {
    0          
    0          
    0          
352 0         0 last SHELLCOMMAND;
353             } elsif (s/\\$//s) {
354 0         0 chomp;
355 0         0 $continuation = $_;
356 0         0 $prompt = " > ";
357             } elsif (/^\!/) {
358 0         0 s/^\!//;
359 0         0 my($eval) = $_;
360             package
361             CPAN::Eval; # hide from the indexer
362 13     13   107 use strict;
  13         25  
  13         347  
363 13     13   69 use vars qw($import_done);
  13         28  
  13         15247  
364 0 0       0 CPAN->import(':DEFAULT') unless $import_done++;
365 0 0       0 CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
366 0         0 eval($eval);
367 0 0       0 warn $@ if $@;
368 0         0 $continuation = "";
369 0         0 $prompt = $oprompt;
370             } elsif (/./) {
371 0         0 my(@line);
372 0         0 eval { @line = Text::ParseWords::shellwords($_) };
  0         0  
373 0 0       0 warn($@), next SHELLCOMMAND if $@;
374 0 0       0 warn("Text::Parsewords could not parse the line [$_]"),
375             next SHELLCOMMAND unless @line;
376 0 0       0 $CPAN::META->debug("line[".join("|",@line)."]") if $CPAN::DEBUG;
377 0         0 my $command = shift @line;
378 0         0 eval {
379 0         0 local (*STDOUT)=*STDOUT;
380 0         0 @line = _redirect(@line);
381 0         0 CPAN::Shell->$command(@line)
382             };
383 0         0 my $command_error = $@;
384 0         0 _unredirect;
385 0         0 my $reported_error;
386 0 0       0 if ($command_error) {
387 0         0 my $err = $command_error;
388 0 0 0     0 if (ref $err and $err->isa('CPAN::Exception::blocked_urllist')) {
389 0         0 $CPAN::Frontend->mywarn("Client not fully configured, please proceed with configuring.$err");
390 0         0 $reported_error = ref $err;
391             } else {
392             # I'd prefer never to arrive here and make all errors exception objects
393 0 0       0 if ($err =~ /\S/) {
394 0         0 require Carp;
395 0         0 require Dumpvalue;
396 0         0 my $dv = Dumpvalue->new(tick => '"');
397 0         0 Carp::cluck(sprintf "Catching error: %s", $dv->stringify($err));
398             }
399             }
400             }
401 0 0       0 if ($command =~ /^(
402             # classic commands
403             make
404             |test
405             |install
406             |clean
407              
408             # pragmas for classic commands
409             |ff?orce
410             |notest
411              
412             # compounds
413             |report
414             |smoke
415             |upgrade
416             )$/x) {
417             # only commands that tell us something about failed distros
418             # eval necessary for people without an urllist
419 0         0 eval {CPAN::Shell->failed($CPAN::CurrentCommandId,1);};
  0         0  
420 0 0       0 if (my $err = $@) {
421 0 0 0     0 unless (ref $err and $reported_error eq ref $err) {
422 0         0 die $@;
423             }
424             }
425             }
426 0         0 soft_chdir_with_alternatives(\@cwd);
427 0         0 $CPAN::Frontend->myprint("\n");
428 0         0 $continuation = "";
429 0         0 $CPAN::CurrentCommandId++;
430 0         0 $prompt = $oprompt;
431             }
432             } continue {
433 0         0 $commandline = ""; # I do want to be able to pass a default to
434             # shell, but on the second command I see no
435             # use in that
436 0         0 $Signal=0;
437 0         0 CPAN::Queue->nullify_queue;
438 0 0       0 if ($try_detect_readline) {
439 0 0 0     0 if ($CPAN::META->has_inst("Term::ReadLine::Gnu")
440             ||
441             $CPAN::META->has_inst("Term::ReadLine::Perl")
442             ) {
443 0         0 delete $INC{"Term/ReadLine.pm"};
444 0         0 my $redef = 0;
445 0         0 local($SIG{__WARN__}) = CPAN::Shell::paintdots_onreload(\$redef);
446 0         0 require Term::ReadLine;
447 0         0 $CPAN::Frontend->myprint("\n$redef subroutines in ".
448             "Term::ReadLine redefined\n");
449 0         0 $GOTOSHELL = 1;
450             }
451             }
452 0 0 0     0 if ($term and $term->can("ornaments")) {
453 0         0 for ($CPAN::Config->{term_ornaments}) { # alias
454 0 0       0 if (defined $_) {
455 0 0 0     0 if (not defined $last_term_ornaments
456             or $_ != $last_term_ornaments
457             ) {
458 0         0 local $Term::ReadLine::termcap_nowarn = 1;
459 0         0 $term->ornaments($_);
460 0         0 $last_term_ornaments = $_;
461             }
462             } else {
463 0         0 undef $last_term_ornaments;
464             }
465             }
466             }
467 0         0 for my $class (qw(Module Distribution)) {
468             # again unsafe meta access?
469 0         0 for my $dm (sort keys %{$CPAN::META->{readwrite}{"CPAN::$class"}}) {
  0         0  
470 0 0       0 next unless $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor};
471 0         0 CPAN->debug("BUG: $class '$dm' was in command state, resetting");
472 0         0 delete $CPAN::META->{readwrite}{"CPAN::$class"}{$dm}{incommandcolor};
473             }
474             }
475 0 0       0 if ($GOTOSHELL) {
476 0         0 $GOTOSHELL = 0; # not too often
477 0 0 0     0 $META->savehist if $CPAN::term && $CPAN::term->can("GetHistory");
478 0         0 @_ = ($oprompt,"");
479 0         0 goto &shell;
480             }
481             }
482 0         0 soft_chdir_with_alternatives(\@cwd);
483             }
484              
485             #-> CPAN::soft_chdir_with_alternatives ;
486             sub soft_chdir_with_alternatives ($) {
487 0     0 0 0 my($cwd) = @_;
488 0 0       0 unless (@$cwd) {
489 0         0 my $root = File::Spec->rootdir();
490 0         0 $CPAN::Frontend->mywarn(qq{Warning: no good directory to chdir to!
491             Trying '$root' as temporary haven.
492             });
493 0         0 push @$cwd, $root;
494             }
495 0         0 while () {
496 0 0       0 if (chdir "$cwd->[0]") {
497 0         0 return;
498             } else {
499 0 0       0 if (@$cwd>1) {
500 0         0 $CPAN::Frontend->mywarn(qq{Could not chdir to "$cwd->[0]": $!
501             Trying to chdir to "$cwd->[1]" instead.
502             });
503 0         0 shift @$cwd;
504             } else {
505 0         0 $CPAN::Frontend->mydie(qq{Could not chdir to "$cwd->[0]": $!});
506             }
507             }
508             }
509             }
510              
511             sub _flock {
512 0     0   0 my($fh,$mode) = @_;
513 0 0 0     0 if ( $Config::Config{d_flock} || $Config::Config{d_fcntl_can_lock} ) {
    0          
514 0         0 return flock $fh, $mode;
515             } elsif (!$Have_warned->{"d_flock"}++) {
516 0         0 $CPAN::Frontend->mywarn("Your OS does not seem to support locking; continuing and ignoring all locking issues\n");
517 0         0 $CPAN::Frontend->mysleep(5);
518 0         0 return 1;
519             } else {
520 0         0 return 1;
521             }
522             }
523              
524             sub _yaml_module () {
525 3   50 3   15 my $yaml_module = $CPAN::Config->{yaml_module} || "YAML";
526 3 50 33     11 if (
527             $yaml_module ne "YAML"
528             &&
529             !$CPAN::META->has_inst($yaml_module)
530             ) {
531             # $CPAN::Frontend->mywarn("'$yaml_module' not installed, falling back to 'YAML'\n");
532 0         0 $yaml_module = "YAML";
533             }
534 3 0 33     13 if ($yaml_module eq "YAML"
      33        
      33        
535             &&
536             $CPAN::META->has_inst($yaml_module)
537             &&
538             $YAML::VERSION < 0.60
539             &&
540             !$Have_warned->{"YAML"}++
541             ) {
542 0         0 $CPAN::Frontend->mywarn("Warning: YAML version '$YAML::VERSION' is too low, please upgrade!\n".
543             "I'll continue but problems are *very* likely to happen.\n"
544             );
545 0         0 $CPAN::Frontend->mysleep(5);
546             }
547 3         13 return $yaml_module;
548             }
549              
550             # CPAN::_yaml_loadfile
551             sub _yaml_loadfile {
552 0     0   0 my($self,$local_file) = @_;
553 0 0       0 return +[] unless -s $local_file;
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 13     13   104 no strict 'refs';
  13         38  
  13         49128  
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 ${ "$yaml_module\::LoadBlessed" } = 1;
  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 130 100 66 130   383 if ($negative_cache->{time} && time < $negative_cache->{time} + 60) {
638             # need to cache the result, otherwise too slow
639 129         298 return $negative_cache->{fact};
640             } else {
641 1         3 $negative_cache = {}; # reset
642             }
643 1   33     5 my $ret = $CPAN::Config->{use_sqlite} && ($CPAN::SQLite || _init_sqlite());
644 1 50       3 return $ret if $ret; # fast anyway
645 1         7 $negative_cache->{time} = time;
646 1         7 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 13     13 1 26 my $getcwd;
934 13   100     66 $getcwd = $CPAN::Config->{'getcwd'} || 'cwd';
935 13         76 CPAN->$getcwd();
936             }
937              
938             #-> sub CPAN::cwd ;
939 13     13 1 48976 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 13 50   13 0 1291 if ( File::Spec->file_name_is_absolute($^X) ) {
965 13         261 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 31     31 0 65 my($mgr,$class,$id) = @_;
1003 31 50       67 CPAN::HandleConfig->load unless $CPAN::Config_loaded++;
1004 31         114 CPAN::Index->reload;
1005             ### Carp::croak "exists called without class argument" unless $class;
1006 31   50     63 $id ||= "";
1007 31 100       70 $id =~ s/:+/::/g if $class eq "CPAN::Module";
1008 31         35 my $exists;
1009 31 50       52 if (CPAN::_sqlite_running) {
1010 0   0     0 $exists = (exists $META->{readonly}{$class}{$id} or
1011             $CPAN::SQLite->set($class, $id));
1012             } else {
1013 31         87 $exists = exists $META->{readonly}{$class}{$id};
1014             }
1015 31   66     164 $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 115     115 1 242 my($self,$mod,$message) = @_;
1030 115 100       423 return 1 if $HAS_USABLE->{$mod};
1031 6         50 my $has_inst = $self->has_inst($mod,$message);
1032 6 100       24 return unless $has_inst;
1033 3         7 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 1     1   9 require CPAN::Meta;
1045 1 50       41 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 0 0 0 0   0 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 0         0 require CPAN::Meta::Requirements;
1062 0 0       0 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             'HTTP::Tiny' => [
1118             sub {
1119 0     0   0 require HTTP::Tiny;
1120 0 0       0 unless (CPAN::Version->vge(HTTP::Tiny->VERSION, 0.005)) {
1121 0         0 for ("Will not use HTTP::Tiny, need version 0.005\n") {
1122 0         0 $CPAN::Frontend->mywarn($_);
1123 0         0 die $_;
1124             }
1125             }
1126             },
1127             ],
1128             'File::HomeDir' => [
1129 0     0   0 sub {require File::HomeDir;
1130 0 0       0 unless (CPAN::Version->vge(File::HomeDir::->VERSION, 0.52)) {
1131 0         0 for ("Will not use File::HomeDir, need 0.52\n") {
1132 0         0 $CPAN::Frontend->mywarn($_);
1133 0         0 die $_;
1134             }
1135             }
1136             },
1137             ],
1138             'Archive::Tar' => [
1139 1     1   9 sub {require Archive::Tar;
1140 1         6 my $demand = "1.50";
1141 1 50       46 unless (CPAN::Version->vge(Archive::Tar::->VERSION, $demand)) {
1142 0         0 my $atv = Archive::Tar->VERSION;
1143 0         0 for ("You have Archive::Tar $atv, but $demand or later is recommended. Please upgrade.\n") {
1144 0         0 $CPAN::Frontend->mywarn($_);
1145             # don't die, because we may need
1146             # Archive::Tar to upgrade
1147             }
1148              
1149             }
1150             },
1151             ],
1152             'File::Temp' => [
1153             # XXX we should probably delete from
1154             # %INC too so we can load after we
1155             # installed a new enough version --
1156             # I'm not sure.
1157 0     0   0 sub {require File::Temp;
1158 0 0       0 unless (CPAN::Version->vge(File::Temp::->VERSION,0.16)) {
1159 0         0 for ("Will not use File::Temp, need 0.16\n") {
1160 0         0 $CPAN::Frontend->mywarn($_);
1161 0         0 die $_;
1162             }
1163             }
1164             },
1165 3         219 ]
1166             };
1167 3 100       22 if ($usable->{$mod}) {
1168 2         18 local @INC = @INC;
1169 2 50       12 pop @INC if $INC[-1] eq '.';
1170 2         11 for my $c (0..$#{$usable->{$mod}}) {
  2         15  
1171 2         9 my $code = $usable->{$mod}[$c];
1172 2         14 my $ret = eval { &$code() };
  2         9  
1173 2 50       11 $ret = "" unless defined $ret;
1174 2 50       17 if ($@) {
1175             # warn "DEBUG: c[$c]\$\@[$@]ret[$ret]";
1176 0         0 return;
1177             }
1178             }
1179             }
1180 3         217 return $HAS_USABLE->{$mod} = 1;
1181             }
1182              
1183             sub frontend {
1184 0     0 1 0 shift;
1185 0 0       0 $CPAN::Frontend = shift if @_;
1186 0         0 $CPAN::Frontend;
1187             }
1188              
1189             sub use_inst {
1190 8     8 1 19 my ($self, $module) = @_;
1191              
1192 8 50       29 unless ($self->has_inst($module)) {
1193 0         0 $self->frontend->mydie("$module not installed, cannot continue");
1194             }
1195             }
1196              
1197             #-> sub CPAN::has_inst
1198             sub has_inst {
1199 51     51 1 2338 my($self,$mod,$message) = @_;
1200 51 50       159 Carp::croak("CPAN->has_inst() called without an argument")
1201             unless defined $mod;
1202 15 100       49 my %dont = map { $_ => 1 } keys %{$CPAN::META->{dontload_hash}||{}},
  51         322  
1203 51 50       254 keys %{$CPAN::Config->{dontload_hash}||{}},
1204 51 50       86 @{$CPAN::Config->{dontload_list}||[]};
  51         224  
1205 51 100 66     334 if (defined $message && $message eq "no" # as far as I remember only used by Nox
      100        
1206             ||
1207             $dont{$mod}
1208             ) {
1209 9   100     70 $CPAN::META->{dontload_hash}{$mod}||=1; # unsafe meta access, ok
1210 9         34 return 0;
1211             }
1212 42         395 local @INC = @INC;
1213 42 50       118 pop @INC if $INC[-1] eq '.';
1214 42         68 my $file = $mod;
1215 42         66 my $obj;
1216 42         216 $file =~ s|::|/|g;
1217 42         95 $file .= ".pm";
1218 42 100       126 if ($INC{$file}) {
    100          
    50          
    50          
    50          
1219             # checking %INC is wrong, because $INC{LWP} may be true
1220             # although $INC{"URI/URL.pm"} may have failed. But as
1221             # I really want to say "blah loaded OK", I have to somehow
1222             # cache results.
1223             ### warn "$file in %INC"; #debug
1224 25         121 return 1;
1225 17         9532 } elsif (eval { require $file }) {
1226             # eval is good: if we haven't yet read the database it's
1227             # perfect and if we have installed the module in the meantime,
1228             # it tries again. The second require is only a NOOP returning
1229             # 1 if we had success, otherwise it's retrying
1230              
1231 7         245739 my $mtime = (stat $INC{$file})[9];
1232             # privileged files loaded by has_inst; Note: we use $mtime
1233             # as a proxy for a checksum.
1234 7         78 $CPAN::Shell::reload->{$file} = $mtime;
1235 7         1095 my $v = eval "\$$mod\::VERSION";
1236 7 50       65 $v = $v ? " (v$v)" : "";
1237 7         178 CPAN::Shell->optprint("load_module","CPAN: $mod loaded ok$v\n");
1238 7 50       52 if ($mod eq "CPAN::WAIT") {
1239 0         0 push @CPAN::Shell::ISA, 'CPAN::WAIT';
1240             }
1241 7         83 return 1;
1242             } elsif ($mod eq "Net::FTP") {
1243             $CPAN::Frontend->mywarn(qq{
1244             Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
1245             if you just type
1246             install Bundle::libnet
1247              
1248 0 0       0 }) unless $Have_warned->{"Net::FTP"}++;
1249 0         0 $CPAN::Frontend->mysleep(3);
1250             } elsif ($mod eq "Digest::SHA") {
1251 0 0       0 if ($Have_warned->{"Digest::SHA"}++) {
1252 0         0 $CPAN::Frontend->mywarn(qq{CPAN: checksum security checks disabled }.
1253             qq{because Digest::SHA not installed.\n});
1254             } else {
1255 0         0 $CPAN::Frontend->mywarn(qq{
1256             CPAN: checksum security checks disabled because Digest::SHA not installed.
1257             Please consider installing the Digest::SHA module.
1258              
1259             });
1260 0         0 $CPAN::Frontend->mysleep(2);
1261             }
1262             } elsif ($mod eq "Module::Signature") {
1263             # NOT prefs_lookup, we are not a distro
1264 0         0 my $check_sigs = $CPAN::Config->{check_sigs};
1265 0 0       0 if (not $check_sigs) {
    0          
1266             # they do not want us:-(
1267             } elsif (not $Have_warned->{"Module::Signature"}++) {
1268             # No point in complaining unless the user can
1269             # reasonably install and use it.
1270 0 0 0     0 if (eval { require Crypt::OpenPGP; 1 } ||
  0   0     0  
  0         0  
1271             (
1272             defined $CPAN::Config->{'gpg'}
1273             &&
1274             $CPAN::Config->{'gpg'} =~ /\S/
1275             )
1276             ) {
1277 0         0 $CPAN::Frontend->mywarn(qq{
1278             CPAN: Module::Signature security checks disabled because Module::Signature
1279             not installed. Please consider installing the Module::Signature module.
1280             You may also need to be able to connect over the Internet to the public
1281             key servers like pool.sks-keyservers.net or pgp.mit.edu.
1282              
1283             });
1284 0         0 $CPAN::Frontend->mysleep(2);
1285             }
1286             }
1287             } else {
1288 10         31 delete $INC{$file}; # if it inc'd LWP but failed during, say, URI
1289             }
1290 10         67 return 0;
1291             }
1292              
1293             #-> sub CPAN::instance ;
1294             sub instance {
1295 46     46 1 111 my($mgr,$class,$id) = @_;
1296 46         134 CPAN::Index->reload;
1297 46   50     85 $id ||= "";
1298             # unsafe meta access, ok?
1299 46 100       175 return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id};
1300 41   33     341 $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id);
1301             }
1302              
1303             #-> sub CPAN::new ;
1304             sub new {
1305 13     13 0 323 bless {}, shift;
1306             }
1307              
1308             #-> sub CPAN::_exit_messages ;
1309             sub _exit_messages {
1310 0     0   0 my ($self) = @_;
1311 0   0     0 $self->{exit_messages} ||= [];
1312             }
1313              
1314             #-> sub CPAN::cleanup ;
1315             sub cleanup {
1316             # warn "cleanup called with arg[@_] End[$CPAN::End] Signal[$Signal]";
1317 13     13 0 126 local $SIG{__DIE__} = '';
1318 13         54 my($message) = @_;
1319 13         44 my $i = 0;
1320 13         39 my $ineval = 0;
1321 13         44 my($subroutine);
1322 13         152 while ((undef,undef,undef,$subroutine) = caller(++$i)) {
1323 26 100       159 $ineval = 1, last if
1324             $subroutine eq '(eval)';
1325             }
1326 13 50 33     215 return if $ineval && !$CPAN::End;
1327 13 50       471 return unless defined $META->{LOCK};
1328 0 0         return unless -f $META->{LOCK};
1329 0           $META->savehist;
1330 0   0       $META->{cachemgr} ||= CPAN::CacheMgr->new('atexit');
1331 0           close $META->{LOCKFH};
1332 0           unlink $META->{LOCK};
1333             # require Carp;
1334             # Carp::cluck("DEBUGGING");
1335 0 0         if ( $CPAN::CONFIG_DIRTY ) {
1336 0           $CPAN::Frontend->mywarn("Warning: Configuration not saved.\n");
1337             }
1338 0           $CPAN::Frontend->myprint("Lockfile removed.\n");
1339 0           for my $msg ( @{ $META->_exit_messages } ) {
  0            
1340 0           $CPAN::Frontend->myprint($msg);
1341             }
1342             }
1343              
1344             #-> sub CPAN::readhist
1345             sub readhist {
1346 0     0 0   my($self,$term,$histfile) = @_;
1347 0   0       my $histsize = $CPAN::Config->{'histsize'} || 100;
1348 0 0         $term->Attribs->{'MaxHistorySize'} = $histsize if (defined($term->Attribs->{'MaxHistorySize'}));
1349 0           my($fh) = FileHandle->new;
1350 0 0         open $fh, "<$histfile" or return;
1351 0           local $/ = "\n";
1352 0           while (<$fh>) {
1353 0           chomp;
1354 0           $term->AddHistory($_);
1355             }
1356 0           close $fh;
1357             }
1358              
1359             #-> sub CPAN::savehist
1360             sub savehist {
1361 0     0 0   my($self) = @_;
1362 0           my($histfile,$histsize);
1363 0 0         unless ($histfile = $CPAN::Config->{'histfile'}) {
1364 0           $CPAN::Frontend->mywarn("No history written (no histfile specified).\n");
1365 0           return;
1366             }
1367 0   0       $histsize = $CPAN::Config->{'histsize'} || 100;
1368 0 0         if ($CPAN::term) {
1369 0 0         unless ($CPAN::term->can("GetHistory")) {
1370 0           $CPAN::Frontend->mywarn("Terminal does not support GetHistory.\n");
1371 0           return;
1372             }
1373             } else {
1374 0           return;
1375             }
1376 0           my @h = $CPAN::term->GetHistory;
1377 0 0         splice @h, 0, @h-$histsize if @h>$histsize;
1378 0           my($fh) = FileHandle->new;
1379 0 0         open $fh, ">$histfile" or $CPAN::Frontend->mydie("Couldn't open >$histfile: $!");
1380 0           local $\ = local $, = "\n";
1381 0           print $fh @h;
1382 0           close $fh;
1383             }
1384              
1385             #-> sub CPAN::is_tested
1386             sub is_tested {
1387 0     0 1   my($self,$what,$when) = @_;
1388 0 0         unless ($what) {
1389 0           Carp::cluck("DEBUG: empty what");
1390 0           return;
1391             }
1392 0           $self->{is_tested}{$what} = $when;
1393             }
1394              
1395             #-> sub CPAN::reset_tested
1396             # forget all distributions tested -- resets what gets included in PERL5LIB
1397             sub reset_tested {
1398 0     0 0   my ($self) = @_;
1399 0           $self->{is_tested} = {};
1400             }
1401              
1402             #-> sub CPAN::is_installed
1403             # unsets the is_tested flag: as soon as the thing is installed, it is
1404             # not needed in set_perl5lib anymore
1405             sub is_installed {
1406 0     0 0   my($self,$what) = @_;
1407 0           delete $self->{is_tested}{$what};
1408             }
1409              
1410             sub _list_sorted_descending_is_tested {
1411 0     0     my($self) = @_;
1412 0           my $foul = 0;
1413             my @sorted = sort
1414 0   0       { ($self->{is_tested}{$b}||0) <=> ($self->{is_tested}{$a}||0) }
      0        
1415             grep
1416 0 0         { if ($foul){ 0 } elsif (-e) { 1 } else { $foul = $_; 0 } }
  0 0          
  0            
  0            
  0            
1417 0           keys %{$self->{is_tested}};
  0            
1418 0 0         if ($foul) {
1419 0           $CPAN::Frontend->mywarn("Lost build_dir detected ($foul), giving up all cached test results of currently running session.\n");
1420 0           for my $dbd (sort keys %{$self->{is_tested}}) { # distro-build-dir
  0            
1421 0           SEARCH: for my $d (sort { $a->id cmp $b->id } $CPAN::META->all_objects("CPAN::Distribution")) {
  0            
1422 0 0 0       if ($d->{build_dir} && $d->{build_dir} eq $dbd) {
1423 0           $CPAN::Frontend->mywarn(sprintf "Flushing cache for %s\n", $d->pretty_id);
1424 0           $d->fforce("");
1425 0           last SEARCH;
1426             }
1427             }
1428 0           delete $self->{is_tested}{$dbd};
1429             }
1430 0           return ();
1431             } else {
1432 0           return @sorted;
1433             }
1434             }
1435              
1436             #-> sub CPAN::set_perl5lib
1437             # Notes on max environment variable length:
1438             # - Win32 : XP or later, 8191; Win2000 or NT4, 2047
1439             {
1440             my $fh;
1441             sub set_perl5lib {
1442 0     0 0   my($self,$for) = @_;
1443 0 0         unless ($for) {
1444 0           (undef,undef,undef,$for) = caller(1);
1445 0           $for =~ s/.*://;
1446             }
1447 0   0       $self->{is_tested} ||= {};
1448 0 0         return unless %{$self->{is_tested}};
  0            
1449 0           my $env = $ENV{PERL5LIB};
1450 0 0         $env = $ENV{PERLLIB} unless defined $env;
1451 0           my @env;
1452 0 0 0       push @env, split /\Q$Config::Config{path_sep}\E/, $env if defined $env and length $env;
1453             #my @dirs = map {("$_/blib/arch", "$_/blib/lib")} keys %{$self->{is_tested}};
1454             #$CPAN::Frontend->myprint("Prepending @dirs to PERL5LIB.\n");
1455              
1456 0           my @dirs = map {("$_/blib/arch", "$_/blib/lib")} $self->_list_sorted_descending_is_tested;
  0            
1457 0 0         return if !@dirs;
1458              
1459 0 0         if (@dirs < 12) {
    0          
1460 0           $CPAN::Frontend->optprint('perl5lib', "Prepending @dirs to PERL5LIB for '$for'\n");
1461 0           $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1462             } elsif (@dirs < 24 ) {
1463 0           my @d = map {my $cp = $_;
  0            
1464 0           $cp =~ s/^\Q$CPAN::Config->{build_dir}\E/%BUILDDIR%/;
1465 0           $cp
1466             } @dirs;
1467 0           $CPAN::Frontend->optprint('perl5lib', "Prepending @d to PERL5LIB; ".
1468             "%BUILDDIR%=$CPAN::Config->{build_dir} ".
1469             "for '$for'\n"
1470             );
1471 0           $ENV{PERL5LIB} = join $Config::Config{path_sep}, @dirs, @env;
1472             } else {
1473 0           my $cnt = keys %{$self->{is_tested}};
  0            
1474 0           my $newenv = join $Config::Config{path_sep}, @dirs, @env;
1475 0           $CPAN::Frontend->optprint('perl5lib', sprintf ("Prepending blib/arch and blib/lib of ".
1476             "%d build dirs to PERL5LIB, reaching size %d; ".
1477             "for '%s'\n", $cnt, length($newenv), $for)
1478             );
1479 0           $ENV{PERL5LIB} = $newenv;
1480             }
1481             }}
1482              
1483              
1484             1;
1485              
1486              
1487             __END__