File Coverage

blib/lib/CPAN.pm
Criterion Covered Total %
statement 247 804 30.7
branch 51 388 13.1
condition 23 165 13.9
subroutine 63 106 59.4
pod 13 27 48.1
total 397 1490 26.6


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