#!/usr/bin/perl # drakroam: wireless network roaming GUI # Austin Acton, 2004 <austin@mandriva.org> # Olivier Blin, 2005 <oblin@mandriva.com> # Licensed under the GPL use strict; use lib qw(/usr/lib/libDrakX); use standalone; use common; use run_program; use detect_devices; use interactive; use mygtk2; use ugtk2 qw(:create :helpers :wrappers); use Gtk2::SimpleList; use network::monitor; use network::wireless; use network::network; use network::ethernet; my $in = 'interactive'->vnew('su'); my $wireless_device = find { detect_devices::is_wireless_interface($_) } detect_devices::getNet(); unless ($wireless_device) { ugtk2::err_dialog(N("Error"), N("You do not have any wireless interface. Run the \"%s\" assistant from the Mandriva Linux Control Center", N("Set up a new network interface (LAN, ISDN, ADSL, ...)"))); ugtk2::exit(0) if !$::testing; } my $modules_conf = modules::any_conf->read; my $dev = find { $_->[0] eq $wireless_device } network::ethernet::get_eth_cards($modules_conf); my $wireless_module = $dev->[1]; my $net = {}; network::network::read_net_conf($net); my $wireless_list = Gtk2::SimpleList->new( "AP" => "hidden", '' => "pixbuf", N("SSID") => "text", '' => "pixbuf", N("Encryption") => "text", N("Signal strength") => "pixbuf" ); $wireless_list->get_selection->set_mode('single'); my $dbus = dbus_object::system_bus(); my $monitor = network::monitor->new($dbus); my $wireless_networks = {}; my %pixbufs = ( state => { map { $_ => gtkcreate_pixbuf($_) } qw(connected disconnected) }, link_level => { map { $_ => gtkcreate_pixbuf('wifi-' . sprintf('%03d', $_) . '.png')->scale_simple(24, 24, 'hyper'); } qw(20 40 60 80 100) }, keyring => gtkcreate_pixbuf("/usr/share/pixmaps/keyring-small.png")->scale_simple(24, 24, 'hyper'), #- provided by usermode, required by drakxtools ); sub update_networks() { $wireless_networks = $monitor->list_wireless; @{$wireless_list->{data}} = (); while (my ($ap, $network) = each(%$wireless_networks)) { push @{$wireless_list->{data}}, [ $ap, $network->{current} ? $pixbufs{state}{connected} : undef, $network->{ssid} || $ap, $network->{flags} ? $pixbufs{keyring} : undef, $network->{flags}, $pixbufs{link_level}{$network->{approx_level}} ]; } 1; } sub configure_selected() { my ($selected) = $wireless_list->get_selected_indices or return; my $ap = $wireless_list->{data}[$selected][0]; my $network = $wireless_networks->{$ap}; my $ssid = $network->{ssid}; my $wireless_net = $ssid && exists $net->{wireless}{$ssid} ? $net->{wireless}{$ssid} : exists $net->{wireless}{$ap} ? $net->{wireless}{$ap} : {}; $wireless_net->{WIRELESS_ESSID} = $ssid if $ssid; my ($wireless_enc_mode, $wireless_enc_key, $wireless_restricted); ($wireless_enc_key, $wireless_restricted) = network::wireless::get_wep_key_from_iwconfig($wireless_net->{WIRELESS_ENC_KEY}); #- FIXME: handle restricted $wireless_enc_mode = $network->{flags} =~ /wpa/i ? 'wpa-psk' : $network->{flags} =~ /wep/i ? 'open' : 'none'; my $dhcp = to_bool(!exists($wireless_net->{BOOTPROTO}) || $wireless_net->{BOOTPROTO} eq "dhcp"); $in->ask_from_({ title => "Wireless settings", messages => N("Please enter settings for wireless network \"%s\"", $ssid || $ap) }, [ { label => N("Network name (ESSID)"), val => \$wireless_net->{WIRELESS_ESSID}, disabled => sub { $ssid } }, { label => N("Encryption mode"), val => \$wireless_enc_mode, list => [ keys %network::wireless::wireless_enc_modes ], sort => 1, format => sub { translate($network::wireless::wireless_enc_modes{$_[0]}) } }, { label => N("Encryption key"), val => \$wireless_enc_key, disabled => sub { $wireless_enc_mode eq 'none' } }, { text => N("Automatic IP (BOOTP/DHCP)"), val => \$dhcp, type => 'bool' }, { label => N("IP address"), val => \$wireless_net->{IPADDR}, disabled => sub { $dhcp } }, { label => N("DNS server"), val => \$wireless_net->{MS_DNS1}, disabled => sub { $dhcp } }, { label => N("Gateway IP address"), val => \$wireless_net->{GATEWAY}, disabled => sub { $dhcp } }, ], ) or return; $wireless_net->{BOOTPROTO} = $dhcp ? 'dhcp' : 'static'; $wireless_net->{WIRELESS_ENC_KEY} = network::wireless::convert_wep_key_for_iwconfig($wireless_enc_key, $wireless_enc_mode eq 'restricted'); $wireless_net->{WIRELESS_WPA_DRIVER} = network::wireless::wpa_supplicant_get_driver($wireless_module); my $wireless_file = "/etc/sysconfig/network-scripts/wireless.d/" . ($ssid || $ap); network::network::write_interface_settings($wireless_net, $wireless_file); network::wireless::wpa_supplicant_add_network($wireless_net->{WIRELESS_ESSID}, $wireless_enc_mode, $wireless_enc_key); system('/usr/sbin/wpa_cli reconfigure'); #- this should be handled by the monitoring daemon instead 1; } sub connect_to_selected() { my ($selected) = $wireless_list->get_selected_indices or return; my $ap = $wireless_list->{data}[$selected][0]; my $network = $wireless_networks->{$ap}; if (defined $network->{id}) { eval { $monitor->select_network($network->{id}) }; $@ and err_dialog(N("Wireless connection"), N("Unable to contact daemon")); } else { configure_selected(); #- apply config in wpa_supplicant and retry } gtkset_mousecursor_wait(); Glib::Timeout->add(5000, sub { update_networks(); gtkset_mousecursor_normal(); 0; }); } update_networks(); Glib::Timeout->add(30000, \&update_networks); my $w = ugtk2->new(N("Wireless connection")); gtkadd($w->{window}, gtknew('VBox', spacing => 5, children => [ $::isEmbedded ? () : (0, Gtk2::Banner->new('/usr/share/mcc/themes/default/drakroam-mdk.png', N("Wireless connection"))), 1, gtknew('HBox', spacing => 5, children => [ 1, gtknew('ScrolledWindow', width => 420, height => 300, child => $wireless_list), 0, gtknew('VButtonBox', layout => 'edge', children_loose => [ gtknew('Button', text => N("Configure"), clicked => \&configure_selected), gtknew('Button', text => N("Connect"), clicked => \&connect_to_selected), gtknew('Button', text => N("Refresh"), clicked => \&update_networks), gtknew('Button', text => N("Quit"), clicked => sub { Gtk2->main_quit }) ]), ]), ]), ); $w->main;