summaryrefslogtreecommitdiffstats
path: root/perl-install/standalone/draknfs
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/standalone/draknfs')
-rw-r--r--perl-install/standalone/draknfs318
1 files changed, 222 insertions, 96 deletions
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, '<Branch>', ],
+ [ "/_File/_Exit", undef, \&quit_all, 1, '<StockItem>', 'gtk-quit' ],
+
+ [ "/_NFS Server", undef, undef, undef, '<Branch>', ],
+ [ "/_NFS Server/_Restart", undef, \&restart_dialog, 1, '<StockItem>', 'gtk-execute' ],
+ [ "/_NFS Server/R_eload", undef, \&reload_dialog, 1, '<StockItem>', '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("<span weight=\"bold\">NFS clients</span> may be specified in a number of ways:
+
+
+<span foreground=\"royalblue3\">single host:</span> 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.
+<span foreground=\"royalblue3\">netgroups:</span> 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.
+<span foreground=\"royalblue3\">wildcards:</span> machine names may contain the wildcard characters * and ?. For instance: *.cs.foo.edu matches all hosts in the domain cs.foo.edu.
+
+
+<span foreground=\"royalblue3\">IP networks:</span> 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("<span weight=\"bold\">User ID options</span>
+
+
+<span foreground=\"royalblue3\">root_squash:</span> map requests from uid/gid 0 to the anonymous uid/gid.
+
+
+<span foreground=\"royalblue3\">no_root_squash:</span> 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.
+<span foreground=\"royalblue3\">all_squash:</span> 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.
+<span foreground=\"royalblue3\">anonuid and anongid:</span> 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("<span weight=\"bold\">Advanced Options</span>
-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).
+<span foreground=\"royalblue3\">secure:</span> 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.
+
+
+<span foreground=\"royalblue3\">rw:</span> 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.
+
+
+<span foreground=\"royalblue3\">async:</span> 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', '<main>', undef);
+$factory->create_items('menu', @items);
+my $menu = $factory->get_widget('<main>');
+
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;