Added Module Config option to not install modules from APT or YUM.
---- Changes since 1.360 ----
The module is now available when running Webmin inside a Solaris zone, but only if Perl is not shared with the global zone.
+---- Changes since 1.390 ----
+Converted all code to use the new Webmin UI library, for a more consistent look.
}
close(LIST);
-# Display the current level of modules
-$bgcolor = defined($gconfig{'cs_page'}) ? $gconfig{'cs_page'} : "ffffff";
-$link = defined($gconfig{'cs_link'}) ? $gconfig{'cs_link'} : "0000ee";
-$text = defined($gconfig{'cs_text'}) ? $gconfig{'cs_text'} : "000000";
+# Show page header and selection javascript
@sel = split(/\0/, $in{'sel'});
-&PrintHeader();
+&popup_header($text{'cpan_title'});
+
print <<EOF;
-<html>
-<head><title>$text{'cpan_title'}</title>
<script>
function sel(m)
{
</script>
</head><body bgcolor=#$bgcolor link=#$link vlink=#$link text=#$text>
EOF
+
if ($in{'search'}) {
# Search for modules matching some name
print "<b>",&text('cpan_match', "<tt>$in{'search'}</tt>"),"</b><p>\n";
- print "<table width=100% cellpadding=1 cellspacing=1>\n";
+ print &ui_columns_start(undef, 100, 1);
foreach $m (@mods) {
if (!$m->{'cat'} && $m->{'full'} =~ /$in{'search'}/i) {
$name = join("::",@{$m->{'name'}});
- print "<tr>\n";
- print "<td><a href='' onClick='sel(\"$name\")'><img src=images/mod.gif border=0></a></td>\n";
- print "<td><a href='' onClick='sel(\"$name\")'>",
- &html_escape($name),"</a></td>\n";
- print "<td align=right>",&html_escape($m->{'ver'}),"</td>\n";
- print "</tr>\n";
+ print &ui_columns_row([
+ "<a href='' onClick='sel(\"$name\")'>".
+ "<img src=images/mod.gif border=0></a>",
+ "<a href='' onClick='sel(\"$name\")'>".
+ &html_escape($name)."</a>",
+ &html_escape($m->{'ver'}),
+ ]);
$matches++;
}
}
- print "</table>\n";
+ print &ui_columns_end();
print "$text{'cpan_none'}<br>\n" if (!$matches);
}
else {
}
else {
# Show search form
- print "<form action=cpan.cgi>\n";
- print "<input type=submit value='$text{'cpan_search'}'>\n";
- print "<input name=search size=15></form>\n";
+ print &ui_form_start("cpan.cgi");
+ print &ui_submit($text{'cpan_search'});
+ print &ui_textbox("search", undef, 20),&ui_form_end();
}
- print "<table width=100% cellpadding=1 cellspacing=1>\n";
+ print &ui_columns_start(undef, 100, 1);
if (@sel) {
+ # Link to up one level
local @up = @sel[0..$#sel-1];
- print "<tr>\n";
- print "<td><a href='cpan.cgi?",join("&",map { "sel=$_" } @up),"#",join("::",@sel),"'><img src=images/cat.gif border=0></a></td>\n";
- print "<td><a href='cpan.cgi?",join("&",map { "sel=$_" } @up),"#",join("::",@sel),"'>..</a></td>\n";
- print "</tr>\n";
+ print &ui_columns_row([
+ "<a href='cpan.cgi?".
+ join("&",map { "sel=$_" } @up),"#",join("::",@sel).
+ "'><img src=images/cat.gif border=0></a>",
+ "<a href='cpan.cgi?".
+ join("&",map { "sel=$_" } @up)."#".
+ join("::",@sel)."'>..</a>",
+ ""
+ ]);
}
MOD: foreach $m (@mods) {
for($i=0; $i<@sel; $i++) {
$pars = join("&",map { "sel=$_" } @{$m->{'name'}});
print "<tr>\n";
if ($m->{'cat'}) {
- print "<td><a name=$name><a href='cpan.cgi?$pars'><img src=images/cat.gif border=0></a></td>\n";
- print "<td><a href='cpan.cgi?$pars'>",&html_escape($name),"</a></td>\n";
+ # A category which can be opened
+ print &ui_columns_row([
+ "<a name=$name><a href='cpan.cgi?$pars'>".
+ "<img src=images/cat.gif border=0></a>",
+ "<a href='cpan.cgi?$pars'>".
+ &html_escape($name)."</a>",
+ ""
+ ]);
}
else {
- print "<td><a href='' onClick='sel(\"$name\")'><img src=images/mod.gif border=0></a></td>\n";
- print "<td><a href='' onClick='sel(\"$name\")'>",&html_escape($name),"</a></td>\n";
- print "<td align=right>",&html_escape($m->{'ver'}),"</td>\n";
+ # A module
+ print &ui_columns_row([
+ "<a href='' onClick='sel(\"$name\")'>".
+ "<img src=images/mod.gif border=0></a>",
+ "<a href='' onClick='sel(\"$name\")'>".
+ &html_escape($name)."</a>",
+ &html_escape($m->{'ver'}),
+ ], [ undef, undef, "align=right" ]);
}
- print "</tr>\n";
}
+ print &ui_columns_end();
}
-print "</table>\n";
-print "</body></html>\n";
+&popup_footer();
}
# Display install options
-print "<p><form action=install.cgi>\n";
-print "<input type=hidden name=source value='$in{'source'}'>\n";
-print "<input type=hidden name=need_unlink value='$need_unlink'>\n";
+print "<p>\n";
+print &ui_form_start("install.cgi");
+print &ui_hidden("source", $in{'source'});
+print &ui_hidden("need_unlink", $need_unlink);
foreach $pfile (@pfile) {
- print "<input type=hidden name=pfile value='$pfile'>\n";
+ print &ui_hidden("pfile", $pfile);
}
foreach $m (@mods) {
- print "<input type=hidden name=mod value='$m'>\n";
+ print &ui_hidden("mod", $m);
}
foreach $v (@vers) {
- print "<input type=hidden name=ver value='$v'>\n";
+ print &ui_hidden("ver", $v);
}
foreach $d (@dirs) {
- print "<input type=hidden name=dir value='$d'>\n";
+ print &ui_hidden("dir", $d);
}
-print "<input type=hidden name=return value='$in{'return'}'>\n";
-print "<input type=hidden name=returndesc value='$in{'returndesc'}'>\n";
-print "<table border>\n";
-print "<tr $tb> <td><b>$text{'download_header'}</b></td> </tr>\n";
-print "<tr $cb> <td><table>\n";
+print &ui_hidden("return", $in{'return'});
+print &ui_hidden("returndesc", $in{'returndesc'});
+print &ui_table_start($text{'download_header'}, undef, 2);
-print "<tr> <td valign=top><b>",
- @mods > 1 ? $text{'download_mods'} : $text{'download_mod'},
- "</b></td> <td>";
+# Modules being installed
for($i=0; $i<@mods; $i++) {
- print &html_escape($mods[$i])," ",&html_escape($vers[$i]),"<br>\n";
+ $modmsg .= &html_escape($mods[$i])." ".&html_escape($vers[$i])."<br>\n";
}
-print "</td> </tr>\n";
-print "<tr> <td valign=top><b>$text{'download_src'}</b></td> <td>",
- $source,"</td> </tr>\n";
+print &ui_table_row(@mods > 1 ? $text{'download_mods'} : $text{'download_mod'},
+ $modmsg);
+
+# Source
+print &ui_table_row($text{'download_src'}, $source);
if (@allreqs) {
- print "<tr> <td valign=top><b>$text{'download_pres'}</b></td> <td>",
- join(" ", map { $needreqs{$_} ? "<i>$_</i>" : "<tt>$_</tt>" } @allreqs);
+ # Pre-requisited
@needreqs = grep { $needreqs{$_} } @allreqs;
foreach $n (@needreqs) {
- print "<input type=hidden name=needreq value='$n'>\n";
+ print &ui_hidden("needreq", $n);
}
if (@needreqs) {
- print " (".&text('download_missing', scalar(@needreqs)).")";
+ $nmsg = " (".&text('download_missing', scalar(@needreqs)).")";
}
else {
- print " ($text{'download_nomissing'})";
+ $nmsg = " ($text{'download_nomissing'})";
}
- print "</td> </tr>\n";
+ print &ui_table_row($text{'download_pres'},
+ join(" ", map { $needreqs{$_} ? "<i>$_</i>" : "<tt>$_</tt>" }
+ @allreqs).$nmsg);
}
-print "<tr> <td><b>$text{'download_act'}</b></td> <td><select name=act>\n";
+# Install mode
$in{'mode'} = 3 if ($in{'mode'} eq '');
-printf "<option value=0 %s> $text{'download_m'}\n",
- $in{'mode'} == 0 ? "selected" : "";
-printf "<option value=1 %s> $text{'download_mt'}\n",
- $in{'mode'} == 1 ? "selected" : "";
-printf "<option value=2 %s> $text{'download_mi'}\n",
- $in{'mode'} == 2 ? "selected" : "";
-printf "<option value=3 %s> $text{'download_mti'}\n",
- $in{'mode'} == 3 ? "selected" : "";
-print "</select></td> </tr>\n";
+print &ui_table_row($text{'download_act'},
+ &ui_select("act", $in{'mode'},
+ [ [ 0, $text{'download_m'} ],
+ [ 1, $text{'download_mt'} ],
+ [ 2, $text{'download_mi'} ],
+ [ 3, $text{'download_mti'} ] ]));
-print "<tr> <td><b>$text{'download_args'}</b></td>\n";
-print "<td>",&ui_textbox("args", $config{'def_args'}, 40),"</td> </tr>\n";
+# Command-line args to Makefile.PL
+print &ui_table_row($text{'download_args'},
+ &ui_textbox("args", $config{'def_args'}, 40));
-print "<tr> <td valign=top><b>$text{'download_envs'}</b></td>\n";
-print "<td><table border> <tr $tb> <td><b>$text{'download_name'}</b></td> ",
- "<td><b>$text{'download_value'}</b></td> </tr>\n";
+# Table of environment variables
+$etable = &ui_columns_start([ $text{'download_name'},
+ $text{'download_value'} ]);
for($i=0; $i<4; $i++) {
- print "<tr $cb>\n";
- print "<td><input name=name_$i size=15></td>\n";
- print "<td><input name=value_$i size=25></td>\n";
+ $etable .= &ui_columns_row([ &ui_textbox("name_$i", undef, 15),
+ &ui_textbox("value_$i", undef, 30) ]);
}
-print "</table></td> </tr>\n";
+$etable .= &ui_columns_end();
+print &ui_table_row($text{'download_envs'}, $etable);
-print "</table></td></tr></table>\n";
-print "<input type=submit value='$text{'download_cont'}'>\n";
-if (@needreqs && $in{'source'} == 3) {
- print " " x 2;
- print "<input type=submit name=need value='$text{'download_need'}'>\n";
- }
-print "</form>\n";
+print &ui_table_end();
+print &ui_form_end([ [ undef, $text{'download_cont'} ],
+ @needreqs && $in{'source'} == 3 ?
+ ( [ "need", $text{'download_need'} ] ) : ( )
+ ]);
&ui_print_footer("", $text{'index_return'});
&ui_print_header(undef, $text{'edit_title'}, "");
-print "<table border width=100%>\n";
-print "<tr $tb> <td><b>$text{'edit_header'}</b></td> </tr>\n";
-print "<tr $cb> <td><table width=100%>\n";
+print &ui_table_start($text{'edit_header'}, "width=100%", 4);
+# Module name and version
@m = @{$mod->{'mods'}};
($desc, $ver) = &module_desc($mod, $midx);
-print "<tr> <td><b>$text{'edit_mod'}</b></td>\n";
-print "<td>$m[$midx] $ver</td>\n";
+print &ui_table_row($text{'edit_mod'}, "$m[$midx] $ver");
-print "<td><b>$text{'edit_desc'}</b></td>\n";
-print "<td>",$desc ? &html_escape($desc) : $text{'edit_none'},"</td> </tr>\n";
+# Description
+print &ui_table_row($text{'edit_desc'},
+ $desc ? &html_escape($desc) : $text{'edit_none'});
-print "<tr> <td><b>$text{'edit_date'}</b></td>\n";
-print "<td nowrap>$mod->{'date'}</td>\n";
+# Install date
+print &ui_table_row($text{'edit_date'}, $mod->{'date'});
-print "<td><b>$text{'edit_file'}</b></td>\n";
-print "<td>$mod->{'files'}->[$midx]</td> </tr>\n";
+# Main file
+print &ui_table_row($text{'edit_file'}, $mod->{'files'}->[$midx]);
-print "<tr> <td><b>$text{'edit_method'}</b></td>\n";
-print "<td>",$mod->{'pkg'} ?
- &text('edit_'.$mod->{'pkgtype'}, "<tt>$mod->{'pkg'}</tt>") :
- $text{'edit_manual'},"</td>\n";
-print "</tr>\n";
+# Install method (RPM or whatever)
+print &ui_table_row($text{'edit_method'},
+ $mod->{'pkg'} ? &text('edit_'.$mod->{'pkgtype'}, "<tt>$mod->{'pkg'}</tt>")
+ : $text{'edit_manual'});
if ($midx == $mod->{'master'} && @m > 1) {
- print "<tr> <td valign=top><b>$text{'edit_subs'}</b></td>\n";
- print "<td colspan=3>";
+ # Sub-modules
@links = ( );
for($i=0; $i<@m; $i++) {
push(@links, "<a href='edit_mod.cgi?idx=$in{'idx'}&midx=$i&name=$in{'name'}'>$m[$i]</a>") if ($i != $mod->{'master'});
}
- print &ui_links_row(\@links);
- print "</td> </tr>\n";
+ print &ui_table_row($text{'edit_subs'}, &ui_links_row(\@links), 3);
}
-print "</table></td></tr></table>\n";
+print &ui_table_end();
-print "<table width=100%> <tr>\n";
+# Un-install form
+print "<table> <tr>\n";
if ($midx == $mod->{'master'} && !$mod->{'noremove'}) {
- print "<form action=uninstall.cgi><td>\n";
- print "<input type=hidden name=idx value='$in{'idx'}'>\n";
- print "<input type=submit value='$text{'edit_uninstall'}'>\n";
- print "</td></form>\n";
+ print &ui_form_start("uninstall.cgi");
+ print &ui_hidden("idx", $in{'idx'});
+ print "<td>",&ui_submit($text{'edit_uninstall'}),"</td>\n";
+ print &ui_form_end();
}
+# Upgrade form
if ($midx == $mod->{'master'} && !$mod->{'noupgrade'}) {
- print "<form action=download.cgi><td align=right>\n";
- print "<input type=hidden name=cpan value='$mod->{'mods'}->[0]'>\n";
- print "<input type=hidden name=source value=3>\n";
- print "<input type=submit value='$text{'edit_upgrade'}'>\n";
- print "</td></form>\n";
+ print &ui_form_start("download.cgi");
+ print &ui_hidden("cpan", $mod->{'mods'}->[0]);
+ print &ui_hidden("source", 3);
+ print "<td>",&ui_submit($text{'edit_upgrade'}),"</td>\n";
+ print &ui_form_end();
}
print "</table>\n";
-print "<br>\n";
+# Module documentation
open(DOC, "$perl_doc -t '$m[$midx]' 2>/dev/null |");
while(<DOC>) { $doc .= $_; }
close(DOC);
if ($doc =~ /\S/) {
- print "<table border width=100%>\n";
- print "<tr $tb> <td><b>$text{'edit_header2'}</b></td> </tr>\n";
- print "<tr $cb> <td><pre>";
- print &html_escape($doc);
- print "</pre></td></tr></table><br>\n";
+ print &ui_table_start($text{'edit_header2'}, "width=100%", 2);
+ print &ui_table_row(undef, "<pre>".&html_escape($doc)."</pre>", 2);
+ print &ui_table_end();
}
&ui_print_footer($midx != $mod->{'master'} ?
$ver = join(".", map { ord($_) } split(//, $^V));
&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1, 0,
undef, undef, undef, &text('index_pversion', $ver));
+&ReadParse();
# Check if Perl is installed from a global zone
if (&shared_perl_root()) {
&ui_print_footer("/", $text{'index'});
exit;
}
+$formno = 0;
-# Display perl modules
+# Start tabs
@mods = &list_perl_modules();
+@tabs = ( [ 'mods', $text{'index_tabmods'}, 'index.cgi?mode=mods' ],
+ [ 'install', $text{'index_tabinstall'}, 'index.cgi?mode=install' ],
+ [ 'suggest', $text{'index_tabsuggest'}, 'index.cgi?mode=suggest' ],
+ );
+if (!$in{'mode'}) {
+ $in{'mode'} = @mods ? 'mods' : 'install';
+ }
+print &ui_tabs_start(\@tabs, 'mode', $in{'mode'}, 1);
+
+# Display perl modules
+print &ui_tabs_start_tab('mode', 'mods');
if (@mods) {
print &ui_form_start("uninstall_mods.cgi", "post");
print &select_all_link("d", 0),"\n";
print &select_invert_link("d", 0),"<br>\n";
print &ui_form_end([ [ "delete", $text{'index_delete'} ],
[ "upgrade", $text{'index_upgrade'} ] ]);
- print "<hr>\n";
+ $formno++;
+ }
+else {
+ print "<b>$text{'index_none'}</b><p>\n";
}
+print &ui_tabs_end_tab();
# Display install form
+print &ui_tabs_start_tab('mode', 'install');
print "$text{'index_installmsg'}<p>\n";
-print "<form action=download.cgi method=post enctype=multipart/form-data>\n";
-print "<input type=radio name=source value=3 checked> $text{'index_cpan'}\n";
-print "<input name=cpan size=40>\n";
-print "<input type=button onClick='window.ifield = document.forms[0].cpan; chooser = window.open(\"cpan.cgi\", \"chooser\", \"toolbar=no,menubar=no,scrollbars=yes,width=400,height=300\")' value=\"...\">\n";
+print &ui_form_start("download.cgi", "form-data");
+
+# Work out of packages should be refreshed
@st = stat($packages_file);
if (@st) {
$now = time();
- print "<br> \n";
- printf "<input type=checkbox name=refresh value=1 %s> %s\n",
- $st[9]+$config{'refresh_days'}*24*60*60 < $now ? "checked" : "",
- $text{'index_refresh'};
+ $refreshopt = "<br>".&ui_checkbox("refresh", 1, $text{'index_refresh'},
+ $st[9]+$config{'refresh_days'}*24*60*60 < $now);
}
-print "<br>\n";
-
-print "<input type=radio name=source value=0> $text{'index_local'}\n";
-print "<input name=local size=50>\n";
-print &file_chooser_button("local", 0); print "<br>\n";
-print "<input type=radio name=source value=1> $text{'index_uploaded'}\n";
-print "<input type=file name=upload size=20><br>\n";
-
-print "<input type=radio name=source value=2> $text{'index_ftp'}\n";
-print "<input name=url size=50><br>\n";
-print "<input type=submit value=\"$text{'index_installok'}\">\n";
-print "</form>\n";
+@opts = ( [ 3, $text{'index_cpan'},
+ &ui_textbox("cpan", undef, 50)." ".
+ &ui_button("...", undef, 0, "onClick='window.ifield = document.forms[$formno].cpan; chooser = window.open(\"cpan.cgi\", \"chooser\", \"toolbar=no,menubar=no,scrollbars=yes,width=800,height=500\"); chooser.ifield = window.ifield;'").
+ $refreshopt ],
+ [ 0, $text{'index_local'},
+ &ui_textbox("local", undef, 50)." ".
+ &file_chooser_button("local", 0) ],
+ [ 1, $text{'index_uploaded'},
+ &ui_upload("upload", 50) ],
+ [ 2, $text{'index_ftp'},
+ &ui_textbox("url", undef, 50) ]
+ );
+print &ui_radio_table("source", 3, \@opts);
+print &ui_form_end([ [ undef, $text{'index_installok'} ] ]);
+print &ui_tabs_end_tab();
# Show button to install recommended Perl modules
+print &ui_tabs_start_tab('mode', 'suggest');
@allrecs = &get_recommended_modules();
@recs = grep { eval "use $_->[0]"; $@ } @allrecs;
if (@recs) {
- print "<hr>\n";
print &ui_form_start("download.cgi");
print &ui_hidden("source", 3),"\n";
print "$text{'index_recs'}<p>\n";
print &ui_form_end();
}
elsif (@allrecs) {
- print "<hr>\n";
print &text('index_recsgot',"<tt>".join(" ", map { $_->[0] } @allrecs)."</tt>"),"<p>\n";
}
+print &ui_tabs_end_tab();
+
+print &ui_tabs_end(1);
&ui_print_footer("/", $text{'index'});
sub show_output
{
local (%seen, $endless_loop);
-print "<table border>\n";
-print "<tr $tb> <td><b>$_[0]</b></td> </tr>\n";
-print "<tr $cb> <td><pre>",&text('install_exec', $_[2]),"\n";
-print " " x 100,"\n";
+print &ui_table_start($_[0], undef, 2);
+local $msg = "<pre>".&text('install_exec', $_[2])."\n";
+$msg .= (" " x 100)."\n";
open(CMD, "(cd $_[1] ; $_[2]) 2>&1 </dev/null |");
while(<CMD>) {
if ($seen{$_}++ > 100) {
$endless_loop = 1;
- print "\n$text{'install_loop'}\n";
+ $msg .= "\n$text{'install_loop'}\n";
last;
}
while(length($_) > 100) {
s/^(.{100})//;
- print &html_escape($1),"\n";
+ $msg .= &html_escape($1)."\n";
}
- print;
+ $msg .= &html_escape($_);
}
close(CMD);
-print "</pre></td></tr> </table><p>\n";
+$msg .= "</pre>";
+print &ui_table_row(undef, $msg, 2);
+print &ui_table_end();
return $? || $endless_loop ? 0 : 1;
}
index_recsok=Install Selected Modules
index_recsgot=All of the following Perl modules recommended by Webmin are installed : $1
index_ezone=Perl appears to be shared with the global zone, so modules cannot be installed here. They must be installed in the global zone instead.
+index_none=No installed Perl modules were found on your system.
+index_tabmods=Existing modules
+index_tabinstall=Install module
+index_tabsuggest=Suggested modules
download_err=Failed to install module
download_elocal=No local file given
# Ask the user if he is sure
&ui_print_header(undef, $text{'uninstall_title'}, "");
- print "<form action=uninstall.cgi>\n";
- print "<input type=hidden name=idx value='$in{'idx'}'>\n";
+ print &ui_form_start("uninstall.cgi");
+ print &ui_hidden("idx", $in{'idx'});
local ($m, @sm) = @{$mod->{'mods'}};
if (@sm) {
print &text('uninstall_rusure2', "<tt>$m</tt>",
print &text('uninstall_'.$mod->{'pkgtype'},
"<tt>$mod->{'pkg'}</tt>"),"<p>\n";
}
- print "<center><input type=submit name=confirm ",
- "value='$text{'uninstall_ok'}'></center></form>\n";
+ print "<center>",&ui_submit($text{'uninstall_ok'}, "confirm"),
+ "</center>",&ui_form_end();
&ui_print_footer("edit_mod.cgi?idx=$in{'idx'}", $text{'edit_return'},
"", $text{'index_return'});