From 043c04163b5ecf74bf0b3b775533c4e77b72a3d0 Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Wed, 25 Apr 2007 10:08:29 +0000 Subject: re-sync after the big svn loss --- bin/drakroam | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100755 bin/drakroam (limited to 'bin') diff --git a/bin/drakroam b/bin/drakroam new file mode 100755 index 0000000..5511e76 --- /dev/null +++ b/bin/drakroam @@ -0,0 +1,238 @@ +#!/usr/bin/perl + +# drakroam: wireless network roaming GUI +# Austin Acton, 2004 +# Olivier Blin, 2005 +# 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::ethernet; +use network::monitor; +use network::network; +use network::tools; +use network::wireless; + +my $in = 'interactive'->vnew('su'); + +my $arg_ap; +/^--ap=(.*)/ and $arg_ap = $1 foreach @ARGV; + +my $wireless_device = detect_devices::get_wireless_interface(); + +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", + N("Signal strength") => "pixbuf", + '' => "pixbuf", + N("Encryption") => "text", + N("Operating Mode") => "text", +); +$wireless_list->get_selection->set_mode('single'); + +my ($dbus, $monitor); +eval { $dbus = dbus_object::system_bus() }; +eval { $monitor = network::monitor->new($dbus) } if $dbus; +my $wireless_networks = {}; +my $has_roaming; + +my %pixbufs = + ( + state => { map { $_ => gtkcreate_pixbuf($_) } qw(connected disconnected refresh) }, + 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, $has_roaming) = network::monitor::list_wireless($monitor, $wireless_device); + @{$wireless_list->{data}} = (); + + my $routes = network::tools::get_routes(); + my $connected = exists $routes->{$wireless_device}{network}; + + while (my ($ap, $network) = each(%$wireless_networks)) { + push @{$wireless_list->{data}}, [ + $ap, + $network->{current} ? $connected ? $pixbufs{state}{connected} : $pixbufs{state}{refresh} : undef, + $network->{essid} || exists $net->{wireless}{$ap} && $net->{wireless}{$ap}{WIRELESS_ESSID} || "[$ap]", + $pixbufs{link_level}{$network->{approx_level}}, + $network->{flags} ? $pixbufs{keyring} : undef, + $network->{flags}, + $network->{mode}, + ]; + } + 1; +} + +sub configure_ap { + my ($ap) = @_; + my $network = $wireless_networks->{$ap}; + my $essid = $network->{essid}; + my $wireless_net = + $essid && exists $net->{wireless}{$essid} ? + $net->{wireless}{$essid} : + exists $net->{wireless}{$ap} ? + $net->{wireless}{$ap} : + {}; + $wireless_net->{WIRELESS_ESSID} = $essid if $essid; + + 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}); + $wireless_enc_mode = $network->{flags} =~ /wpa/i ? 'wpa-psk' : $network->{flags} =~ /wep/i ? $wireless_restricted ? 'restricted' : '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\"", $essid || $ap) + }, + [ + { label => N("Network name (ESSID)"), val => \$wireless_net->{WIRELESS_ESSID}, disabled => sub { $essid } }, + { 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} = $wireless_enc_key && network::wireless::convert_wep_key_for_iwconfig($wireless_enc_key, $wireless_enc_mode eq 'restricted'); + $wireless_net->{WIRELESS_MODE} = $network->{mode} eq 'Ad-Hoc' ? $network->{mode} : 'Managed'; + + if ($has_roaming || $wireless_enc_mode eq 'wpa-psk') { + $wireless_net->{WIRELESS_WPA_DRIVER} = network::wireless::wpa_supplicant_get_driver($wireless_module); + network::wireless::wpa_supplicant_add_network($wireless_net->{WIRELESS_ESSID}, $wireless_enc_mode, $wireless_enc_key); + } else { + delete $wireless_net->{WIRELESS_WPA_DRIVER}; + } + + my $ssid = $essid || $ap; + $net->{wireless}{$ssid} = $wireless_net; + + network::network::write_wireless_conf($ssid, $wireless_net); + + if ($has_roaming) { + #- this should be handled by the monitoring daemon instead + run_program::run('/usr/sbin/wpa_cli', 'reconfigure'); + } else { + overwrite_wireless_ifcfg($wireless_net); + } + + 1; +} + +sub overwrite_wireless_ifcfg { + my ($wireless_net) = @_; + my $ifcfg = $net->{ifcfg}{$wireless_device} ||= {}; + delete $ifcfg->{$_} foreach grep { /wireless/i } keys %$ifcfg; + put_in_hash($ifcfg, $wireless_net); + network::network::write_interface_conf($net, $wireless_device); +} + +sub wait_and_run_sub { + my ($time, $sub) = @_; + gtkset_mousecursor_wait(); + Glib::Timeout->add($time, sub { + $sub->(); + gtkset_mousecursor_normal(); + 0; + }); +} + +sub connect_to_ap { + my ($ap, $o_disable_configure) = @_; + my $network = $wireless_networks->{$ap}; + my $found; + + if ($network) { + my $wireless_net = !$has_roaming && ($net->{wireless}{$ap} || $net->{wireless}{$network->{essid}}); + if (defined $network->{id}) { + eval { $monitor->select_network($network->{id}) }; + $found = !$@; + $found or ugtk2::err_dialog(N("Wireless connection"), N("Unable to contact daemon")); + } elsif ($wireless_net) { + network::tools::stop_interface($wireless_device, 0); + overwrite_wireless_ifcfg($wireless_net); + network::tools::start_interface($wireless_device, 1); + $found = 1; + } + } + + $found || !$o_disable_configure or return; + + if (!$found) { + if ($has_roaming) { + configure_ap($ap); + #- wait for wpa_supplicant to reconfigure the device + wait_and_run_sub(2000, sub { connect_to_ap($ap, 1) }); + return; + } else { + network::tools::stop_interface($wireless_device, 0); + configure_ap($ap); + network::tools::start_interface($wireless_device, 0); + } + } + wait_and_run_sub(10000, \&update_networks); +} + +sub configure_selected() { + my ($selected) = $wireless_list->get_selected_indices or return; + configure_ap($wireless_list->{data}[$selected][0]); +} + +sub connect_to_selected() { + my ($selected) = $wireless_list->get_selected_indices or return; + connect_to_ap($wireless_list->{data}[$selected][0]); +} + +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 => 500, 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 }) + ]), + ]), + ]), + ); + +$arg_ap and Glib::Timeout->add(100, sub { connect_to_ap($arg_ap); 0 }); + +$w->main; -- cgit v1.2.1