1 # -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
2 package CPAN::Mirrored::By;
5 $VERSION = sprintf "%.2f", substr(q$Rev: 399 $,4)/100;
11 sub continent { shift->[0] }
12 sub country { shift->[1] }
13 sub url { shift->[2] }
15 package CPAN::FirstTime;
18 use ExtUtils::MakeMaker ();
20 use File::Basename ();
23 use vars qw($VERSION);
24 $VERSION = sprintf "%.2f", substr(q$Rev: 399 $,4)/100;
28 CPAN::FirstTime - Utility for CPAN::Config file Initialization
32 CPAN::FirstTime::init()
36 The init routine asks a few questions and writes a CPAN::Config
37 file. Nothing special.
41 use vars qw( %prompts );
44 my($configpm, %args) = @_;
46 # extra arg in 'o conf init make' selects only $item =~ /make/
47 my $matcher = $args{args} && @{$args{args}} ? $args{args}[0] : '';
49 unless ($CPAN::VERSION) {
52 eval {require CPAN::Config;};
65 # if (!@sections or grep /^(files|dirs)$/, @sections) {
67 print $prompts{manual_config};
71 local *_real_prompt = \&ExtUtils::MakeMaker::prompt;
72 if ( $args{autoconfig} ) {
75 $manual_conf = prompt("Are you ready for manual configuration?", "yes");
79 if ($manual_conf =~ /^y/i) {
83 $CPAN::Config->{urllist} ||= [];
86 # prototype should match that of &MakeMaker::prompt
87 *_real_prompt = sub ($;$) {
89 my($ret) = defined $a ? $a : "";
90 $CPAN::Frontend->myprint(sprintf qq{%s [%s]\n\n}, $q, $ret);
91 eval { require Time::HiRes };
93 Time::HiRes::sleep(0.1);
99 # if ('config_intro' ~= $matcher) {
101 $CPAN::Frontend->myprint($prompts{config_intro});
106 my $cpan_home = $CPAN::Config->{cpan_home}
107 || File::Spec->catdir($ENV{HOME}, ".cpan");
110 $CPAN::Frontend->myprint(qq{
112 I see you already have a directory
114 Shall we use it as the general CPAN build and cache directory?
119 $CPAN::Frontend->myprint($prompts{cpan_home_where});
122 $default = $cpan_home;
123 while ($ans = prompt("CPAN build and cache directory?",$default)) {
124 unless (File::Spec->file_name_is_absolute($ans)) {
126 my $cwd = Cwd::cwd();
127 my $absans = File::Spec->catdir($cwd,$ans);
128 warn "The path '$ans' is not an absolute path. Please specify an absolute path\n";
132 eval { File::Path::mkpath($ans); }; # dies if it can't
134 warn "Couldn't create directory $ans.\nPlease retry.\n";
137 if (-d $ans && -w _) {
140 warn "Couldn't find directory $ans\n"
141 . "or directory is not writable. Please retry.\n";
144 $CPAN::Config->{cpan_home} = $ans;
146 $CPAN::Frontend->myprint($prompts{keep_source_where});
148 $CPAN::Config->{keep_source_where}
149 = File::Spec->catdir($CPAN::Config->{cpan_home},"sources");
151 $CPAN::Config->{build_dir}
152 = File::Spec->catdir($CPAN::Config->{cpan_home},"build");
155 # Cache size, Index expire
158 $CPAN::Frontend->myprint($prompts{build_cache_intro});
160 # large enough to build large dists like Tk
161 my_dflt_prompt(build_cache => 100, $matcher);
163 # XXX This the time when we refetch the index files (in days)
164 $CPAN::Config->{'index_expire'} = 1;
166 $CPAN::Frontend->myprint($prompts{scan_cache_intro});
167 my_prompt_loop(scan_cache => 'atstart', $matcher, 'atstart|never');
173 $CPAN::Frontend->myprint($prompts{cache_metadata});
175 defined($default = $CPAN::Config->{cache_metadata}) or $default = 1;
177 $ans = prompt("Cache metadata (yes/no)?", ($default ? 'yes' : 'no'));
178 } while ($ans !~ /^[yn]/i);
179 $CPAN::Config->{cache_metadata} = ($ans =~ /^y/i ? 1 : 0);
185 $CPAN::Frontend->myprint($prompts{term_is_latin});
187 defined($default = $CPAN::Config->{term_is_latin}) or $default = 1;
189 $ans = prompt("Your terminal expects ISO-8859-1 (yes/no)?",
190 ($default ? 'yes' : 'no'));
191 } while ($ans !~ /^[yn]/i);
192 $CPAN::Config->{term_is_latin} = ($ans =~ /^y/i ? 1 : 0);
195 # save history in file histfile
198 $CPAN::Frontend->myprint($prompts{histfile});
200 defined($default = $CPAN::Config->{histfile}) or
201 $default = File::Spec->catfile($CPAN::Config->{cpan_home},"histfile");
202 $ans = prompt("File to save your history?", $default);
203 $CPAN::Config->{histfile} = $ans;
205 if ($CPAN::Config->{histfile}) {
206 defined($default = $CPAN::Config->{histsize}) or $default = 100;
207 $ans = prompt("Number of lines to save?", $default);
208 $CPAN::Config->{histsize} = $ans;
212 # do an ls on the m or the d command
214 $CPAN::Frontend->myprint($prompts{show_upload_date_intro});
216 defined($default = $CPAN::Config->{show_upload_date}) or
218 $ans = prompt("Always try to show upload date with 'd' and 'm' command (yes/no)?",
219 ($default ? 'yes' : 'no'));
220 $CPAN::Config->{show_upload_date} = ($ans =~ /^[y1]/i ? 1 : 0);
222 #my_prompt_loop(show_upload_date => 'n', $matcher,
223 #'follow|ask|ignore');
226 # prerequisites_policy
227 # Do we follow PREREQ_PM?
230 $CPAN::Frontend->myprint($prompts{prerequisites_policy_intro});
232 my_prompt_loop(prerequisites_policy => 'ask', $matcher,
233 'follow|ask|ignore');
240 $CPAN::Frontend->myprint($prompts{external_progs});
243 local $^W if $^O eq 'MacOS';
244 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
245 local $^W = $old_warn;
247 for $progname (qw/bzip2 gzip tar unzip make
248 curl lynx wget ncftpget ncftp ftp
251 if ($^O eq 'MacOS') {
252 $CPAN::Config->{$progname} = 'not_here';
255 next if $matcher && $progname !~ /$matcher/;
257 my $progcall = $progname;
258 # we don't need ncftp if we have ncftpget
259 next if $progname eq "ncftp" && $CPAN::Config->{ncftpget} gt " ";
260 my $path = $CPAN::Config->{$progname}
261 || $Config::Config{$progname}
263 if (File::Spec->file_name_is_absolute($path)) {
264 # testing existence is not good enough, some have these exe
267 # warn "Warning: configured $path does not exist\n" unless -e $path;
274 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
277 $path ||= find_exe($progcall,[@path]);
278 $CPAN::Frontend->mywarn("Warning: $progcall not found in PATH\n") unless
279 $path; # not -e $path, because find_exe already checked that
280 $ans = prompt("Where is your $progname program?",$path) || $path;
281 $CPAN::Config->{$progname} = $ans;
283 my $path = $CPAN::Config->{'pager'} ||
284 $ENV{PAGER} || find_exe("less",[@path]) ||
285 find_exe("more",[@path]) || ($^O eq 'MacOS' ? $ENV{EDITOR} : 0 )
287 $ans = prompt("What is your favorite pager program?",$path);
288 $CPAN::Config->{'pager'} = $ans;
289 $path = $CPAN::Config->{'shell'};
290 if (File::Spec->file_name_is_absolute($path)) {
291 warn "Warning: configured $path does not exist\n" unless -e $path;
294 $path ||= $ENV{SHELL};
295 if (!$path && $^O eq 'MSWin32') {
296 $path = Win32::IsWinNT() ? "cmd.exe" : "command.com";
298 if ($^O eq 'MacOS') {
299 $CPAN::Config->{'shell'} = 'not_here';
301 $path =~ s,\\,/,g if $^O eq 'os2'; # Cosmetic only
302 $ans = prompt("What is your favorite shell?",$path);
303 $CPAN::Config->{'shell'} = $ans;
307 # Arguments to make etc.
310 $CPAN::Frontend->myprint($prompts{prefer_installer_intro});
312 my_prompt_loop(prefer_installer => 'EUMM', $matcher, 'MB|EUMM');
315 $CPAN::Frontend->myprint($prompts{makepl_arg_intro});
317 my_dflt_prompt(makepl_arg => "", $matcher);
319 my_dflt_prompt(make_arg => "", $matcher);
321 my_dflt_prompt(make_install_make_command => $CPAN::Config->{make} || "",
324 my_dflt_prompt(make_install_arg => $CPAN::Config->{make_arg} || "",
327 $CPAN::Frontend->myprint($prompts{mbuildpl_arg_intro});
329 my_dflt_prompt(mbuildpl_arg => "", $matcher);
331 my_dflt_prompt(mbuild_arg => "", $matcher);
333 my_dflt_prompt(mbuild_install_build_command => "./Build", $matcher);
335 my_dflt_prompt(mbuild_install_arg => "", $matcher);
341 $CPAN::Frontend->myprint($prompts{inactivity_timeout_intro});
343 # my_dflt_prompt(inactivity_timeout => 0);
345 $default = $CPAN::Config->{inactivity_timeout} || 0;
346 $CPAN::Config->{inactivity_timeout} =
347 prompt("Timeout for inactivity during {Makefile,Build}.PL?",$default);
351 $CPAN::Frontend->myprint($prompts{proxies});
353 for (qw/ftp_proxy http_proxy no_proxy/) {
354 $default = $CPAN::Config->{$_} || $ENV{$_};
355 $CPAN::Config->{$_} = prompt("Your $_?",$default);
358 if ($CPAN::Config->{ftp_proxy} ||
359 $CPAN::Config->{http_proxy}) {
361 $default = $CPAN::Config->{proxy_user} || $CPAN::LWP::UserAgent::USER;
363 $CPAN::Frontend->myprint($prompts{proxy_user});
365 if ($CPAN::Config->{proxy_user} = prompt("Your proxy user id?",$default)) {
366 $CPAN::Frontend->myprint($prompts{proxy_pass});
368 if ($CPAN::META->has_inst("Term::ReadKey")) {
369 Term::ReadKey::ReadMode("noecho");
371 $CPAN::Frontend->myprint($prompts{password_warn});
373 $CPAN::Config->{proxy_pass} = prompt_no_strip("Your proxy password?");
374 if ($CPAN::META->has_inst("Term::ReadKey")) {
375 Term::ReadKey::ReadMode("restore");
377 $CPAN::Frontend->myprint("\n\n");
385 conf_sites() unless $fastread;
387 # We don't ask that now, it will be noticed in time, won't it?
388 $CPAN::Config->{'inhibit_startup_message'} = 0;
389 $CPAN::Config->{'getcwd'} = 'cwd';
391 $CPAN::Frontend->myprint("\n\n");
392 CPAN::HandleConfig->commit($configpm);
396 my ($item, $dflt, $m) = @_;
397 my $default = $CPAN::Config->{$item} || $dflt;
400 if (!$m || $item =~ /$m/) {
401 $CPAN::Config->{$item} = prompt($prompts{$item}, $default);
403 $CPAN::Config->{$item} = $default;
408 my ($item, $dflt, $m, $ok) = @_;
409 my $default = $CPAN::Config->{$item} || $dflt;
413 if (!$m || $item =~ /$m/) {
414 do { $ans = prompt($prompts{$item}, $default);
415 } until $ans =~ /$ok/;
416 $CPAN::Config->{$item} = $ans;
418 $CPAN::Config->{$item} = $default;
424 my $m = 'MIRRORED.BY';
425 my $mby = File::Spec->catfile($CPAN::Config->{keep_source_where},$m);
426 File::Path::mkpath(File::Basename::dirname($mby));
427 if (-f $mby && -f $m && -M $m < -M $mby) {
429 File::Copy::copy($m,$mby) or die "Could not update $mby: $!";
433 my $overwrite_local = 0;
434 if ($mby && -f $mby && -M _ <= 60 && -s _ > 0) {
435 my $mtime = localtime((stat _)[9]);
436 my $prompt = qq{Found $mby as of $mtime
438 I\'d use that as a database of CPAN sites. If that is OK for you,
439 please answer 'y', but if you want me to get a new database now,
440 please answer 'n' to the following question.
442 Shall I use the local database in $mby?};
443 my $ans = prompt($prompt,"y");
444 $overwrite_local = 1 unless $ans =~ /^y/i;
447 if ($overwrite_local) {
448 print qq{Trying to overwrite $mby\n};
449 $mby = CPAN::FTP->localize($m,$mby,3);
450 $overwrite_local = 0;
451 } elsif ( ! -f $mby ){
452 print qq{You have no $mby\n I\'m trying to fetch one\n};
453 $mby = CPAN::FTP->localize($m,$mby,3);
454 } elsif (-M $mby > 60 && $loopcount == 0) {
455 print qq{Your $mby is older than 60 days,\n I\'m trying to fetch one\n};
456 $mby = CPAN::FTP->localize($m,$mby,3);
458 } elsif (-s $mby == 0) {
459 print qq{You have an empty $mby,\n I\'m trying to fetch one\n};
460 $mby = CPAN::FTP->localize($m,$mby,3);
465 read_mirrored_by($mby);
472 #warn "in find_exe exe[$exe] path[@$path]";
474 my $abs = File::Spec->catfile($dir,$exe);
475 if (($abs = MM->maybe_command($abs))) {
482 my($items,$prompt,$default,$require_nonempty,$empty_warning)=@_;
490 # display, at most, 15 items at a time
491 my $limit = $#{ $items } - $pos;
492 $limit = 15 if $limit > 15;
494 # show the next $limit items, get the new position
495 $pos = display_some($items, $limit, $pos);
496 $pos = 0 if $pos >= @$items;
498 my $num = prompt($prompt,$default);
500 @nums = split (' ', $num);
501 my $i = scalar @$items;
502 (warn "invalid items entered, try again\n"), next
503 if grep (/\D/ || $_ < 1 || $_ > $i, @nums);
504 if ($require_nonempty) {
505 (warn "$empty_warning\n");
509 # a blank line continues...
518 my ($items, $limit, $pos) = @_;
521 my @displayable = @$items[$pos .. ($pos + $limit)];
522 for my $item (@displayable) {
523 printf "(%d) %s\n", ++$pos, $item;
525 printf("%d more items, hit SPACE RETURN to show them\n",
532 sub read_mirrored_by {
533 my $local = shift or return;
534 my(%all,$url,$expected_size,$default,$ans,$host,
535 $dst,$country,$continent,@location);
536 my $fh = FileHandle->new;
537 $fh->open($local) or die "Couldn't open $local: $!";
540 ($host) = /^([\w\.\-]+)/ unless defined $host;
541 next unless defined $host;
542 next unless /\s+dst_(dst|location)/;
543 /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
544 ($continent, $country) = @location[-1,-2];
545 $continent =~ s/\s\(.*//;
546 $continent =~ s/\W+$//; # if Jarkko doesn't know latitude/longitude
547 /dst_dst\s+=\s+\"([^\"]+)/ and $dst = $1;
548 next unless $host && $dst && $continent && $country;
549 $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
551 $dst=$continent=$country="";
554 $CPAN::Config->{urllist} ||= [];
556 if (@previous_urls = @{$CPAN::Config->{urllist}}) {
557 $CPAN::Config->{urllist} = [];
560 print $prompts{urls_intro};
562 my (@cont, $cont, %cont, @countries, @urls, %seen);
563 my $no_previous_warn =
564 "Sorry! since you don't have any existing picks, you must make a\n" .
565 "geographic selection.";
566 @cont = picklist([sort keys %all],
567 "Select your continent (or several nearby continents)",
573 foreach $cont (@cont) {
574 my @c = sort keys %{$all{$cont}};
575 @cont{@c} = map ($cont, 0..$#c);
576 @c = map ("$_ ($cont)", @c) if @cont > 1;
577 push (@countries, @c);
581 @countries = picklist (\@countries,
582 "Select your country (or several nearby countries)",
586 %seen = map (($_ => 1), @previous_urls);
587 # hmmm, should take list of defaults from CPAN::Config->{'urllist'}...
588 foreach $country (@countries) {
589 (my $bare_country = $country) =~ s/ \(.*\)//;
590 my @u = sort keys %{$all{$cont{$bare_country}}{$bare_country}};
591 @u = grep (! $seen{$_}, @u);
592 @u = map ("$_ ($bare_country)", @u)
597 push (@urls, map ("$_ (previous pick)", @previous_urls));
598 my $prompt = "Select as many URLs as you like (by number),
599 put them on one line, separated by blanks, e.g. '1 4 5'";
600 if (@previous_urls) {
601 $default = join (' ', ((scalar @urls) - (scalar @previous_urls) + 1) ..
603 $prompt .= "\n(or just hit RETURN to keep your previous picks)";
606 @urls = picklist (\@urls, $prompt, $default);
607 foreach (@urls) { s/ \(.*\)//; }
608 push @{$CPAN::Config->{urllist}}, @urls;
612 my %seen = map (($_ => 1), @{$CPAN::Config->{urllist}});
615 my $prompt = "Enter another URL or RETURN to quit:";
617 $prompt = qq{CPAN.pm needs at least one URL where it can fetch CPAN files from.
619 Please enter your CPAN site:};
621 $ans = prompt ($prompt, "");
624 $ans =~ s|/?\z|/|; # has to end with one slash
625 $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
626 if ($ans =~ /^\w+:\/./) {
627 push @urls, $ans unless $seen{$ans}++;
629 printf(qq{"%s" doesn\'t look like an URL at first sight.
630 I\'ll ignore it for now.
631 You can add it to your %s
632 later if you\'re sure it\'s right.\n},
634 $INC{'CPAN/MyConfig.pm'} || $INC{'CPAN/Config.pm'} || "configuration file",
638 } while $ans || !%seen;
640 push @{$CPAN::Config->{urllist}}, @urls;
641 # xxx delete or comment these out when you're happy that it works
642 print "New set of picks:\n";
643 map { print " $_\n" } @{$CPAN::Config->{urllist}};
648 $_[0] =~ s/^\s+//; # no leading spaces
649 $_[0] =~ s/\s+\z//; # no trailing spaces
654 my $ans = _real_prompt(@_);
662 sub prompt_no_strip ($;$) {
663 return _real_prompt(@_);
673 CPAN is the world-wide archive of perl resources. It consists of about
674 100 sites that all replicate the same contents all around the globe.
675 Many countries have at least one CPAN site already. The resources
676 found on CPAN are easily accessible with the CPAN.pm module. If you
677 want to use CPAN.pm, you have to configure it properly.
679 If you do not want to enter a dialog now, you can answer 'no' to this
680 question and I\'ll try to autoconfigure. (Note: you can revisit this
681 dialog anytime later by typing 'o conf init' at the cpan prompt.)
687 The following questions are intended to help you with the
688 configuration. The CPAN module needs a directory of its own to cache
689 important index files and maybe keep a temporary mirror of CPAN files.
690 This may be a site-wide directory or a personal directory.
694 # cpan_home => qq{ },
696 cpan_home_where => qq{
698 First of all, I\'d like to create this directory. Where?
702 keep_source_where => qq{
704 If you like, I can cache the source files after I build them. Doing
705 so means that, if you ever rebuild that module in the future, the
706 files will be taken from the cache. The tradeoff is that it takes up
707 space. How much space would you like to allocate to this cache? (If
708 you don\'t want me to keep a cache, answer 0.)
712 build_cache_intro => qq{
714 How big should the disk cache be for keeping the build directories
715 with all the intermediate files\?
720 "Cache size for build directory (in MB)?",
723 scan_cache_intro => qq{
725 By default, each time the CPAN module is started, cache scanning is
726 performed to keep the cache size in sync. To prevent this, answer
731 scan_cache => "Perform cache scanning (atstart or never)?",
733 cache_metadata => qq{
735 To considerably speed up the initial CPAN shell startup, it is
736 possible to use Storable to create a cache of metadata. If Storable
737 is not available, the normal index mechanism will be used.
743 The next option deals with the charset (aka character set) your
744 terminal supports. In general, CPAN is English speaking territory, so
745 the charset does not matter much, but some of the aliens out there who
746 upload their software to CPAN bear names that are outside the ASCII
747 range. If your terminal supports UTF-8, you should say no to the next
748 question. If it supports ISO-8859-1 (also known as LATIN1) then you
749 should say yes. If it supports neither, your answer does not matter
750 because you will not be able to read the names of some authors
751 anyway. If you answer no, names will be output in UTF-8.
757 If you have one of the readline packages (Term::ReadLine::Perl,
758 Term::ReadLine::Gnu, possibly others) installed, the interactive CPAN
759 shell will have history support. The next two questions deal with the
760 filename of the history file and with its size. If you do not want to
761 set this variable, please hit SPACE RETURN to the following question.
765 show_upload_date_intro => qq{
767 The 'd' and the 'm' command normally only show you information they
768 have in their in-memory database and thus will never connect to the
769 internet. If you set the 'show_upload_date' variable to true, 'm' and
770 'd' will additionally show you the upload date of the module or
771 distribution. Per default this feature is off because it may require a
772 net connection to get at the upload date.
777 "Always try to show upload date with 'd' and 'm' command (yes/no)?",
779 prerequisites_policy_intro => qq{
781 The CPAN module can detect when a module which you are trying to build
782 depends on prerequisites. If this happens, it can build the
783 prerequisites for you automatically ('follow'), ask you for
784 confirmation ('ask'), or just ignore them ('ignore'). Please set your
785 policy to one of the three values.
789 prerequisites_policy =>
790 qq{Policy on building prerequisites (follow, ask or ignore)?},
792 external_progs => qq{
794 The CPAN module will need a few external programs to work properly.
795 Please correct me, if I guess the wrong path for a program. Don\'t
796 panic if you do not have some of them, just press ENTER for those. To
797 disable the use of a download program, you can type a space followed
802 prefer_installer_intro => qq{
804 When you have Module::Build installed and a module comes with both a
805 Makefile.PL and a Build.PL, which shall have precedence? The two
806 installer modules we have are the old and well established
807 ExtUtils::MakeMaker (for short: EUMM) understands the Makefile.PL and
808 the next generation installer Module::Build (MB) works with the
814 qq{In case you could choose, which installer would you prefer (EUMM or MB)?},
816 makepl_arg_intro => qq{
818 Every Makefile.PL is run by perl in a separate process. Likewise we
819 run \'make\' and \'make install\' in separate processes. If you have
820 any parameters \(e.g. PREFIX, LIB, UNINST or the like\) you want to
821 pass to the calls, please specify them here.
823 If you don\'t understand this question, just press ENTER.
827 Parameters for the 'perl Makefile.PL' command?
828 Typical frequently used settings:
830 PREFIX=~/perl # non-root users (please see manual for more hints)
834 make_arg => qq{Parameters for the 'make' command?
835 Typical frequently used setting:
837 -j3 # dual processor system
842 make_install_make_command => qq{Do you want to use a different make command for 'make install'?
843 Cautious people will probably prefer:
849 /path1/to/sudo -u admin_account /path2/to/make
851 or some such. Your choice: },
854 make_install_arg => qq{Parameters for the 'make install' command?
855 Typical frequently used setting:
857 UNINST=1 # to always uninstall potentially conflicting files
862 mbuildpl_arg_intro => qq{
864 The next questions deal with Module::Build support.
866 A Build.PL is run by perl in a separate process. Likewise we run
867 './Build' and './Build install' in separate processes. If you have any
868 parameters you want to pass to the calls, please specify them here.
872 mbuildpl_arg => qq{Parameters for the 'perl Build.PL' command?
873 Typical frequently used settings:
875 --install_base /home/xxx # different installation directory
879 mbuild_arg => qq{Parameters for the './Build' command?
882 --extra_linker_flags -L/usr/foo/lib # non-standard library location
887 mbuild_install_build_command => qq{Do you want to use a different command for './Build install'?
888 Sudo users will probably prefer:
894 /path1/to/sudo -u admin_account ./Build
896 or some such. Your choice: },
899 mbuild_install_arg => qq{Parameters for the './Build install' command?
900 Typical frequently used setting:
902 --uninst 1 # uninstall conflicting files
908 inactivity_timeout_intro => qq{
910 Sometimes you may wish to leave the processes run by CPAN alone
911 without caring about them. Because the Makefile.PL sometimes contains
912 question you\'re expected to answer, you can set a timer that will
913 kill a 'perl Makefile.PL' process after the specified time in seconds.
915 If you set this value to 0, these processes will wait forever. This is
916 the default and recommended setting.
920 inactivity_timeout =>
921 qq{Timeout for inactivity during {Makefile,Build}.PL? },
926 If you\'re accessing the net via proxies, you can specify them in the
927 CPAN configuration or via environment variables. The variable in
928 the \$CPAN::Config takes precedence.
934 If your proxy is an authenticating proxy, you can store your username
935 permanently. If you do not want that, just press RETURN. You will then
936 be asked for your username in every future session.
942 Your password for the authenticating proxy can also be stored
943 permanently on disk. If this violates your security policy, just press
944 RETURN. You will then be asked for the password in every future
951 Now we need to know where your favorite CPAN sites are located. Push
952 a few sites onto the array (just in case the first on the array won\'t
953 work). If you are mirroring CPAN to your local workstation, specify a
956 First, pick a nearby continent and country (you can pick several of
957 each, separated by spaces, or none if you just want to keep your
958 existing selections). Then, you will be presented with a list of URLs
959 of CPAN mirrors in the countries you selected, along with previously
960 selected URLs. Select some of those URLs, or just keep the old list.
961 Finally, you will be prompted for any extra URLs -- file:, ftp:, or
962 http: -- that host a CPAN mirror.
968 Warning: Term::ReadKey seems not to be available, your password will
969 be echoed to the terminal!
975 die "Coding error in \@prompts declaration. Odd number of elements, above"
980 if (scalar(keys %prompts) != scalar(@prompts)/2) {
984 for my $item (0..$#prompts) {
986 die "$prompts[$item] is duplicated\n"
987 if $already{$prompts[$item]}++;