#!/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 (drakhosts instead of libDrakX) BEGIN { unshift @::textdomains, 'drakhosts' } use lib qw(/usr/lib/libDrakX); use standalone; use strict; use common; use network::network; use interactive; 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\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 = _create_dialog(); $dialog->set_transient_for($::main_window); $dialog->set_title("Drakhosts $wanted entry"); $dialog->set_modal(1); $dialog->set_resizable(1); $dialog->set_size_request(300, -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 %s information", $wanted)), 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"); $::main_window = $window->{real_window}; $window->{rwindow}->set_size_request(500, 400) 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); $treeview->signal_connect(button_press_event => sub { my (undef, $event) = @_; 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]; add_modify_entry($model, $treeview, "modify") if $event->type eq '2button-press'; } }); my $okcancel = create_okcancel({ cancel_clicked => sub { ugtk2->exit }, ok_clicked => sub { write_conf_hosts; ugtk2->exit; }, }, ); # main interface $W->add(gtkpack_(Gtk2::VBox->new(0,0), if_(!$::isEmbedded, 0, Gtk2::Banner->new('drakgw', N("DrakHOSTS manage hosts definitions"))), if_($::isEmbedded, 0, Gtk2::Label->new("Here you can add, remove and alter NFS shares.")), 1, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 0), 1, create_scrolled_window($treeview), 0, gtkpack_(gtkset_border_width(create_vbox('start', 3)), 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 host.") . "\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 host.") . "\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 host.") . "\n\n" . $err); } }), 0, gtksignal_connect(Gtk2::Button->new(N("Apply")), clicked => sub { write_conf_hosts(); }), if_($::isEmbedded, 0, gtksignal_connect(Gtk2::Button->new(N("Quit")), clicked => sub { ugtk2->exit })), ), ), 0, $okcancel, ), ); $W->show_all; Gtk2->main;