From a2c27067801beb1c93b48f9cac1d498cec77001e Mon Sep 17 00:00:00 2001 From: Antoine Ginies Date: Wed, 6 Jul 2005 02:29:14 +0000 Subject: button to close draknfs "Reload NFS server" hput in a menu using icons for "dir path" button an editable combolist for Access various typor fix "close" button in help dialog box use pango for text field --- perl-install/standalone/draknfs | 318 ++++++++++++++++++++++++++++------------ 1 file changed, 222 insertions(+), 96 deletions(-) (limited to 'perl-install/standalone/draknfs') diff --git a/perl-install/standalone/draknfs b/perl-install/standalone/draknfs index c98e9c3ee..474bde4f4 100644 --- a/perl-install/standalone/draknfs +++ b/perl-install/standalone/draknfs @@ -17,42 +17,70 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. -my $version = "0.1"; +my $version = "0.2"; use strict; use lib qw(/usr/lib/libDrakX); use standalone; use common; - +use network::network; use interactive; use ugtk2 qw(:ask :wrappers :create :dialogs); my $in = 'interactive'->vnew('su'); - use constant FALSE => 0; use constant TRUE => 1; - -sub test_root { - unless ($> == 0) { - err_dialog(N("Error!"), N("You are not root. Exiting...")); - die unless $::testing; - } -} +use constant COLUMN_DIR => 0; +use constant COLUMN_ACCESS => 1; +use constant COLUMN_RIGHT => 2; +use constant COLUMN_OPTIONS => 3; +use constant NUM_COLUMNS => 4; my $CONF = "/etc/exports"; my @listshare; my @listuserid = qw(root_squash no_root_squash all_squash no_all_squash); push @listuserid, ""; -my @listsecure = qw(secure insecure ); push @listsecure, ""; -my @listsync = qw(async sync); push @listsync, ""; -my @listr = qw(ro rw); push @listr, ""; +# root_squash : Map root user as anonymous +# all_squash : map all users to a precise user +# no_root_squash : Allow real remote root access + +my @yesno = qw(yes no); push @yesno, ""; + +sub get_items { + my @items = ( + [ "/_File", undef, undef, undef, '', ], + [ "/_File/_Exit", undef, \&quit_all, 1, '', 'gtk-quit' ], + + [ "/_NFS Server", undef, undef, undef, '', ], + [ "/_NFS Server/_Restart", undef, \&restart_dialog, 1, '', 'gtk-execute' ], + [ "/_NFS Server/R_eload", undef, \&reload_dialog, 1, '', 'gtk-refresh' ], + ); + return @items; +} +sub quit_all() { + ugtk2->exit; +} -use constant COLUMN_DIR => 0; -use constant COLUMN_ACCESS => 1; -use constant COLUMN_RIGHT => 2; -use constant COLUMN_OPTIONS => 3; -use constant NUM_COLUMNS => 4; +sub restart_dialog { + wait_action("system nfs restart"); +} + +sub reload_dialog { + wait_action("system nfs reload"); +} + +sub wait_action { + my ($cmd) = @_; + my $w = $in->wait_message(N("NFS server"), N("Restarting/reloading your NFS server...")); + eval { system($cmd) }; + my $err = $@; + undef $w; + if ($err) { + err_dialog(N("Error"), N("NFS server cant restart:") . "\n\n" . $err); + } + undef $w; +} my %size_groups = map { $_ => Gtk2::SizeGroup->new('horizontal') } qw(label widget button); my $label_and_widgets = sub { @@ -100,76 +128,136 @@ sub write_conf { } } -my $help_access = N("NFS clients may be specified in a number of ways: -single host: You may specify a host either by an abbreviated name recognized be the resolver, the fully qualified domain name, or an IP address. +my $help_access = N("NFS clients may be specified in a number of ways: + + +single host: a host either by an abbreviated name recognized be the resolver, fully qualified domain name, or an IP address + -netgroups: NIS netgroups may be given as \@group. +netgroups: NIS netgroups may be given as \@group. -wildcards: machine names may contain the wildcard characters * and ?. For instance: *.cs.foo.edu matches all hosts in the domain cs.foo.edu. -IP networks: you can also export directories to all hosts on an IP (sub-)network simultaneously. for example, either `/255.255.252.0' or `/22' appended to the network base address result. +wildcards: machine names may contain the wildcard characters * and ?. For instance: *.cs.foo.edu matches all hosts in the domain cs.foo.edu. + + +IP networks: you can also export directories to all hosts on an IP (sub-)network simultaneously. for example, either `/255.255.252.0' or `\/22' appended to the network base address result. "); -my $help_userid = N("root_squash: map requests from uid/gid 0 to the anonymous uid/gid. +my $help_userid = N("User ID options + + +root_squash: map requests from uid/gid 0 to the anonymous uid/gid. + + +no_root_squash: turn off root squashing. This option is mainly useful for diskless clients. + -no_root_squash: turn off root squashing. This option is mainly useful for diskless clients. +all_squash: map all uids and gids to the anonymous user. Useful for NFS-exported public FTP directories, news spool directories, etc. The opposite option is no_all_squash, which is the default setting. -all_squash: map all uids and gids to the anonymous user. Useful for NFS-exported public FTP directories, news spool directories, etc. The opposite option is no_all_squash, which is the default setting. -anonuid and anongid: explicitly set the uid and gid of the anonymous account. +anonuid and anongid: explicitly set the uid and gid of the anonymous account. "); -my $help_global = N("secure: this option requires that requests originate on an internet port less than IPPORT_RESERVED (1024). This option is on by default. To turn it off, specify insecure. +my $help_global = N("Advanced Options -rw: allow both read and write requests on this NFS volume. The default is to disallow any request which changes the filesystem. This can also be made explicit by using the ro option. -async: allows the NFS server to violate the NFS protocol and reply to requests before any changes made by that request have been committed to stable storage (e.g. disc drive). +secure: this option requires that requests originate on an internet port less than IPPORT_RESERVED (1024). This option is on by default. To turn it off, specify insecure. + + +rw: allow both read and write requests on this NFS volume. The default is to disallow any request which changes the filesystem. This can also be made explicit by using the ro option. + + +async: allows the NFS server to violate the NFS protocol and reply to requests before any changes made by that request have been committed to stable storage (e.g. disc drive). "); +sub create_pango_help_box { + # perl code from draksec + my ($help) = @_; + my $text = Gtk2::TextView->new; + use Gtk2::Pango; + my %common_opts = ('left-margin' => '10', 'right-margin' => '10'); + gtktext_insert($text, [ map { + if (s!^/span>!!) { + [ $_, \%common_opts ]; + } elsif (s!span !!) { + my %tags = %common_opts; + while (s!(\w+?)="(\w+?)"!!) { + $tags{weight} ||= Gtk2::Pango->PANGO_WEIGHT_BOLD if $1 eq 'foreground'; + $tags{$1} = $2 eq "bold" ? Gtk2::Pango->PANGO_WEIGHT_BOLD : $2; + } + s/^>//; + [ $_, \%tags ]; + } else { + [ $_, \%common_opts ]; + } + } split("<", formatAlaTeX($help)) ]); + gtkset_size_request(create_scrolled_window($text), 350, 300); +} + sub help_b { my ($tittle, $help_data) = @_; - gtksignal_connect(new Gtk2::Button(N("Help")), clicked => sub { + gtksignal_connect(new Gtk2::Button->new_from_stock('gtk-dialog-info'), clicked => sub { my $dialog = new Gtk2::Dialog(); $dialog->set_title(N("Help")); $dialog->set_modal(1); gtkpack_($dialog->vbox, - 0, gtkadd(Gtk2::Frame->new(translate($tittle)), - gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), - 0, $help_data, - ), - ), + 1, $help_data, + 0, gtksignal_connect(Gtk2::Button->new_from_stock('gtk-close'), clicked => sub { + $dialog->destroy; + } + ), ); $dialog->show_all; } ); } +sub get_access_list { + my $net = {}; + network::network::read_net_conf($net); + my $interface ||= $net->{net_interface}; + my $ip_address = network::tools::get_interface_ip_address($net, $interface); + my $domain = chomp_(`dnsdomainame`); + my @o = split(/\./, $ip_address); + my $ipnet; + if ($ip_address) { + $ipnet = $o[0] . "." . $o[1] . "." . $o[2] . "0"; + } else { $ipnet = "ip_address" } + my @all = split(", ", qq(*, $domain, $ipnet/8, $ipnet/24, $ipnet/32)); + return @all; +} + sub add_modify_entry { my ($widget, $treeview, $wanted) = @_; my $model = $treeview->get_model; my $selection = $treeview->get_selection; my $iter; my ($i, $dir, $access, $right, $anonuid, $anongid, $options); - my ($lr, $luserid, $lsecure, $lsync); + my ($lr, $luserid, $lsecure, $lsync, $lr_data, $lsync_data, $lsecure_data); undef $i; undef $iter; - $_ = Gtk2::Entry->new foreach $dir, $access, $anongid, $anonuid, $options; + $_ = Gtk2::Entry->new foreach $dir, $anongid, $anonuid, $options; $_ = Gtk2::OptionMenu->new foreach $lr, $luserid, $lsecure, $lsync; - my $luserid = new Gtk2::OptionMenu; + + $access = Gtk2::ComboBoxEntry->new_text; + foreach (get_access_list()) { + $_ and $access->append_text($_); + } $luserid->set_popdown_strings(@listuserid); - $lr->set_popdown_strings(@listr); - $lsync->set_popdown_strings(@listsync); - $lsecure->set_popdown_strings(@listsecure); + $lr->set_popdown_strings(@yesno); + $lsync->set_popdown_strings(@yesno); + $lsecure->set_popdown_strings(@yesno); my $file_dialog = $fdwidget->($dir, ""); - my $button = Gtk2::Button->new(N("dir path")); + my $button = Gtk2::Button->new_from_stock('gtk-open'); $button->signal_connect(clicked => sub { $file_dialog->show }); # test if modify or add a nfs share my $dialog = new Gtk2::Dialog(); $dialog->set_title("Draknfs $wanted entry"); + $dialog->set_position('center'); $dialog->set_modal(1); $dialog->set_resizable(1); @@ -178,7 +266,9 @@ sub add_modify_entry { my $path = $model->get_path($iter); $i = ($path->get_indices)[0]; $dir->set_text($listshare[$i]{dir}); - $access->set_text($listshare[$i]{access}); + $access->append_text($listshare[$i]{access}); + $access->child->set_text($listshare[$i]{access}); +# $access->set_active(0); # list of all rigth in bracket # $anongid, $anonuid, $lr, $luserid, $lsecure, $lsync; $right = $listshare[$i]{right}; @@ -187,9 +277,9 @@ sub add_modify_entry { foreach my $opt (@opts) { if ($opt =~ m/(\bro\b|\brw\b)/) { - $lr->set_text($opt); + if ($opt =~ /ro/) { $lr->set_text("yes") } else { $lr->set_text("no") } } elsif ($opt =~ m/\bsync\b|\basync\b/) { - $lsync->set_text($opt); + if ($opt =~ /sync/) { $lsync->set_text("yes") } else { $lsync->set_text("no") } } elsif ($opt =~ m/anongid=(\d+)/) { $anongid->set_text($1); } elsif ($opt =~ m/anonuid=(\d+)/) { @@ -197,11 +287,33 @@ sub add_modify_entry { } elsif ($opt =~ m/(no_root_squash|root_squash|all_squash|no_all_squash)/) { $luserid->set_text($opt); } elsif ($opt =~ m/(\bsecure\b|\binsecure\b)/) { - $lsecure->set_text($opt); + if ($opt =~ /insecure/) { $lsecure->set_text("no") } else { $lsecure->set_text("yes") } } else { next } } } + $luserid->signal_connect(changed => sub { + if ($luserid->get_text =~ /no_root_squash/) { + $anongid->set_sensitive(0); + $anonuid->set_sensitive(0); + } else { + $anongid->set_sensitive(1); + $anonuid->set_sensitive(1); + } + }); + if ($luserid->get_text =~ /no_root_squash/) { + $anongid->set_sensitive(0); + $anonuid->set_sensitive(0); + } + + if ($wanted =~ /add/) { + # default choice root_squash and ro + $luserid->set_text("root_squash"); + $lr->set_text("yes"); + $lsecure->set_text(""); + $lsync->set_text(""); + } + gtkpack_($dialog->vbox, 0, gtkadd(Gtk2::Frame->new(N("NFS directory")), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), @@ -210,24 +322,24 @@ sub add_modify_entry { ), 0, gtkadd(Gtk2::Frame->new(N("Host access")), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), - 0, $label_and_widgets->(N("Access:"), $access, help_b(N_("Help User ID"), $help_access)), + 0, $label_and_widgets->(N("Access:"), $access, help_b(N_("Hosts Access"), create_pango_help_box($help_access))), ), ), 0, gtkadd(Gtk2::Frame->new(N("User ID Mapping")), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), - 0, $label_and_widgets->(N("User ID:"), $luserid, help_b(N_("Help User ID"), $help_userid)), + 0, $label_and_widgets->(N("User ID:"), $luserid, help_b(N_("Help User ID"), create_pango_help_box($help_userid))), 0, $label_and_widgets->(N("anonuid:"), $anonuid, ""), 0, $label_and_widgets->(N("anongid:"), $anongid, ""), ), ), - 0, gtkadd(Gtk2::Frame->new(N("General Options")), + 0, gtkadd(Gtk2::Frame->new(N("Advanced Options")), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), - 0, $label_and_widgets->(N("Force sync:"), $lsync, help_b(N_("Help General options"), $help_global)), - 0, $label_and_widgets->(N("port below 1024:"), $lsecure, ""), - 0, $label_and_widgets->(N("Read/Write request:"), $lr, ""), + 0, $label_and_widgets->(N("Synchronous access:"), $lsync, help_b(N_("Help Adcanced options"), create_pango_help_box($help_global))), + 0, $label_and_widgets->(N("Secured Connection:"), $lsecure, ""), + 0, $label_and_widgets->(N("Read-Only share:"), $lr, ""), ), ), - 0, gtkadd(Gtk2::Frame->new(N("More Options")), + 0, gtkadd(Gtk2::Frame->new(N("Custom Options")), gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), 0, $label_and_widgets->(N("options:"), $options, ""), ), @@ -238,21 +350,26 @@ sub add_modify_entry { my ($anonu, $anong); $anonuid->get_text and $anonu = "anonuid=" . $anonuid->get_text; $anongid->get_text and $anong = "anongid=" . $anongid->get_text; - my $all_right = join(",", grep { defined $_ } $luserid->get_text, $anonu, $anong, $lsync->get_text, $lsecure->get_text, $lr->get_text); + if ($lsync->get_text =~ /yes/) { $lsync_data = "sync" } elsif ($lsync->get_text =~ /no/) { $lsync_data = "async" } else { $lsync_data = "" } + if ($lr->get_text =~ /yes/) { $lr_data = "ro" } elsif ($lr->get_text =~ /no/) { $lr_data = "rw" } else { $lr_data = "" } + if ($lsecure->get_text =~ /yes/) { $lsecure_data = "secure" } elsif ($lsecure->get_text =~ /no/) { $lsecure_data = "insecure" } else { $lsecure_data = "" } + my $all_right = join(",", grep { defined $_ } $luserid->get_text, $anonu, $anong, $lsync_data, $lsecure_data, $lr_data); if ($wanted =~ /add/) { - my $test_dir = $dir->get_text; - -d $test_dir or err_dialog(N("Error!"), N("Please enter a directory to share.")) and return; + my $test_dir = $dir->get_text; + -d $test_dir or err_dialog(N("Error!"), N("Please enter a directory to share.")) and return; + my $test_access = $access->child->get_text; + $test_access or err_dialog(N("Error!"), N("You must specify hosts access.")) and return; $iter = $model->append; $i = "-1"; push @listshare, { dir => $dir->get_text, - access => $access->get_text, + access => $access->child->get_text, right => $all_right, options => $options->get_text, }; } $listshare[$i]{right} = $all_right; - $listshare[$i]{access} = $access->get_text; + $listshare[$i]{access} = $access->child->get_text; $listshare[$i]{dir} = $dir->get_text; $listshare[$i]{options} = $options->get_text; $model->set($iter, @@ -304,13 +421,21 @@ sub create_model() { sub add_columns { my $treeview = shift; my $model = $treeview->get_model; +# my @colsize = (120, 160, 120); +# each_index { +# my $renderer = Gtk2::TreeViewColumn->new_with_attributes($_, Gtk2::CellRendererText->new, 'text' => $::i); +# $renderer->set_sort_column_id($::i); +# $renderer->set_min_width($colsize[$::i]); +# $treeview->append_column($renderer); +# } N("Share Directory"), N("Hosts Wildcard"), N("General Options"), N("Custom Options"); + each_index { my $renderer = Gtk2::CellRendererText->new; $renderer->set(editable => 0); $renderer->signal_connect(edited => \&cell_edited, $model); $renderer->set_data(column => $::i); $treeview->insert_column_with_attributes(-1, $_, $renderer, 'text' => $::i); - } N("Share Directory"), N("Hosts Wildcard"), N("General Options"), N("More Options"); + } N("Share Directory"), N("Hosts Wildcard"), N("General Options"), N("Custom Options"); } @@ -318,12 +443,11 @@ sub add_columns { # Main Program ############### # create model -#test_root(); - my $model = create_model(); my $window = ugtk2->new("Draknfs $version"); $window->{rwindow}->set_size_request(530, 300) unless $::isEmbedded; +$window->{rwindow}->set_position('center') if !$::isEmbedded; my $W = $window->{window}; $W->signal_connect(delete_event => sub { ugtk2->exit }); @@ -332,6 +456,12 @@ $treeview->set_rules_hint(TRUE); $treeview->get_selection->set_mode('single'); add_columns($treeview); +# create menu +my @items = get_items(); +my $factory = Gtk2::ItemFactory->new('Gtk2::MenuBar', '
', undef); +$factory->create_items('menu', @items); +my $menu = $factory->get_widget('
'); + my $okcancel = create_okcancel({ cancel_clicked => sub { ugtk2->exit }, ok_clicked => \&write_conf, @@ -340,42 +470,38 @@ my $okcancel = create_okcancel({ # main interface $W->add(gtkpack_(Gtk2::VBox->new(0,0), - 0, Gtk2::Label->new("Here you cann add, remove and alter NFS shares."), + 0, Gtk2::Label->new("Here you can add, remove and alter NFS shares."), + 0, $menu, 1, create_scrolled_window($treeview), 0, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 3), - 1, gtkpack_(create_hbox('edge'), - 0, gtksignal_connect(Gtk2::Button->new(N("Add")), clicked => sub { - eval { add_modify_entry($model, $treeview, "add") }; - my $err = $@; - if ($err) { - err_dialog(N("Error"), N("Failed to add NFS share.") . "\n\n" . $err); - } - }), - 0, gtksignal_connect(Gtk2::Button->new(N("Modify")), clicked => sub { - eval { add_modify_entry($model, $treeview, "modify") }; - my $err = $@; - if ($err) { - err_dialog(N("Error"), N("Failed to Modify NFS share.") . "\n\n" . $err); - } - }), - - 0, gtksignal_connect(Gtk2::Button->new(N("Remove")), clicked => sub { - eval { remove_entry($model, $treeview) }; - my $err = $@; - if ($err) { - err_dialog(N("Error"), N("Failed to remove an NFS share.") . "\n\n" . $err); - } - }), - ), - 0, Gtk2::VSeparator->new, - 0, gtksignal_connect(Gtk2::Button->new(N("Reload NFS server")), clicked => sub { - system("/sbin/service nfs reload"); - }), - - ), - if_($::isEmbedded, 0, $okcancel), - ), - ); + 1, gtkpack_(create_hbox('edge'), + 0, gtksignal_connect(Gtk2::Button->new(N("Add")), clicked => sub { + eval { add_modify_entry($model, $treeview, "add") }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to add NFS share.") . "\n\n" . $err); + } + }), + 0, gtksignal_connect(Gtk2::Button->new(N("Modify")), clicked => sub { + eval { add_modify_entry($model, $treeview, "modify") }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to Modify NFS share.") . "\n\n" . $err); + } + }), + + 0, gtksignal_connect(Gtk2::Button->new(N("Remove")), clicked => sub { + eval { remove_entry($model, $treeview) }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to remove an NFS share.") . "\n\n" . $err); + } + }), + ), + if_($::isEmbedded, 0, $okcancel), + ), + ), + ); $W->show_all; Gtk2->main; -- cgit v1.2.1