3 # Get a perl module from somewhere
5 require './cpan-lib.pl';
7 if ($ENV{REQUEST_METHOD} eq "POST") { &ReadParseMime(); }
8 else { &ReadParse(); $no_upload = 1; }
9 &error_setup($text{'download_err'});
11 if ($in{'source'} >= 2) {
12 &ui_print_unbuffered_header(undef, $text{'download_title'}, "");
15 &ui_print_header(undef, $text{'download_title'}, "");
19 if ($in{'source'} == 0) {
20 # installing from local file (or maybe directory)
22 { &install_error($text{'download_elocal'}); }
24 { &install_error(&text('download_elocal2', $in{'local'})); }
25 $source = $in{'local'};
26 @pfile = ( $in{'local'} );
29 elsif ($in{'source'} == 1) {
30 # installing from upload .. store file in temp location
32 &install_error($text{'download_eupload'});
34 $in{'upload_filename'} =~ /([^\/\\]+$)/;
35 @pfile = ( &tempname("$1") );
36 open(PFILE, ">$pfile[0]");
37 print PFILE $in{'upload'};
39 $source = $in{'upload_filename'};
42 elsif ($in{'source'} == 2) {
43 # installing from URL.. store downloaded file in temp location
44 $in{'url'} =~ /\/([^\/]+)\/*$/;
45 @pfile = ( &tempname("$1") );
46 $progress_callback_url = $in{'url'};
47 if ($in{'url'} =~ /^(http|https):\/\/([^\/]+)(\/.*)$/) {
50 $host = $2; $page = $3; $port = $ssl ? 443 : 80;
51 if ($host =~ /^(.*):(\d+)$/) { $host = $1; $port = $2; }
52 &http_download($host, $port, $page, $pfile[0], \$error,
53 \&progress_callback, $ssl);
55 elsif ($in{'url'} =~ /^ftp:\/\/([^\/]+)(:21)?(\/.*)$/) {
56 $host = $1; $file = $3;
57 &ftp_download($host, $file, $pfile[0], \$error,
60 else { &install_error(&text('download_eurl', $in{'url'})); }
61 &install_error($error) if ($error);
65 elsif ($in{'source'} == 3) {
66 # installing from CPAN.. find the module, and then install it
67 $in{'cpan'} || &error($text{'download_emodname'});
68 $in{'cpan'} =~ s/^\s+//;
69 $in{'cpan'} =~ s/\s+$//;
70 @cpan = split(/\s+|\0/, $in{'cpan'});
72 # First check if YUM or APT can install this module for us
73 if ($config{'incyum'} && !$in{'forcecpan'}) {
74 @yum = &list_packaged_modules();
76 ($yum) = grep { lc($_->{'mod'}) eq lc($c) } @yum;
77 push(@cpanyum, $yum) if ($yum);
80 if (scalar(@cpan) == scalar(@cpanyum)) {
81 # Can install from YUM or APT .. do it!
83 foreach $yum (@cpanyum) {
84 print &text('download_yum', "<tt>$cpan[$i]</tt>",
85 "<tt>$yum->{'package'}</tt>"),"<br>\n";
87 &software::update_system_install($yum->{'package'});
91 &ui_print_footer($in{'return'},
92 $in{'returndesc'} || $text{'index_return'});
96 $progress_callback_url = $config{'packages'};
97 if (!-r $packages_file || $in{'refresh'}) {
98 # Need to download the modules list from CPAN first
99 &download_packages_file(\&progress_callback);
102 # Make sure it is valid
103 open(PFILE, $packages_file);
104 read(PFILE, $two, 2);
106 if ($two ne "\037\213") {
107 &install_error(&text('download_ecpangz',
108 "<tt>$config{'packages'}</tt>"));
112 # Find each module in the modules list
113 open(LIST, "gunzip -c $packages_file |");
116 if ($_ eq '') { $found_blank++; }
117 elsif ($found_blank && /^(\S+)\s+(\S+)\s+(.*)/) {
118 local $i = &indexof($1, @cpan);
119 if ($i >= 0 && !$source[$i]) {
120 $source[$i] = "$config{'cpan'}/$3";
121 $source[$i] =~ /\/perl-[0-9\.]+\.tar\.gz$/ &&
122 &install_error(&text('download_eisperl',
123 "<tt>$in{'cpan'}</tt>"));
130 # Fail if any modules are missing from CPAN
131 for($i=0; $i<@cpan; $i++) {
132 push(@missing, "<tt>$cpan[$i]</tt>") if (!$source[$i]);
135 if ($in{'missingok'}) {
136 # If missing modules are OK, exclude them from the sources list
137 for($i=0; $i<@cpan; $i++) {
139 splice(@source, $i, 1);
140 splice(@cpan, $i, 1);
144 @cpan || &install_error(&text('download_ecpan',
145 join(" ", @missing)));
148 # Fail due to missing modules
149 &install_error(&text('download_ecpan', join(" ", @missing)));
151 $source = join("<br>", @source);
153 # Download the actual modules
154 foreach $m (@source) {
155 $m =~ /\/([^\/]+)\/*$/;
156 $pfile = &tempname("$1");
157 $progress_callback_url = $m;
158 if ($m =~ /^http:\/\/([^\/]+)(\/.*)$/) {
159 # Make a HTTP request
160 $host = $1; $page = $2; $port = 80;
161 if ($host =~ /^(.*):(\d+)$/) { $host = $1; $port = $2; }
162 &http_download($host, $port, $page, $pfile, \$error,
163 \&progress_callback);
165 elsif ($m =~ /^ftp:\/\/([^\/]+)(:21)?(\/.*)$/) {
166 $host = $1; $file = $3;
167 &ftp_download($host, $file, $pfile, \$error,
168 \&progress_callback);
170 else { &install_error(&text('download_eurl', $m)); }
171 &install_error($error) if ($error);
172 push(@pfile, $pfile);
177 &error("Unknown source mode $in{'source'}");
180 # Check if the file looks like a perl module
181 foreach $pfile (@pfile) {
182 open(TAR, "( gunzip -c $pfile | tar tf - ) 2>&1 |");
183 while($line = <TAR>) {
184 if ($line =~ /^\.\/([^\/]+)\/(.*)$/ ||
185 $line =~ /^([^\/]+)\/(.*)$/) {
196 unlink(@pfile) if ($need_unlink);
197 &install_error(&text('download_etar', "<tt>$tar</tt>"));
200 if (@dirs == 0 || $file{'Makefile.PL'}+$file{'Build.PL'} < @dirs) {
201 # Not all files were Perl modules
202 unlink(@pfile) if ($need_unlink);
203 &install_error($text{'download_emod'});
205 if ($file{'Build.PL'} && $file{'Makefile.PL'} < @dirs) {
206 # Make sure we have Module::Build if using Build.PL
207 eval "use Module::Build";
209 unlink(@pfile) if ($need_unlink);
210 &install_error(&text('download_ebuild',
211 "<tt>Module::Build</tt>"));
215 if ($d =~ /^(\S+)\-v?([0-9\.ab]+)$/) {
223 $mods[$#mods] =~ s/-/::/g;
226 # Extract all module files to look for depends
227 $mtemp = &tempname();
230 system("cd $mtemp ; gunzip -c $dirs{$d} | tar xf - >/dev/null");
232 if ($d =~ /^Net_SSLeay/) {
233 $testargs = &has_command("openssl");
234 $testargs =~ s/\/bin\/openssl$//;
236 local $cmd = "cd $mtemp/$d ; $perl_path Makefile.PL $testargs --skip";
237 if (&foreign_check("proc")) {
238 # Run in a PTY, to handle CPAN prompting
239 &foreign_require("proc", "proc-lib.pl");
240 local ($fh, $fpid) = &proc::pty_process_exec($cmd);
241 &sysprint($fh, "no\n"); # For CPAN manual config question
243 # Wait till it completes
248 system("$cmd >/dev/null 2>&1 </dev/null");
251 open(MAKEFILE, "$mtemp/$d/Makefile");
253 last if /MakeMaker post_initialize section/;
254 if (/^#\s+PREREQ_PM\s+=>\s+(.+)/) {
256 while($prereq =~ m/(?:\s)([\w\:]+)=>q\[.*?\],?/g) {
262 push(@allreqs, @prereqs);
264 system("rm -rf $mtemp");
266 # Work out which pre-requesites are missing
267 @allreqs = &unique(@allreqs);
268 %needreqs = map { eval "use $_"; $@ ? ($_, 1) : ($_, 0) } @allreqs;
270 # Don't need modules in tar files
271 delete($needreqs{$m});
274 # Don't need modules we are getting from CPAN
275 delete($needreqs{$c});
278 # Display install options
280 print &ui_form_start("install.cgi");
281 print &ui_hidden("source", $in{'source'});
282 print &ui_hidden("need_unlink", $need_unlink);
283 foreach $pfile (@pfile) {
284 print &ui_hidden("pfile", $pfile);
287 print &ui_hidden("mod", $m);
290 print &ui_hidden("ver", $v);
293 print &ui_hidden("dir", $d);
295 print &ui_hidden("return", $in{'return'});
296 print &ui_hidden("returndesc", $in{'returndesc'});
297 print &ui_table_start($text{'download_header'}, undef, 2);
299 # Modules being installed
300 for($i=0; $i<@mods; $i++) {
301 $modmsg .= &html_escape($mods[$i])." ".&html_escape($vers[$i])."<br>\n";
303 print &ui_table_row(@mods > 1 ? $text{'download_mods'} : $text{'download_mod'},
308 print &ui_table_row($text{'download_missingok'},
309 join(" ", @missing));
313 print &ui_table_row($text{'download_src'}, $source);
317 @needreqs = grep { $needreqs{$_} } @allreqs;
318 foreach $n (@needreqs) {
319 print &ui_hidden("needreq", $n);
322 $nmsg = " (".&text('download_missing', scalar(@needreqs)).")";
325 $nmsg = " ($text{'download_nomissing'})";
327 print &ui_table_row($text{'download_pres'},
328 join(" ", map { $needreqs{$_} ? "<i>$_</i>" : "<tt>$_</tt>" }
333 $in{'mode'} = 3 if ($in{'mode'} eq '');
334 print &ui_table_row($text{'download_act'},
335 &ui_select("act", $in{'mode'},
336 [ [ 0, $text{'download_m'} ],
337 [ 1, $text{'download_mt'} ],
338 [ 2, $text{'download_mi'} ],
339 [ 3, $text{'download_mti'} ] ]));
341 # Command-line args to Makefile.PL
342 print &ui_table_row($text{'download_args'},
343 &ui_textbox("args", $config{'def_args'}, 40));
345 # Table of environment variables
346 $etable = &ui_columns_start([ $text{'download_name'},
347 $text{'download_value'} ]);
348 for($i=0; $i<4; $i++) {
349 $etable .= &ui_columns_row([ &ui_textbox("name_$i", undef, 15),
350 &ui_textbox("value_$i", undef, 30) ]);
352 $etable .= &ui_columns_end();
353 print &ui_table_row($text{'download_envs'}, $etable);
355 print &ui_table_end();
356 print &ui_form_end([ [ undef, $text{'download_cont'} ],
357 @needreqs && $in{'source'} == 3 ?
358 ( [ "need", $text{'download_need'} ] ) : ( )
361 &ui_print_footer($in{'return'},
362 $in{'returndesc'} || $text{'index_return'});
366 print "<br><b>$main::whatfailed : $_[0]</b> <p>\n";
367 &ui_print_footer($in{'return'},
368 $in{'returndesc'} || $text{'index_return'});