diff options
-rw-r--r-- | perl-install/standalone/drakhosts | 252 | ||||
-rw-r--r-- | perl-install/standalone/draknfs | 370 |
2 files changed, 622 insertions, 0 deletions
diff --git a/perl-install/standalone/drakhosts b/perl-install/standalone/drakhosts new file mode 100644 index 000000000..c76762158 --- /dev/null +++ b/perl-install/standalone/drakhosts @@ -0,0 +1,252 @@ +#!/usr/bin/perl -w +# +# Copyright (C) 2005 by Mandriva aginies _ateuh_ mandriva.com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +my $version = "0.1"; + +# i18n: IMPORTANT: to get correct namespace (drakpxelinux instead of libDrakX) +BEGIN { unshift @::textdomains, 'drakhosts' } + +use lib qw(/usr/lib/libDrakX); +use standalone; +use strict; +use common; +use network::network; + +use interactive; +# must come *after* definition of textdomains for proper initialisation +use ugtk2 qw(:ask :wrappers :create :dialogs); + +use constant FALSE => 0; +use constant TRUE => 1; + +my $HOSTS = "/etc/hosts"; +my @listhosts; + +use constant COLUMN_IP => 0; +use constant COLUMN_HOSTNAME => 1; +use constant COLUMN_ALIAS => 2; +use constant NUM_COLUMNS => 3; + +my $in = 'interactive'->vnew('su'); + +my %size_groups = map { $_ => Gtk2::SizeGroup->new('horizontal') } qw(label widget); +my $label_and_widgets = sub { + my ($label, $widget) = @_; + gtkpack_(Gtk2::HBox->new(0,5), + 0, gtkadd_widget($size_groups{label}, $label), + 1, gtkadd_widget($size_groups{widget}, $widget), + ); +}; + + +sub get_host_data { +# 127.0.0.1 localhost.localdomain localhost +# 10.0.1.253 guibpiv.guibland.com + foreach (cat_($HOSTS)) { + my ($ip, $name, $alias) = $_ =~ /^(\d\S*)\s+(\S*)\s+(.*)$/; + $ip and push @listhosts, { + ip => $ip, + hostname => $name, + alias => $alias, + }; + } +} + +sub write_conf_hosts { + output($HOSTS, "# generated by drakhosts.pl\n"); + foreach my $a (@listhosts) { + append_to_file($HOSTS, "$a->{ip} $a->{hostname} $a->{alias}\n"); + } +} + +sub add_modify_entry { + my ($widget, $treeview, $wanted) = @_; + my $model = $treeview->get_model; + my $selection = $treeview->get_selection; + my $iter; + my ($i, $ip, $hostname, $alias, $oldip); + undef $i; + undef $iter; + + map { $_ = Gtk2::Entry->new } $ip, $hostname, $alias; + +# test if modify or add a host + + my $dialog = new Gtk2::Dialog(); + $dialog->set_title("Drakhosts $wanted entry"); + $dialog->set_modal(1); + $dialog->set_resizable(1); + + if ($wanted =~ /modify/) { + $iter = $selection->get_selected; + my $path = $model->get_path($iter); + $i = ($path->get_indices)[0]; + $ip->set_text($listhosts[$i]{ip}); + $hostname->set_text($listhosts[$i]{hostname}); + $alias->set_text($listhosts[$i]{alias}); + $oldip = $listhosts[$i]{ip}; + } + + gtkpack_($dialog->vbox, + 0, gtkadd(Gtk2::Frame->new(N("Please $wanted information")), + gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), + 0, $label_and_widgets->(N("IP address:"), $ip), + 0, $label_and_widgets->(N("Host name:"), $hostname), + 0, $label_and_widgets->(N("Host Aliases:"), $alias), + ), + ), + 0, create_okcancel({ + cancel_clicked => sub { $dialog->destroy }, + ok_clicked => sub { + is_ip($ip->get_text()) or err_dialog(N("Error!"), N("Please enter a valid IP address.")) and return; + my $testip = chomp_($ip->get_text()); + my $testname = chomp_($hostname->get_text()); + my $toldip = chomp_($oldip); + if ($testip !~ /$toldip/ or $wanted =~ /add/) { + foreach my $a (@listhosts) { + if ($a->{ip} =~ /$testip/) { + err_dialog(N("Error!"), N("Same IP is already in %s file.", $HOSTS)) and return; + } + } + } + if ($wanted =~ /add/) { + $iter = $model->append; + $i = "-1"; + push @listhosts, { + ip => $ip->get_text(), + hostname => $hostname->get_text(), + alias => $alias->get_text(), + }; + } + $listhosts[$i]{hostname} = $hostname->get_text(); + $listhosts[$i]{alias} = $alias->get_text(); + $listhosts[$i]{ip} = $ip->get_text(); + $model->set($iter, + COLUMN_IP, $listhosts[$i]{ip}, + COLUMN_HOSTNAME, $listhosts[$i]{hostname}, + COLUMN_ALIAS, $listhosts[$i]{alias}, + ); + $dialog->destroy; + write_conf_hosts(); + }, + }, + ), + ); + $dialog->show_all; +} + +sub remove_entry { + my ($widget, $treeview) = @_; + my $model = $treeview->get_model; + my $selection = $treeview->get_selection; + my $iter = $selection->get_selected; + if ($iter) { + my $path = $model->get_path($iter); + my $i = ($path->get_indices)[0]; + ask_okcancel("Remove entry ?", "Remove $listhosts[$i]{hostname}") or return; + $model->remove($iter); + splice @listhosts, $i, 1; + } + write_conf_hosts(); +} + +sub create_model() { + get_host_data(); + my $model = Gtk2::ListStore->new("Glib::String", "Glib::String", "Glib::String"); + foreach my $a (@listhosts) { + my $iter = $model->append; + $model->set($iter, + COLUMN_IP, $a->{ip}, + COLUMN_HOSTNAME, $a->{hostname}, + COLUMN_ALIAS, $a->{alias}, + ), + } + return $model; +} + +# add colum to model +sub add_columns { + my $treeview = shift; + my $model = $treeview->get_model; + 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("IP address"), N("Host name"), N("Host Aliases"); +} + + +############### +# Main Program +############### +# create model +my $model = create_model(); + +my $window = ugtk2->new("Drakhosts $version"); +$window->{rwindow}->set_size_request(400, 300) unless $::isEmbedded; +my $W = $window->{window}; +$W->signal_connect(delete_event => sub { ugtk2->exit }); + +my $treeview = Gtk2::TreeView->new_with_model($model); +$treeview->set_rules_hint(TRUE); +$treeview->get_selection->set_mode('single'); +add_columns($treeview); + +my $okcancel = create_okcancel({ + cancel_clicked => sub { ugtk2->exit }, + ok_clicked => \&write_conf_hosts, + }, + ); + +# main interface +$W->add(gtkpack_(Gtk2::VBox->new(0,0), + 1, create_scrolled_window($treeview), + 0, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 3), + 0, gtksignal_connect(Gtk2::Button->new(N("Add a host")), clicked => sub { + eval { add_modify_entry($model, $treeview, "add") }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to add host.") . "\n\n" . $err); + } + }), + 0, gtksignal_connect(Gtk2::Button->new(N("Modify a host")), clicked => sub { + eval { add_modify_entry($model, $treeview, "modify") }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to Modify host.") . "\n\n" . $err); + } + }), + + 0, gtksignal_connect(Gtk2::Button->new(N("Remove a host")), clicked => sub { + eval { remove_entry($model, $treeview) }; + my $err = $@; + if ($err) { + err_dialog(N("Error"), N("Failed to remove host.") . "\n\n" . $err); + } + }), + 0, Gtk2::VSeparator->new, + ), + if_($::isEmbedded, 0, $okcancel), + ), + ); + +$W->show_all; +Gtk2->main; diff --git a/perl-install/standalone/draknfs b/perl-install/standalone/draknfs new file mode 100644 index 000000000..c1c812572 --- /dev/null +++ b/perl-install/standalone/draknfs @@ -0,0 +1,370 @@ +#!/usr/bin/perl +# +# Copyright (C) 2005 by Mandriva aginies _ateuh_ mandriva.com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +my $version = "0.1"; + +# i18n: IMPORTANT: to get correct namespace (draknfs instead of libDrakX) +BEGIN { unshift @::textdomains, 'draknfs' } + +use strict; +use lib qw(/usr/lib/libDrakX); +use standalone; +use common; +use any; + +use interactive; +# must come *after* definition of textdomains for proper initialisation +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; + } +} + +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, ""; + + +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 %size_groups = map { $_ => Gtk2::SizeGroup->new('horizontal') } qw(label widget button); +my $label_and_widgets = sub { + my ($label, $widget, $button) = @_; + gtkpack_(Gtk2::HBox->new(0,5), + 0, gtkadd_widget($size_groups{label}, $label), + 1, gtkadd_widget($size_groups{widget}, $widget), + 2, gtkadd_widget($size_groups{button}, $button), + ); +}; + +my $fdwidget = sub { + my ($data, $label) = @_; + my $fd = new Gtk2::FileSelection(N("Directory Selection")); + $fd->set_modal(TRUE); + $fd->signal_connect("destroy", sub { $fd->hide }); + $fd->ok_button->signal_connect(clicked => sub { + my $file = $fd->get_filename; + -d $file or err_dialog(N("Error!"), N("Should be a directory.")) and return; + $data->set_text($file); + $fd->hide; + }, $fd); + $fd->cancel_button->signal_connect(clicked => sub { $fd->hide }); + return $fd; +}; + +sub get_nfs_data { +# /home/nis *(async,rw,no_root_squash) +# /home/nis/guibo/Build *(async,rw,no_root_squash) + foreach (cat_($CONF)) { + my ($dir, $access, $right, $options) = m/^(\/\S+)\s+(\S*)\((\S*)\)\s+(\S*)/; + $dir and push @listshare, { + dir => $dir, + access => $access, + right => $right, + options => $options, + }; + } +} + +sub write_conf { + output($CONF, "# generated by drakhosts.pl\n"); + foreach my $a (@listshare) { + append_to_file($CONF, "$a->{dir} $a->{access}($a->{right}) $a->{options}\n"); + } +} + +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. + +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. +"); + +my $help_userid = N(""); + +my $help_global = N(""); + +sub help_b { + my ($tittle, $help_data) = @_; + gtksignal_connect(new Gtk2::Button(N("Help")), clicked => sub { + my $dialog = new Gtk2::Dialog(); + $dialog->set_title("Help"); + $dialog->set_modal(1); + gtkpack_($dialog->vbox, + 0, gtkadd(Gtk2::Frame->new(N($tittle)), + gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), + 0, $help_data, + ), + ), + ); + $dialog->show_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, $all_right, $anonuid, $anongid, $options); + my ($lr, $luserid, $lsecure, $lsync); + undef $i; + undef $iter; + + map { $_ = Gtk2::Entry->new } $dir, $access, $anongid, $anonuid, $options; + map { $_ = Gtk2::OptionMenu->new() } $lr, $luserid, $lsecure, $lsync; + my $luserid = new Gtk2::OptionMenu(); + + $luserid->set_popdown_strings(@listuserid); + $lr->set_popdown_strings(@listr); + $lsync->set_popdown_strings(@listsync); + $lsecure->set_popdown_strings(@listsecure); + + my $file_dialog = $fdwidget->($dir, ""); + my $button = Gtk2::Button->new(N("dir path")); + $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_modal(1); + $dialog->set_resizable(1); + + if ($wanted =~ /modify/) { + $iter = $selection->get_selected; + my $path = $model->get_path($iter); + $i = ($path->get_indices)[0]; + $dir->set_text($listshare[$i]{dir}); + $access->set_text($listshare[$i]{access}); + # list of all rigth in bracket + # $anongid, $anonuid, $lr, $luserid, $lsecure, $lsync; + $right = $listshare[$i]{right}; + my @opts = split(/,/, $right); + map { $_->set_text("") } $lr, $lsync, $anonuid, $anongid, $luserid, $lsecure; + + foreach my $opt (@opts) { + if ($opt =~ m/(\bro\b|\brw\b)/) { + $lr->set_text($opt); + } elsif ($opt =~ m/\bsync\b|\basync\b/) { + $lsync->set_text($opt); + } elsif ($opt =~ m/anongid=(\d+)/) { + $anongid->set_text($1); + } elsif ($opt =~ m/anonuid=(\d+)/) { + $anonuid->set_text($1); + } 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); + } else { next } + } + } + + gtkpack_($dialog->vbox, + 0, gtkadd(Gtk2::Frame->new(N("NFS directory")), + gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), + 0, $label_and_widgets->(N("Directory:"), $dir, $button), + ), + ), + 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("Help User ID", $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("Help User ID", $help_userid)), + 0, $label_and_widgets->(N("anonuid:"), $anonuid, ""), + 0, $label_and_widgets->(N("anongid:"), $anongid, ""), + ), + ), + 0, gtkadd(Gtk2::Frame->new(N("General Options")), + gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), + 0, $label_and_widgets->(N("Force sync:"), $lsync, help_b("Help General options", $help_global)), + 0, $label_and_widgets->(N("port below 1024:"), $lsecure, ""), + 0, $label_and_widgets->(N("Read/Write request:"), $lr, ""), + ), + ), + 0, gtkadd(Gtk2::Frame->new(N("More Options")), + gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5), + 0, $label_and_widgets->(N("options:"), $options, ""), + ), + ), + 0, create_okcancel({ + cancel_clicked => sub { $dialog->destroy }, + ok_clicked => sub { + my ($anonu, $anong); + $anonuid->get_text() and $anonu = "anonuid=" . $anonuid->get_text(); + $anongid->get_text() and $anong = "anongid=" . $anongid->get_text(); + map { $_ and $all_right = $_ . "," . $all_right; } $luserid->get_text(), $anonu, $anong, $lsync->get_text(), $lsecure->get_text(), $lr->get_text(); + if ($wanted =~ /add/) { + -d $dir->get_text() or err_dialog(N("Error!"), N("Please enter a directory to share.")) and return; + $iter = $model->append; + $i = "-1"; + push @listshare, { + dir => $dir->get_text(), + access => $access->get_text(), + right => $all_right, + options => $options->get_text(), + }; + } + $listshare[$i]{right} = $all_right; + $listshare[$i]{access} = $access->get_text(); + $listshare[$i]{dir} = $dir->get_text(); + $listshare[$i]{options} = $options->get_text(); + $model->set($iter, + COLUMN_DIR, $listshare[$i]{dir}, + COLUMN_ACCESS, $listshare[$i]{access}, + COLUMN_RIGHT, $all_right, + COLUMN_OPTIONS, $listshare[$i]{options}, + ); + $dialog->destroy; + write_conf(); + }, + }, + ), + ); + $dialog->show_all; +} + +sub remove_entry { + my ($widget, $treeview) = @_; + my $model = $treeview->get_model; + my $selection = $treeview->get_selection; + my $iter = $selection->get_selected; + if ($iter) { + my $path = $model->get_path($iter); + my $i = ($path->get_indices)[0]; + ask_okcancel("Remove entry ?", "Remove $listshare[$i]{dir}") or return; + $model->remove($iter); + splice @listshare, $i, 1; + } + write_conf(); +} + +sub create_model() { + get_nfs_data(); + my $model = Gtk2::ListStore->new("Glib::String", "Glib::String", "Glib::String", "Glib::String"); + foreach my $a (@listshare) { + my $iter = $model->append; + $model->set($iter, + COLUMN_DIR, $a->{dir}, + COLUMN_ACCESS, $a->{access}, + COLUMN_RIGHT, $a->{right}, + COLUMN_OPTIONS, $a->{options}, + ), + } + return $model; +} + +# add colum to model +sub add_columns { + my $treeview = shift; + my $model = $treeview->get_model; + 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"); +} + + +############### +# 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; +my $W = $window->{window}; +$W->signal_connect(delete_event => sub { ugtk2->exit }); + +my $treeview = Gtk2::TreeView->new_with_model($model); +$treeview->set_rules_hint(TRUE); +$treeview->get_selection->set_mode('single'); +add_columns($treeview); + +my $okcancel = create_okcancel({ + cancel_clicked => sub { ugtk2->exit }, + ok_clicked => \&write_conf, + }, + ); + +# main interface +$W->add(gtkpack_(Gtk2::VBox->new(0,0), + 1, create_scrolled_window($treeview), + 0, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 3), + 0, gtksignal_connect(Gtk2::Button->new(N("Add an NFS share")), 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 an NFS share")), 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 an NFS share")), 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), + ), + ); + +$W->show_all; +Gtk2->main; |