#!/usr/bin/perl # DrakConnect $Id: drakconnect 239415 2008-03-14 11:06:49Z blino $ # Copyright (C) 1999-2006 Mandriva # Damien "Dam's" Krotkine # Damien "poulpy" Chaumette # Thierry Vignaud # # 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. use strict; use lib qw(/usr/lib/libDrakX); # i18n: IMPORTANT: to get correct namespace (drakx-net instead of libDrakX) BEGIN { unshift @::textdomains, 'drakx-net' } use standalone; #- warning, standalone must be loaded very first, for 'explanations' use common; use interactive; use ugtk3 qw(:create :dialogs :helpers :wrappers); use mygtk3 qw(gtknew); use network::netconnect; use network::connection::ethernet; require_root_capability(); $ugtk3::wm_icon = "drakconnect"; my $in = 'interactive'->vnew; my $net = {}; network::network::read_net_conf($net); my $modules_conf = modules::any_conf->read; my @all_cards; my $window1 = ugtk3->new(N("Network configuration (%d adapters)", scalar @all_cards)); $window1->{rwindow}->signal_connect(delete_event => sub { ugtk3->exit(0) }); unless ($::isEmbedded) { $window1->{rwindow}->set_position('center'); $window1->{rwindow}->set_size_request(-1, -1); } $window1->{rwindow}->set_border_width(10); my $button_apply; my $hostname = chomp_(`hostname`); my $tree_model = Gtk3::TreeStore->new("Gtk3::Gdk::Pixbuf", map { "Glib::String" } 2..6); my $list = Gtk3::TreeView->new_with_model($tree_model); $list->append_column(Gtk3::TreeViewColumn->new_with_attributes("", Gtk3::CellRendererPixbuf->new, 'pixbuf' => 0)); each_index { $list->append_column(my $col = Gtk3::TreeViewColumn->new_with_attributes($_, Gtk3::CellRendererText->new, 'text' => $::i + 1)); $col->set_sort_column_id($::i); } (N("Interface"), N("IP address"), N("Protocol"), N("Driver"), N("State")); $list->signal_connect(button_press_event => sub { my (undef, $event) = @_; my (undef, $iter) = $list->get_selection->get_selected; return unless $iter; configure_lan() if $event->type eq '2button-press'; }); update_list($modules_conf); my $label_host; $window1->{window}->add( gtkpack__(Gtk3::VBox->new(0,10), gtkpack(Gtk3::HBox->new, Gtk3::Label->new(N("Hostname: ")), $label_host = Gtk3::Label->new($hostname), gtksignal_connect(Gtk3::Button->new(N("Configure hostname...")), clicked => sub { local ($::isWizard, $::Wizard_finished) = (1, 1); eval { # For wizcancel network::netconnect::real_main($net, $in, $modules_conf); $button_apply->set_sensitive(1); update(); }; if ($@ =~ /wizcancel/) {} $::WizardWindow->destroy; undef $::WizardWindow; } ), ), gtkadd(gtkcreate_frame(N("LAN configuration")), gtkpack_(gtkset_border_width(Gtk3::VBox->new(0,0), 5), 0, $list, 0, Gtk3::HBox->new(0,0), 0, gtkpack_(Gtk3::HBox->new(0, 0), 0, gtksignal_connect(Gtk3::Button->new(N("Configure Local Area Network...")), clicked => \&configure_lan), ), ) ), gtkpack(Gtk3::HButtonBox->new, gtksignal_connect(Gtk3::Button->new(N("Help")), clicked => sub { run_program::raw({ detach => 1 }, 'drakhelp', '--id', 'internet-connection') }), $button_apply = gtksignal_connect(gtkset_sensitive(Gtk3::Button->new(N("Apply")), 0), clicked => \&apply), gtksignal_connect(Gtk3::Button->new(N("Cancel")), clicked => \&quit_global), gtksignal_connect(Gtk3::Button->new(N("Ok")), clicked => sub { if ($button_apply->get('sensitive')) { my $dialog = _create_dialog(N("Please wait")); gtkpack($dialog->get_child, Gtk3::Label->new(N("Please Wait... Applying the configuration"))); $dialog->show_all; gtkflush(); apply(); $dialog->destroy; } update(); quit_global(); }), ), ), ); $window1->{rwindow}->show_all; gtkflush(); $window1->main; ugtk3->exit(0); sub quit_global() { ugtk3->exit(0); } sub get_intf_status { my ($c) = @_; ethisup($c) ? N("Deactivate now") : N("Activate now"); } my %intf; sub update_list { my ($modules_conf) = @_; @all_cards = network::connection::ethernet::get_eth_cards($modules_conf); my %new_intf = map { @$_ } @all_cards; my @new_intf = sort keys %new_intf; foreach my $interface (difference2(\@new_intf, [ keys %intf ])) { $intf{$interface} = $tree_model->append(undef); } foreach my $interface (@new_intf) { my ($ip, $state) = get_intf_ip($interface); $tree_model->set($intf{$interface}, map_index { $::i => $_ } (gtkcreate_pixbuf("eth_card_mini2"), $interface, $ip , $net->{ifcfg}{$interface}{BOOTPROTO}, $new_intf{$interface}, $state)); } foreach my $i (difference2([ keys %intf ], \@new_intf)) { $tree_model->remove($intf{$i}); delete $intf{$i}; } } sub update() { my $h = chomp_(`hostname`); $label_host->set_label($h); update_list($modules_conf); 1; } sub configure_lan() { my $window = _create_dialog(N("LAN configuration")); my @card_tab; if (@all_cards < 1) { $window->get_child->add(Gtk3::Label->new(N("You do not have any configured interface. Configure them first by clicking on 'Configure'"))); gtkpack(gtkset_layout($window->get_action_area, 'end'), gtksignal_connect(Gtk3::Button->new(N("Ok")), clicked => sub { Gtk3->main_quit }) ); $window->show_all; $window->run; $window->destroy; return; } $window->set_border_width(10); gtkpack($window->get_child, Gtk3::Label->new(N("LAN Configuration")), my $notebook = Gtk3::Notebook->new, ); foreach (0..$#all_cards) { my @infos; my @conf_data; $card_tab[2*$_] = \@infos; $card_tab[2*$_+1] = \@conf_data; my $vbox_local = Gtk3::VBox->new(0,0); $vbox_local->set_border_width(10); $vbox_local->pack_start(Gtk3::Label->new(N("Adapter %s: %s", $_+1 , $all_cards[$_][0])),1,1,0); # Eth${_}Hostname = $netc->{HOSTNAME} # Eth${_}HostAlias = " . do { $netc->{HOSTNAME} =~ /([^\.]*)\./; $1 } . " # Eth${_}Driver = $all_cards[$_]->[1] my $interface = $all_cards[$_][0]; my ($ip, undef, $mask) = get_intf_ip($interface); $mask ||= $net->{ifcfg}{$interface}{NETMASK}; @conf_data = ([ N("IP address"), \$ip ], [ N("Netmask"), \$mask ], [ N("Boot Protocol"), \$net->{ifcg}{$interface}{BOOTPROTO}, ["static", "dhcp", "bootp"] ], [ N("Started on boot"), \$net->{ifcg}{$interface}{ONBOOT} , ["yes", "no"] ], [ N("DHCP client"), \$net->{ifcfg}{$interface}{DHCP_CLIENT} ] ); my $i = 0; my $size_group = Gtk3::SizeGroup->new('horizontal'); foreach my $j (@conf_data) { my $l = Gtk3::Label->new($j->[0]); $l->set_justify('left'); $infos[2*$i] = gtkpack_(Gtk3::HBox->new, 1, $l); $vbox_local->pack_start($infos[2*$i], 1, 1, 0); my $c; if (defined $j->[2]) { $c = Gtk3::ComboBoxText->new; $c->set_popdown_strings(@{$j->[2]}); $infos[2*$i+1] = $c->entry; $infos[2*$i]->pack_start($c,0,0,0); } else { $infos[2*$i+1] = ($c = Gtk3::Entry->new); $infos[2*$i]->pack_start($infos[2*$i+1],0,0,0); } $size_group->add_widget($c); $infos[2*$i+1]->set_text(${$j->[1]}); $i++; } my $widget_temp; if (-e "/etc/sysconfig/network-scripts/ifcfg-$interface") { $widget_temp = gtksignal_connect(Gtk3::Button->new(get_intf_status($interface)), clicked => sub { system("/sbin/if" . (ethisup($interface) ? "down" : "up") . " $interface"); $_[0]->set_label(get_intf_status($interface)); update(); }); } else { $widget_temp = N("This interface has not been configured yet.\nRun the \"%s\" assistant from the Mageia Linux Control Center", N("Set up a new network interface (LAN, ISDN, ADSL, ...)")); } $vbox_local->pack_start(gtkpack__(Gtk3::HBox->new(0,0), $widget_temp ),0,0,0); # $list->append($_+1, $interface, $intf->{$interface}{IPADDR}, $intf->{$interface}{BOOTPROTO}, $all_cards[$_]->[1]); # $list->set_selectable($_, 0); $notebook->append_page($vbox_local, Gtk3::Label->new($interface)); } my $exit_dialogsub = sub { $window->destroy; Gtk3->main_quit; }; gtkpack($window->get_action_area, gtksignal_connect(Gtk3::Button->new(N("Cancel")), clicked => $exit_dialogsub), gtksignal_connect(Gtk3::Button->new(N("Ok")), clicked => sub { foreach (0..$#all_cards) { my @infos = @{$card_tab[2*$_]}; each_index { ${$_->[1]} = $infos[2*$::i+1]->get_text } @{$card_tab[2*$_+1]}; my $interface = $all_cards[$_][0]; if ($net->{ifcfg}{$interface}{BOOTPROTO} ne "static") { delete @{$net->{ifcfg}{$interface}}{qw(IPADDR NETWORK NETMASK BROADCAST)}; } else { if ($infos[1]->get_text ne N("No IP")) { $net->{ifcfg}{$interface}{IPADDR} = $infos[1]->get_text; $net->{ifcfg}{$interface}{NETMASK} = $infos[3]->get_text; } } } update(); $button_apply->set_sensitive(1); $exit_dialogsub->(); }), ); $window->show_all; foreach (0..$#all_cards) { my @infos = @{$card_tab[2*$_]}; $net->{ifcfg}{$all_cards[$_][0]}{BOOTPROTO} eq "dhcp" or $infos[8]->hide; } $window->run; } sub apply() { network::network::configure_network($net, $in, $modules_conf); } sub ethisup { `LC_ALL=C LANGUAGE=C /sbin/ifconfig $_[0]` =~ /inet/ } # FIXME: duplicated with drakconnect sub get_intf_ip { my ($interface) = @_; my ($ip, $state, $mask); if (-x "/sbin/ifconfig") { local $_ = `LC_ALL=C LANGUAGE=C /sbin/ifconfig $interface`; $ip = /inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/mso ? $1 : N("No IP"); $mask = /Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/mso ? $1 : N("No Mask"); $state = /inet/ ? N("up") : N("down"); } else { $ip = $net->{ifcfg}{$interface}{IPADDR}; $state = "n/a"; } ($ip, $state, $mask); }