From ba3bc2afc2f3d4baec8b001ac9cc93e309c8b39a Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Tue, 16 Dec 2008 00:48:47 -0500 Subject: [PATCH 1/6] Only show valid wpa_supplicant drivers in the GUI. Don't needlessly created PreferenceDialog objects. Use dbus signals to alert the UI that the daemon is back up, instead of polling. --- wicd/backends/be-external.py | 4 + wicd/backends/be-ioctl.py | 4 + wicd/gui.py | 29 +++--- wicd/networking.py | 5 + wicd/prefs.py | 178 +++++++++++++++++++---------------- wicd/wicd-client.py | 24 ++--- wicd/wicd-daemon.py | 13 ++- wicd/wnettools.py | 10 ++ 8 files changed, 149 insertions(+), 118 deletions(-) diff --git a/wicd/backends/be-external.py b/wicd/backends/be-external.py index 024e0fa..801574d 100644 --- a/wicd/backends/be-external.py +++ b/wicd/backends/be-external.py @@ -98,6 +98,10 @@ def GetWiredInterfaces(*args, **kargs): """ Call the wnettools GetWiredInterfaces method. """ return wnettools.GetWiredInterfaces(*args, **kargs) +def IsValidWpaSuppDriver(*args, **kargs): + """ Call the wnettools IsValidWpaSuppDrive method. """ + return wnettools.IsValidWpaSuppDriver(*args, **kargs) + def NeedsExternalCalls(*args, **kargs): """ Return True, since this backend using iwconfig/ifconfig. """ return True diff --git a/wicd/backends/be-ioctl.py b/wicd/backends/be-ioctl.py index 18c1a94..b8d22ec 100644 --- a/wicd/backends/be-ioctl.py +++ b/wicd/backends/be-ioctl.py @@ -102,6 +102,10 @@ def GetWiredInterfaces(*args, **kargs): """ Call the wnettools GetWiredInterfaces method. """ return wnettools.GetWiredInterfaces(*args, **kargs) +def IsValidWpaSuppDriver(*args, **kargs): + """ Call the wnettools IsValidWpaSuppDrive method. """ + return wnettools.IsValidWpaSuppDriver(*args, **kargs) + def get_iw_ioctl_result(iface, call): """ Makes the given ioctl call and returns the results. diff --git a/wicd/gui.py b/wicd/gui.py index 261ed1b..7d9bbe7 100644 --- a/wicd/gui.py +++ b/wicd/gui.py @@ -85,21 +85,7 @@ def handle_no_dbus(from_tray=False): if from_tray: return False print "Wicd daemon is shutting down!" error(None, "The wicd daemon has shut down, the UI will not function properly until it is restarted.") - _wait_for_dbus() return False - -@misc.threaded -def _wait_for_dbus(): - global DBUS_AVAIL - while True: - time.sleep(10) - print "Trying to reconnect.." - if not setup_dbus(force=False): - print "Failed to reconnect to the daemon." - else: - print "Successfully reconnected to the daemon." - DBUS_AVAIL = True - return def error(parent, message): """ Shows an error dialog """ @@ -284,6 +270,7 @@ class appGui(object): self.first_dialog_load = True self.is_visible = True self.pulse_active = False + self.pref = None self.standalone = standalone self.wpadrivercombo = None self.connecting = False @@ -305,6 +292,8 @@ class appGui(object): if standalone: bus.add_signal_receiver(handle_no_dbus, "DaemonClosing", "org.wicd.daemon") + bus.add_signal_receiver(lambda: setup_dbus(force=False), + "DaemonStarting", "org.wicd.daemon") try: gobject.timeout_add_seconds(1, self.update_statusbar) except: @@ -384,10 +373,14 @@ class appGui(object): def settings_dialog(self, widget, event=None): """ Displays a general settings dialog. """ - pref = PreferencesDialog(self.wTree, dbusmanager.get_dbus_ifaces()) - if pref.run() == 1: - pref.save_results() - pref.hide() + if not self.pref: + self.pref = PreferencesDialog(self.wTree, + dbusmanager.get_dbus_ifaces()) + else: + self.pref.load_preferences_diag() + if self.pref.run() == 1: + self.pref.save_results() + self.pref.hide() def connect_hidden(self, widget): """ Prompts the user for a hidden network, then scans for it. """ diff --git a/wicd/networking.py b/wicd/networking.py index 11adcbf..b20be29 100644 --- a/wicd/networking.py +++ b/wicd/networking.py @@ -528,6 +528,11 @@ class Wireless(Controller): """ Get the out of iwconfig. """ return self.wiface.GetIwconfig() + def GetWpaSupplicantDrivers(self, drivers): + """ Returns all valid wpa_supplicant drivers in a list. """ + return [driver for driver in drivers if + BACKEND.IsValidWpaSuppDriver(driver)] + def IsUp(self): """ Calls the IsUp method for the wireless interface. diff --git a/wicd/prefs.py b/wicd/prefs.py index 23f18db..95a517f 100644 --- a/wicd/prefs.py +++ b/wicd/prefs.py @@ -27,6 +27,8 @@ handles recieving/sendings the settings from/to the daemon. import gtk import gobject import pango +import os +import gtk.glade from wicd import misc from wicd import wpath @@ -54,87 +56,28 @@ class PreferencesDialog(object): wireless = dbus['wireless'] wired = dbus['wired'] self.wTree = wTree + self.wpadrivers = None self.prep_settings_diag() - self.build_preferences_diag() + self.load_preferences_diag() - def build_preferences_diag(self): - """ Builds the preferences dialog window. """ - def build_combobox(lbl): - """ Sets up a ComboBox using the given widget name. """ - liststore = gtk.ListStore(gobject.TYPE_STRING) - combobox = self.wTree.get_widget(lbl) - combobox.clear() - combobox.set_model(liststore) - cell = gtk.CellRendererText() - combobox.pack_start(cell, True) - combobox.add_attribute(cell, 'text', 0) - return combobox + def load_preferences_diag(self): + """ Loads data into the preferences Dialog. """ - def setup_label(name, lbl=""): - """ Sets up a label for the given widget name. """ - widget = self.wTree.get_widget(name) - if lbl: - widget.set_label(language[lbl]) - return widget - - self.dialog = self.wTree.get_widget("pref_dialog") - self.dialog.set_title(language['preferences']) - if os.path.exists(os.path.join(wpath.images, "wicd.png")): - self.dialog.set_icon_from_file(os.path.join(wpath.images, "wicd.png")) - size = daemon.ReadWindowSize("pref") - width = size[0] - height = size[1] - if width > -1 and height > -1: - self.dialog.resize(int(width), int(height)) - else: - self.dialog.resize(gtk.gdk.screen_width() / 3, - gtk.gdk.screen_height() / 2) - - self.wiredcheckbox = setup_label("pref_always_check", - 'wired_always_on') self.wiredcheckbox.set_active(daemon.GetAlwaysShowWiredInterface()) - self.reconnectcheckbox = setup_label("pref_auto_check", - 'auto_reconnect') self.reconnectcheckbox.set_active(daemon.GetAutoReconnect()) - self.debugmodecheckbox = setup_label("pref_debug_check", - 'use_debug_mode') self.debugmodecheckbox.set_active(daemon.GetDebugMode()) - self.displaytypecheckbox = setup_label("pref_dbm_check", - 'display_type_dialog') self.displaytypecheckbox.set_active(daemon.GetSignalDisplayType()) - self.usedefaultradiobutton = setup_label("pref_use_def_radio", - 'use_default_profile') - self.showlistradiobutton = setup_label("pref_prompt_radio", - 'show_wired_list') - self.lastusedradiobutton = setup_label("pref_use_last_radio", - 'use_last_used_profile') - # DHCP Clients - self.dhcpautoradio = setup_label("dhcp_auto_radio", "wicd_auto_config") - self.dhclientradio = self.wTree.get_widget("dhclient_radio") - self.pumpradio = self.wTree.get_widget("pump_radio") - self.dhcpcdradio = self.wTree.get_widget("dhcpcd_radio") dhcp_list = [self.dhcpautoradio, self.dhclientradio, self.dhcpcdradio, self.pumpradio] - dhcp_method = daemon.GetDHCPClient() dhcp_list[dhcp_method].set_active(True) - # Wired Link Detection Apps - self.linkautoradio = setup_label("link_auto_radio", 'wicd_auto_config') - self.linkautoradio = setup_label("link_auto_radio") - self.ethtoolradio = setup_label("ethtool_radio") - self.miitoolradio = setup_label("miitool_radio") wired_link_list = [self.linkautoradio, self.ethtoolradio, self.miitoolradio] wired_link_method = daemon.GetLinkDetectionTool() wired_link_list[wired_link_method].set_active(True) - - # Route Flushing Apps - self.flushautoradio = setup_label("flush_auto_radio", - 'wicd_auto_config') - self.ipflushradio = setup_label("ip_flush_radio") - self.routeflushradio = setup_label("route_flush_radio") + flush_list = [self.flushautoradio, self.ipflushradio, self.routeflushradio] flush_method = daemon.GetFlushTool() @@ -148,16 +91,9 @@ class PreferencesDialog(object): elif auto_conn_meth == 3: self.lastusedradiobutton.set_active(True) - self.entryWirelessInterface = self.wTree.get_widget("pref_wifi_entry") self.entryWirelessInterface.set_text(daemon.GetWirelessInterface()) - - self.entryWiredInterface = self.wTree.get_widget("pref_wired_entry") self.entryWiredInterface.set_text(daemon.GetWiredInterface()) - # Replacement for the combo box hack - self.wpadrivercombo = build_combobox("pref_wpa_combobox") - self.wpadrivers = ["wext", "hostap", "madwifi", "atmel", "ndiswrapper", - "ipw", "ralink legacy"] found = False def_driver = daemon.GetWPADriver() for i, x in enumerate(self.wpadrivers): @@ -175,14 +111,6 @@ class PreferencesDialog(object): # Use wext as default, since normally it is the correct driver. self.wpadrivercombo.set_active(0) - # Set up global DNS stuff - self.useGlobalDNSCheckbox = setup_label("pref_global_check", - 'use_global_dns') - self.searchDomEntry = self.wTree.get_widget("pref_search_dom_entry") - self.dns1Entry = self.wTree.get_widget("pref_dns1_entry") - self.dns2Entry = self.wTree.get_widget("pref_dns2_entry") - self.dns3Entry = self.wTree.get_widget("pref_dns3_entry") - self.useGlobalDNSCheckbox.connect("toggled", checkboxTextboxToggle, (self.dns1Entry, self.dns2Entry, self.dns3Entry, self.searchDomEntry)) @@ -201,7 +129,6 @@ class PreferencesDialog(object): self.dns3Entry.set_sensitive(False) # Load backend combobox - self.backendcombo = build_combobox("pref_backend_combobox") self.backends = daemon.GetBackendList() # "" is included as a hack for DBus limitations, so we remove it. self.backends.remove("") @@ -229,9 +156,12 @@ class PreferencesDialog(object): """ Hides the preferences dialog window. """ self.dialog.hide() + def destroy(self): + self.dialog.destroy() + def show_all(self): """ Shows the preferences dialog window. """ - self.show_all() + self.dialog.show() def save_results(self): """ Pushes the selected settings to the daemon. """ @@ -290,6 +220,24 @@ class PreferencesDialog(object): def prep_settings_diag(self): """ Set up anything that doesn't have to be persisted later. """ + def build_combobox(lbl): + """ Sets up a ComboBox using the given widget name. """ + liststore = gtk.ListStore(gobject.TYPE_STRING) + combobox = self.wTree.get_widget(lbl) + combobox.clear() + combobox.set_model(liststore) + cell = gtk.CellRendererText() + combobox.pack_start(cell, True) + combobox.add_attribute(cell, 'text', 0) + return combobox + + def setup_label(name, lbl=""): + """ Sets up a label for the given widget name. """ + widget = self.wTree.get_widget(name) + if lbl: + widget.set_label(language[lbl]) + return widget + # External Programs tab self.wTree.get_widget("gen_settings_label").set_label(language["gen_settings"]) self.wTree.get_widget("ext_prog_label").set_label(language["ext_programs"]) @@ -312,3 +260,71 @@ class PreferencesDialog(object): self.set_label("pref_wifi_label", "%s:" % language['wireless_interface']) self.set_label("pref_wired_label", "%s:" % language['wired_interface']) self.set_label("pref_driver_label", "%s:" % language['wpa_supplicant_driver']) + + self.dialog = self.wTree.get_widget("pref_dialog") + self.dialog.set_title(language['preferences']) + if os.path.exists(os.path.join(wpath.images, "wicd.png")): + self.dialog.set_icon_from_file(os.path.join(wpath.images, "wicd.png")) + size = daemon.ReadWindowSize("pref") + width = size[0] + height = size[1] + if width > -1 and height > -1: + self.dialog.resize(int(width), int(height)) + else: + self.dialog.resize(gtk.gdk.screen_width() / 3, + gtk.gdk.screen_height() / 2) + + self.wiredcheckbox = setup_label("pref_always_check", + 'wired_always_on') + + self.reconnectcheckbox = setup_label("pref_auto_check", + 'auto_reconnect') + self.debugmodecheckbox = setup_label("pref_debug_check", + 'use_debug_mode') + self.displaytypecheckbox = setup_label("pref_dbm_check", + 'display_type_dialog') + self.usedefaultradiobutton = setup_label("pref_use_def_radio", + 'use_default_profile') + self.showlistradiobutton = setup_label("pref_prompt_radio", + 'show_wired_list') + self.lastusedradiobutton = setup_label("pref_use_last_radio", + 'use_last_used_profile') + + + # DHCP Clients + self.dhcpautoradio = setup_label("dhcp_auto_radio", "wicd_auto_config") + self.dhclientradio = self.wTree.get_widget("dhclient_radio") + self.pumpradio = self.wTree.get_widget("pump_radio") + self.dhcpcdradio = self.wTree.get_widget("dhcpcd_radio") + + # Wired Link Detection Apps + self.linkautoradio = setup_label("link_auto_radio", 'wicd_auto_config') + self.linkautoradio = setup_label("link_auto_radio") + self.ethtoolradio = setup_label("ethtool_radio") + self.miitoolradio = setup_label("miitool_radio") + + # Route Flushing Apps + self.flushautoradio = setup_label("flush_auto_radio", + 'wicd_auto_config') + self.ipflushradio = setup_label("ip_flush_radio") + self.routeflushradio = setup_label("route_flush_radio") + + # Replacement for the combo box hack + self.wpadrivercombo = build_combobox("pref_wpa_combobox") + self.wpadrivers = ["wext", "hostap", "madwifi", "atmel", + "ndiswrapper", "ipw"] + self.wpadrivers = wireless.GetWpaSupplicantDrivers(self.wpadrivers) + self.wpadrivers.append("ralink_legacy") + + self.entryWirelessInterface = self.wTree.get_widget("pref_wifi_entry") + self.entryWiredInterface = self.wTree.get_widget("pref_wired_entry") + + # Set up global DNS stuff + self.useGlobalDNSCheckbox = setup_label("pref_global_check", + 'use_global_dns') + self.searchDomEntry = self.wTree.get_widget("pref_search_dom_entry") + self.dns1Entry = self.wTree.get_widget("pref_dns1_entry") + self.dns2Entry = self.wTree.get_widget("pref_dns2_entry") + self.dns3Entry = self.wTree.get_widget("pref_dns3_entry") + + self.backendcombo = build_combobox("pref_backend_combobox") \ No newline at end of file diff --git a/wicd/wicd-client.py b/wicd/wicd-client.py index 96d484c..37528ae 100755 --- a/wicd/wicd-client.py +++ b/wicd/wicd-client.py @@ -642,7 +642,7 @@ Arguments: def setup_dbus(force=True): global bus, daemon, wireless, wired, DBUS_AVAIL - + print "Connecting to daemon..." try: dbusmanager.connect_to_dbus() except DBusException: @@ -653,7 +653,7 @@ def setup_dbus(force=True): dbusmanager.connect_to_dbus() except DBusException: gui.error(None, "Could not connect to wicd's D-Bus interface. " + - "Check the wicd log for error messages.") + "Check the wicd log for error messages.") return False else: return False @@ -664,6 +664,7 @@ def setup_dbus(force=True): wireless = dbus_ifaces['wireless'] wired = dbus_ifaces['wired'] DBUS_AVAIL = True + print "Connected." return True @@ -674,23 +675,8 @@ def handle_no_dbus(): print "Wicd daemon is shutting down!" gui.error(None, "The wicd daemon has shut down, the UI will not function " + "properly until it is restarted.") - _wait_for_dbus() return False -@misc.threaded -def _wait_for_dbus(): - global DBUS_AVAIL - while True: - time.sleep(10) - print "Trying to reconnect.." - if not setup_dbus(force=False): - print "Failed to reconnect to the daemon." - else: - print "Successfully reconnected to the daemon." - gui.setup_dbus(force=False) - DBUS_AVAIL = True - return - def main(argv): """ The main frontend program. @@ -750,7 +736,9 @@ def main(argv): 'SendStartScanSignal', 'org.wicd.daemon.wireless') bus.add_signal_receiver(lambda: handle_no_dbus() or tray_icon.icon_info.set_not_connected_state(), "DaemonClosing", 'org.wicd.daemon') - print 'Done.' + bus.add_signal_receiver(lambda: setup_dbus(force=False), "DaemonStarting", + "org.wicd.daemon") + print 'Done loading.' mainloop = gobject.MainLoop() mainloop.run() diff --git a/wicd/wicd-daemon.py b/wicd/wicd-daemon.py index 5d3ee1b..4b2e8c5 100644 --- a/wicd/wicd-daemon.py +++ b/wicd/wicd-daemon.py @@ -113,7 +113,8 @@ class WicdDaemon(dbus.service.Object): self.wired.wiface = self.wifi.wiface signal.signal(signal.SIGTERM, self.DaemonClosing) - + self.DaemonStarting() + # Scan since we just got started if auto_connect: print "autoconnecting if needed...", str(self.GetWirelessInterface()) @@ -705,6 +706,11 @@ class WicdDaemon(dbus.service.Object): print 'calling wired profile chooser' self.SetNeedWiredProfileChooser(True) + @dbus.service.signal(dbus_interface="org.wicd.daemon", signature='') + def DaemonStarting(self): + """ Emits a signa indicating the daemon is starting. """ + pass + @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='') def DaemonClosing(self): """ Emits a signal indicating the daemon will be closing. """ @@ -1122,6 +1128,11 @@ class WirelessDaemon(dbus.service.Object): essid_key = "essid:" + str(self.LastScan[networkid]) self.config.remove_section(essid_key) + @dbus.service.method('org.wicd.daemon.wireless') + def GetWpaSupplicantDrivers(self, drivers): + """ Returns all valid wpa_supplicant drivers in a given list. """ + return self.wifi.GetWpaSupplicantDrivers(drivers) + @dbus.service.method('org.wicd.daemon.wireless') def ReloadConfig(self): """ Reloads the active config file. """ diff --git a/wicd/wnettools.py b/wicd/wnettools.py index 8bb4f64..0a0b9c2 100644 --- a/wicd/wnettools.py +++ b/wicd/wnettools.py @@ -131,6 +131,16 @@ def NeedsExternalCalls(): """ Returns True if the backend needs to use an external program. """ raise NotImplementedError + +def IsValidWpaSuppDriver(driver): + """ Returns True if given string is a valid wpa_supplicant driver. """ + output = misc.Run(["wpa_supplicant", "-D%s" % driver, "-iwlan9", + "-c/etc/zzzzzzzz.confzzz"]) + if re.match("Unsupported driver", output): + return False + else: + return True + class BaseInterface(object): """ Control a network interface. """ From 556c40ad75a0e947f91e59593c3438b3f0e2c687 Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Tue, 16 Dec 2008 01:19:26 -0500 Subject: [PATCH 2/6] Make gui.error() calls optionally not block. Make the lost dbus error message translatable. --- wicd/gui.py | 20 ++++++++++++-------- wicd/misc.py | 2 ++ wicd/wicd-client.py | 3 +-- wicd/wicd-daemon.py | 5 ++++- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/wicd/gui.py b/wicd/gui.py index 7d9bbe7..91a685a 100644 --- a/wicd/gui.py +++ b/wicd/gui.py @@ -84,24 +84,28 @@ def handle_no_dbus(from_tray=False): DBUS_AVAIL = False if from_tray: return False print "Wicd daemon is shutting down!" - error(None, "The wicd daemon has shut down, the UI will not function properly until it is restarted.") + error(None, language['lost_dbus'], block=False) return False - -def error(parent, message): + +def error(parent, message, block=True): """ Shows an error dialog """ dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK) dialog.set_markup(message) - dialog.run() - dialog.destroy() + if not block: + dialog.present() + dialog.connect("response", lambda *args: dialog.destroy()) + else: + dialog.run() + dialog.destroy() def alert(parent, message): - """ Shows an error dialog """ + """ Shows an warning dialog """ dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK) dialog.set_markup(message) - dialog.run() - dialog.destroy() + dialog.present() + dialog.connect("response", lambda *args: dialog.destroy()) def dummy(x=None):pass diff --git a/wicd/misc.py b/wicd/misc.py index a3c01e2..a65fc4e 100644 --- a/wicd/misc.py +++ b/wicd/misc.py @@ -511,6 +511,7 @@ def get_language_list_gui(): language['cannot_start_daemon'] = _("Unable to connect to wicd daemon DBus interface." + \ "This typically means there was a problem starting the daemon." + \ "Check the wicd log for more info") + language['lost_dbus'] = _("The wicd daemon has shut down, the UI will not function properly until it is restarted.") return language @@ -536,6 +537,7 @@ def get_language_list_tray(): "This typically means there was a problem starting the daemon." + \ "Check the wicd log for more info") language['no_daemon_tooltip'] = _("Wicd daemon unreachable") + language['lost_dbus'] = _("The wicd daemon has shut down, the UI will not function properly until it is restarted.") return language def noneToBlankString(text): diff --git a/wicd/wicd-client.py b/wicd/wicd-client.py index 37528ae..40114de 100755 --- a/wicd/wicd-client.py +++ b/wicd/wicd-client.py @@ -673,8 +673,7 @@ def handle_no_dbus(): DBUS_AVAIL = False gui.handle_no_dbus(from_tray=True) print "Wicd daemon is shutting down!" - gui.error(None, "The wicd daemon has shut down, the UI will not function " + - "properly until it is restarted.") + gui.error(None, language['lost_dbus'], block=False) return False def main(argv): diff --git a/wicd/wicd-daemon.py b/wicd/wicd-daemon.py index 4b2e8c5..150d81e 100644 --- a/wicd/wicd-daemon.py +++ b/wicd/wicd-daemon.py @@ -1571,7 +1571,10 @@ def sigterm_caught(sig=None, frame=None): global child_pid if child_pid: print 'Daemon going down, killing wicd-monitor...' - os.kill(child_pid, signal.SIGTERM) + try: + os.kill(child_pid, signal.SIGTERM) + except OSError: + pass print 'Removing PID file...' if os.path.exists(wpath.pidfile): os.remove(wpath.pidfile) From 69d2cd2d7737780dd1f1a237602d6b0a17aca711 Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Tue, 16 Dec 2008 01:30:46 -0500 Subject: [PATCH 3/6] Fix non-blocking error dialog. --- wicd/gui.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wicd/gui.py b/wicd/gui.py index 91a685a..9ecb8f6 100644 --- a/wicd/gui.py +++ b/wicd/gui.py @@ -89,12 +89,14 @@ def handle_no_dbus(from_tray=False): def error(parent, message, block=True): """ Shows an error dialog """ + def delete_event(dialog, id): + dialog.destroy() dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK) dialog.set_markup(message) if not block: dialog.present() - dialog.connect("response", lambda *args: dialog.destroy()) + dialog.connect("response", delete_event) else: dialog.run() dialog.destroy() From a82b53309e583a588a9f3bdd7954ed71a4740799 Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Sun, 21 Dec 2008 00:19:18 -0500 Subject: [PATCH 4/6] Checkpoint for work on getting reasons for connection failure back up to the UI. --- wicd/gui.py | 15 ++++-- wicd/monitor.py | 2 + wicd/networking.py | 112 +++++++++++++++++++++++++++++--------------- wicd/wicd-daemon.py | 53 +++++++++++++++------ 4 files changed, 124 insertions(+), 58 deletions(-) diff --git a/wicd/gui.py b/wicd/gui.py index 9ecb8f6..d1d5203 100644 --- a/wicd/gui.py +++ b/wicd/gui.py @@ -295,17 +295,22 @@ class appGui(object): 'org.wicd.daemon.wireless') bus.add_signal_receiver(self.update_connect_buttons, 'StatusChanged', 'org.wicd.daemon') - if standalone: - bus.add_signal_receiver(handle_no_dbus, "DaemonClosing", - "org.wicd.daemon") - bus.add_signal_receiver(lambda: setup_dbus(force=False), - "DaemonStarting", "org.wicd.daemon") + bus.add_signal_receiver(self.handle_connection_results, + 'ConnectResultsSent', 'org.wicd.daemon') + bus.add_signal_receiver(handle_no_dbus, "DaemonClosing", + "org.wicd.daemon") + bus.add_signal_receiver(lambda: setup_dbus(force=False), + "DaemonStarting", "org.wicd.daemon") try: gobject.timeout_add_seconds(1, self.update_statusbar) except: gobject.timeout_add(1000, self.update_statusbar) self.refresh_clicked() + + def handle_connection_results(self, results): + if results != "Success" and self.is_visible: + error(self.window, results, block=False) def create_adhoc_network(self, widget=None): """ Shows a dialog that creates a new adhoc network. """ diff --git a/wicd/monitor.py b/wicd/monitor.py index b875b10..27b2f1a 100755 --- a/wicd/monitor.py +++ b/wicd/monitor.py @@ -146,6 +146,8 @@ class ConnectionStatus(object): state = misc.CONNECTING self.update_state(state) return True + + daemon.SendConnectResultsIfAvail() # Check for wired. wired_ip = wired.GetWiredIP("") diff --git a/wicd/networking.py b/wicd/networking.py index b20be29..813f2a9 100644 --- a/wicd/networking.py +++ b/wicd/networking.py @@ -57,6 +57,22 @@ if __name__ == '__main__': BACKEND = None BACKEND_MGR = BackendManager() +def abortable(func): + """ Mark a method in a ConnectionThread as abortable. + + This decorator runs a check that will abort the connection thread + if necessary before running a given method. + + """ + def wrapper(self, *__args, **__kargs): + self.abort_if_needed() + return func(self, *__args, **__kargs) + + wrapper.__name__ = func.__name__ + wrapper.__dict__ = func.__dict__ + wrapper.__doc__ = func.__doc__ + return wrapper + def get_backend_list(): if BACKEND_MGR: return BACKEND_MGR.get_available_backends() @@ -96,6 +112,7 @@ class Controller(object): self.driver = None self.wiface = None self.liface = None + self.iface = None self.backend_manager = BackendManager() def set_wireless_iface(self, value): @@ -155,6 +172,9 @@ class Controller(object): return self._backend.NeedsExternalCalls() else: return True + + def StopDHCP(self): + return self.iface.StopDHCP() class ConnectThread(threading.Thread): @@ -194,12 +214,13 @@ class ConnectThread(threading.Thread): self.wired_interface = wired self.is_connecting = False self.is_aborted = False - self.abort_msg = None + self.connect_result = None self.before_script = before_script self.after_script = after_script self.disconnect_script = disconnect_script self._should_die = False self.abort_reason = "" + self.connect_result = "" self.global_dns_1 = gdns1 self.global_dns_2 = gdns2 @@ -251,6 +272,7 @@ class ConnectThread(threading.Thread): self.lock.release() return message + @abortable def reset_ip_addresses(self, wiface, liface): """ Resets the IP addresses for both wired/wireless interfaces. @@ -262,13 +284,15 @@ class ConnectThread(threading.Thread): self.SetStatus('resetting_ip_address') wiface.SetAddress('0.0.0.0') liface.SetAddress('0.0.0.0') - + + @abortable def put_iface_down(self, iface): """ Puts the given interface down. """ print 'Putting interface down' self.SetStatus('interface_down') iface.Down() + @abortable def run_script_if_needed(self, script, msg): """ Execute a given script if needed. @@ -280,21 +304,24 @@ class ConnectThread(threading.Thread): if script: print 'Executing %s script' % (msg) misc.ExecuteScript(script) - + + @abortable def flush_routes(self, wiface, liface): """ Flush the routes for both wired/wireless interfaces. """ self.SetStatus('flushing_routing_table') print 'Flushing the routing table...' wiface.FlushRoutes() liface.FlushRoutes() - + + @abortable def set_broadcast_address(self, iface): """ Set the broadcast address for the given interface. """ if not self.network.get('broadcast') == None: self.SetStatus('setting_broadcast_address') print 'Setting the broadcast address...' + self.network['broadcast'] iface.SetAddress(broadcast=self.network['broadcast']) - + + @abortable def set_ip_address(self, iface): """ Set the IP address for the given interface. @@ -315,7 +342,8 @@ class ConnectThread(threading.Thread): if dhcp_status in ['no_dhcp_offers', 'dhcp_failed']: self.abort_connection(dhcp_status) return - + + @abortable def set_dns_addresses(self): """ Set the DNS address(es). @@ -336,6 +364,20 @@ class ConnectThread(threading.Thread): self.network.get('dns3'), self.network.get('search_domain')) + @abortable + def release_dhcp_clients(self, wiface, liface): + """ Release all running dhcp clients. """ + print "Releasing DHCP leases..." + wiface.ReleaseDHCP() + liface.ReleaseDHCP() + + @abortable + def stop_dhcp_clients(self, iface): + """ Stop and running DHCP clients, as well as wpa_supplicant. """ + print 'Stopping wpa_supplicant and any DHCP clients' + iface.StopWPA() + BACKEND.StopDHCP() + def connect_aborted(self, reason): """ Sets the thread status to aborted in a thread-safe way. @@ -347,7 +389,7 @@ class ConnectThread(threading.Thread): reason = self.abort_reason self.connecting_message = reason self.is_aborted = True - self.abort_msg = reason + self.connect_result = reason self.is_connecting = False print 'exiting connection thread' @@ -356,18 +398,6 @@ class ConnectThread(threading.Thread): self.abort_reason = reason self.should_die = True - def release_dhcp_clients(self, wiface, liface): - """ Release all running dhcp clients. """ - print "Releasing DHCP leases..." - wiface.ReleaseDHCP() - liface.ReleaseDHCP() - - def stop_dhcp_clients(self, iface): - """ Stop and running DHCP clients, as well as wpa_supplicant. """ - print 'Stopping wpa_supplicant and any DHCP clients' - iface.StopWPA() - BACKEND.StopDHCP() - def abort_if_needed(self): """ Abort the thread is it has been requested. """ self.lock.acquire() @@ -377,7 +407,8 @@ class ConnectThread(threading.Thread): thread.exit() finally: self.lock.release() - + + @abortable def put_iface_up(self, iface): """ Bring up given interface. """ print 'Putting interface up...' @@ -397,11 +428,15 @@ class Wireless(Controller): self._wpa_driver = value if self.wiface: self.SetWPADriver(value) - def get_wpa_driver(self): return self._wpa_driver - wpa_driver = property(get_wpa_driver, set_wpa_driver) + def set_iface(self, value): + self.wiface = value + def get_iface(self): + return self.wiface + iface = property(get_iface, set_iface) + def LoadBackend(self, backend): """ Load a given backend. @@ -541,6 +576,9 @@ class Wireless(Controller): """ return self.wiface.IsUp() + + def StopWPA(self): + return self.wiface.StopWPA() def CreateAdHocNetwork(self, essid, channel, ip, enctype, key, enc_used, ics): @@ -632,6 +670,7 @@ class Wireless(Controller): misc.ExecuteScript(self.disconnect_script) wiface.ReleaseDHCP() + wiface.StopWPA() wiface.SetAddress('0.0.0.0') wiface.Down() wiface.Up() @@ -699,17 +738,13 @@ class WirelessConnectThread(ConnectThread): self.is_connecting = True # Run pre-connection script. - self.abort_if_needed() self.run_script_if_needed(self.before_script, 'pre-connection') - self.abort_if_needed() # Take down interface and clean up previous connections. self.put_iface_down(wiface) - self.abort_if_needed() self.release_dhcp_clients(wiface, liface) self.reset_ip_addresses(wiface, liface) self.stop_dhcp_clients(wiface) - self.abort_if_needed() self.flush_routes(wiface, liface) # Generate PSK and authenticate if needed. @@ -717,10 +752,8 @@ class WirelessConnectThread(ConnectThread): self.generate_psk_and_authenticate(wiface) # Put interface up. - self.abort_if_needed() self.SetStatus('configuring_interface') self.put_iface_up(wiface) - self.abort_if_needed() # Associate. wiface.SetMode(self.network['mode']) @@ -737,24 +770,23 @@ class WirelessConnectThread(ConnectThread): self.SetStatus('validating_authentication') if not wiface.ValidateAuthentication(time.time()): self.abort_connection('bad_pass') - self.abort_if_needed() # Set up gateway, IP address, and DNS servers. self.set_broadcast_address(wiface) - self.abort_if_needed() self.set_ip_address(wiface) self.set_dns_addresses() # Run post-connection script. - self.abort_if_needed() self.run_script_if_needed(self.after_script, 'post-connection') self.SetStatus('done') print 'Connecting thread exiting.' if self.debug: print "IP Address is: " + str(wiface.GetIP()) + self.connect_result = "Success" self.is_connecting = False - + + @abortable def generate_psk_and_authenticate(self, wiface): """ Generates a PSK and authenticates if necessary. @@ -799,6 +831,12 @@ class Wired(Controller): def get_link_detect(self): return self._link_detect link_detect = property(get_link_detect, set_link_detect) + def set_iface(self, value): + self.liface = value + def get_iface(self): + return self.liface + iface = property(get_iface, set_iface) + def LoadBackend(self, backend): """ Load the backend up. """ Controller.LoadBackend(self, backend) @@ -831,7 +869,7 @@ class Wired(Controller): self.wiface, self.liface, debug) self.connecting_thread.setDaemon(True) self.connecting_thread.start() - return True + return self.connecting_thread def DetectWiredInterface(self): """ Attempts to automatically detect a wired interface. """ @@ -937,28 +975,22 @@ class WiredConnectThread(ConnectThread): self.is_connecting = True # Run pre-connection script. - self.abort_if_needed() self.run_script_if_needed(self.before_script, 'pre-connection') - self.abort_if_needed() # Take down interface and clean up previous connections. self.put_iface_down(liface) self.release_dhcp_clients(wiface, liface) self.reset_ip_addresses(wiface, liface) self.stop_dhcp_clients(wiface) - self.abort_if_needed() self.flush_routes(wiface, liface) # Bring up interface. self.put_iface_up(liface) - self.abort_if_needed() # Set gateway, IP adresses, and DNS servers. self.set_broadcast_address(liface) - self.abort_if_needed() self.set_ip_address(liface) self.set_dns_addresses() - self.abort_if_needed() # Run post-connection script. self.run_script_if_needed(self.after_script, 'post-connection') @@ -967,4 +999,6 @@ class WiredConnectThread(ConnectThread): print 'Connecting thread exiting.' if self.debug: print "IP Address is: " + str(liface.GetIP()) + + self.connect_result = "Success" self.is_connecting = False diff --git a/wicd/wicd-daemon.py b/wicd/wicd-daemon.py index 150d81e..7d7a047 100644 --- a/wicd/wicd-daemon.py +++ b/wicd/wicd-daemon.py @@ -83,8 +83,9 @@ class WicdDaemon(dbus.service.Object): self.wired = networking.Wired() self.config = ConfigManager(os.path.join(wpath.etc, "manager-settings.conf")) - self.wired_bus= WiredDaemon(bus_name, wired=self.wired, wifi=self.wifi) - self.wireless_bus = WirelessDaemon(bus_name, wired=self.wired, + self.wired_bus= WiredDaemon(bus_name, self, wired=self.wired, + wifi=self.wifi) + self.wireless_bus = WirelessDaemon(bus_name, self, wired=self.wired, wifi=self.wifi) self.forced_disconnect = False self.need_profile_chooser = False @@ -321,8 +322,6 @@ class WicdDaemon(dbus.service.Object): def GetAutoReconnect(self): """ Returns the value of self.auto_reconnect. See SetAutoReconnect. """ do = bool(self.auto_reconnect) - return self.__printReturn('returning automatically reconnect when ' \ - + 'connection drops', do) @dbus.service.method('org.wicd.daemon') def SetAutoReconnect(self, value): @@ -358,9 +357,12 @@ class WicdDaemon(dbus.service.Object): print 'canceling connection attempt' if self.wifi.connecting_thread: self.wifi.connecting_thread.should_die = True + self.wifi.StopDHCP() + self.wifi.StopWPA() if self.wired.connecting_thread: self.wired.connecting_thread.should_die = True - misc.Run("killall dhclient dhclient3 wpa_supplicant") + self.wired.StopDHCP() + #misc.Run("killall dhclient pump dhcpcd-bin dhclient3 wpa_supplicant") @dbus.service.method('org.wicd.daemon') def GetCurrentInterface(self): @@ -699,7 +701,33 @@ class WicdDaemon(dbus.service.Object): return False self.auto_connecting = False return False + + @dbus.service.method("org.wicd.daemon") + def ConnectResultsAvailable(self): + if ((self.wired.connecting_thread and self.wired.connecting_thread.connect_result) or + (self.wifi.connecting_thread and self.wifi.connecting_thread.connect_result)): + return True + else: + return False + + @dbus.service.method("org.wicd.daemon") + def SendConnectResultsIfAvail(self): + if self.ConnectResultsAvailable(): + self.SendConnectResult() + @dbus.service.method("org.wicd.daemon") + def SendConnectResult(self): + if self.wired.connecting_thread and self.wired.connecting_thread.connect_result: + self.ConnectResultsSent(self.wired.connecting_thread.connect_result) + self.wired.connecting_thread.connect_result = "" + elif self.wifi.connecting_thread and self.wifi.connecting_thread.connect_result: + self.ConnectResultsSent(self.wifi.connecting_thread.connect_result) + self.wifi.connecting_thread.connect_result = "" + + @dbus.service.signal(dbus_interface="org.wicd.daemon",signature='s') + def ConnectResultsSent(self, result): + print "Sending connectiong attempt result %s" % result + @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='') def LaunchChooser(self): """ Emits the wired profile chooser dbus signal. """ @@ -731,12 +759,6 @@ class WicdDaemon(dbus.service.Object): """ pass - def __printReturn(self, text, value): - """ Prints the specified text and value, then returns the value. """ - if self.debug_mode: - print ''.join([text, " ", str(value)]) - return value - def ReadConfig(self): """ Reads the manager-settings.conf file. @@ -823,11 +845,12 @@ class WicdDaemon(dbus.service.Object): class WirelessDaemon(dbus.service.Object): """ DBus interface for wireless connection operations. """ - def __init__(self, bus_name, wired=None, wifi=None, debug=False): + def __init__(self, bus_name, daemon, wired=None, wifi=None, debug=False): """ Intitialize the wireless DBus interface. """ dbus.service.Object.__init__(self, bus_name=bus_name, object_path='/org/wicd/daemon/wireless') self.hidden_essid = None + self.daemon = daemon self.wired = wired self.wifi = wifi self.debug_mode = debug @@ -1012,7 +1035,7 @@ class WirelessDaemon(dbus.service.Object): self.wifi.disconnect_script = self.GetWirelessProperty(id, 'disconnectscript') print 'Connecting to wireless network ' + self.LastScan[id]['essid'] - return self.wifi.Connect(self.LastScan[id], debug=self.debug_mode) + conthread = self.wifi.Connect(self.LastScan[id], debug=self.debug_mode) @dbus.service.method('org.wicd.daemon.wireless') def CheckIfWirelessConnecting(self): @@ -1174,10 +1197,11 @@ class WirelessDaemon(dbus.service.Object): class WiredDaemon(dbus.service.Object): """ DBus interface for wired connection operations. """ - def __init__(self, bus_name, wired=None, wifi=None, debug=False): + def __init__(self, bus_name, daemon, wired=None, wifi=None, debug=False): """ Intitialize the wireless DBus interface. """ dbus.service.Object.__init__(self, bus_name=bus_name, object_path="/org/wicd/daemon/wired") + self.daemon = daemon self.wired = wired self.wifi = wifi self.debug_mode = debug @@ -1587,4 +1611,5 @@ if __name__ == '__main__': print ("Root privileges are required for the daemon to run properly." + " Exiting.") sys.exit(1) + gobject.threads_init() main(sys.argv) From 16aad93febc4bdc5162d2c8377797272b681fba7 Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Mon, 22 Dec 2008 00:05:19 -0500 Subject: [PATCH 5/6] More work on bubbling the reason for connection failures up to the UI. Refactor Wireless/Wired classes in networking module and daemon so that they don't need to reference each other. Wired objects don't know about Wireless objects and vice versa. This also means connecting to a wired/wireless network will only clear the connection on whichever network type you're connecting to. --- wicd/gui.py | 4 +- wicd/misc.py | 3 +- wicd/networking.py | 319 +++++++++++++++++--------------------------- wicd/wicd-daemon.py | 27 ++-- 4 files changed, 134 insertions(+), 219 deletions(-) diff --git a/wicd/gui.py b/wicd/gui.py index d1d5203..2957166 100644 --- a/wicd/gui.py +++ b/wicd/gui.py @@ -309,8 +309,8 @@ class appGui(object): self.refresh_clicked() def handle_connection_results(self, results): - if results != "Success" and self.is_visible: - error(self.window, results, block=False) + if results not in ['Success', 'aborted'] and self.is_visible: + error(self.window, language[results], block=False) def create_adhoc_network(self, widget=None): """ Shows a dialog that creates a new adhoc network. """ diff --git a/wicd/misc.py b/wicd/misc.py index a65fc4e..d7e65e7 100644 --- a/wicd/misc.py +++ b/wicd/misc.py @@ -504,8 +504,9 @@ def get_language_list_gui(): language['setting_static_ip'] = _('Setting static IP addresses...') language['running_dhcp'] = _('Obtaining IP address...') language['dhcp_failed'] = _('Connection Failed: Unable to Get IP Address') + language['no_dhcp_offers'] = _('Connection Failed: No DHCP offers received.') language['aborted'] = _('Connection Cancelled') - language['bad_pass'] = _('Connection Failed: Bad password') + language['bad_pass'] = _('Connection Failed: Could not authenticate (bad password?)') language['done'] = _('Done connecting...') language['scanning'] = _('Scanning') language['cannot_start_daemon'] = _("Unable to connect to wicd daemon DBus interface." + \ diff --git a/wicd/networking.py b/wicd/networking.py index 813f2a9..180da9d 100644 --- a/wicd/networking.py +++ b/wicd/networking.py @@ -99,8 +99,6 @@ class Controller(object): self.global_dns_2 = None self.global_dns_3 = None self.global_search_dom = None - self._wired_interface = None - self._wireless_interface = None self._dhcp_client = None self._flush_tool = None self._debug = None @@ -110,51 +108,29 @@ class Controller(object): self.after_script = None self.disconnect_script = None self.driver = None - self.wiface = None - self.liface = None self.iface = None - self.backend_manager = BackendManager() - - def set_wireless_iface(self, value): - self._wireless_interface = value - if self.wiface: - self.wiface.SetInterface(value) - def get_wireless_iface(self): return self._wireless_interface - wireless_interface = property(get_wireless_iface, set_wireless_iface) - - def set_wired_iface(self, value): - self._wired_interface = value - if self.liface: - self.liface.SetInterface(value) - def get_wired_iface(self): return self._wired_interface - wired_interface = property(get_wired_iface, set_wired_iface) + self.backend_manager = BackendManager() def set_debug(self, value): self._debug = value - if self.wiface: - self.wiface.SetDebugMode(value) - if self.liface: - self.liface.SetDebugMode(value) + if self.iface: + self.iface.SetDebugMode(value) def get_debug(self): return self._debug debug = property(get_debug, set_debug) def set_dhcp_client(self, value): self._dhcp_client = value - if self.wiface: - self.wiface.DHCP_CLIENT = value - self.wiface.CheckDHCP() - if self.liface: - self.liface.DHCP_CLIENT = value - self.liface.CheckDHCP() + if self.iface: + self.iface.DHCP_CLIENT = value + self.iface.CheckDHCP() + def get_dhcp_client(self): return self._dhcp_client dhcp_client = property(get_dhcp_client, set_dhcp_client) def set_flush_tool(self, value): self._flush_tool = value - if self.wiface: - self.wiface.flush_tool = value - if self.liface: - self.liface.flush_tool = value + if self.iface: + self.iface.flush_tool = value def get_flush_tool(self): return self._flush_tool flush_tool = property(get_flush_tool, set_flush_tool) @@ -174,7 +150,55 @@ class Controller(object): return True def StopDHCP(self): - return self.iface.StopDHCP() + return BACKEND.StopDHCP() + + def GetIP(self, ifconfig=""): + """ Get the IP of the interface. + + Returns: + The IP address of the interface in dotted notation. + + """ + return self.iface.GetIP(ifconfig) + + def Disconnect(self): + """ Disconnect from the network. """ + iface = self.iface + if self.disconnect_script != None: + print 'Running wired disconnect script' + misc.Run(self.disconnect_script) + + iface.ReleaseDHCP() + iface.SetAddress('0.0.0.0') + iface.Down() + iface.Up() + + def IsUp(self): + """ Calls the IsUp method for the wired interface. + + Returns: + True if the interface is up, False otherwise. + + """ + return self.iface.IsUp() + + def EnableInterface(self): + """ Puts the interface up. + + Returns: + True if the interface was put up succesfully, False otherwise. + + """ + return self.iface.Up() + + def DisableInterface(self): + """ Puts the interface down. + + Returns: + True if the interface was put down succesfully, False otherwise. + + """ + return self.iface.Down() class ConnectThread(threading.Thread): @@ -190,9 +214,9 @@ class ConnectThread(threading.Thread): should_die = False lock = thread.allocate_lock() - def __init__(self, network, wireless, wired, before_script, after_script, + def __init__(self, network, interface_name, before_script, after_script, disconnect_script, gdns1, gdns2, gdns3, gsearch_dom, - wiface, liface, debug): + iface, debug): """ Initialise the required object variables and the thread. Keyword arguments: @@ -210,8 +234,6 @@ class ConnectThread(threading.Thread): """ threading.Thread.__init__(self) self.network = network - self.wireless_interface = wireless - self.wired_interface = wired self.is_connecting = False self.is_aborted = False self.connect_result = None @@ -227,8 +249,7 @@ class ConnectThread(threading.Thread): self.global_dns_3 = gdns3 self.global_search_dom = gsearch_dom - self.wiface = wiface - self.liface = liface + self.iface = iface self.connecting_message = None self.debug = debug @@ -273,7 +294,7 @@ class ConnectThread(threading.Thread): return message @abortable - def reset_ip_addresses(self, wiface, liface): + def reset_ip_addresses(self, iface): """ Resets the IP addresses for both wired/wireless interfaces. Sets a false ip so that when we set the real one, the correct @@ -282,8 +303,7 @@ class ConnectThread(threading.Thread): """ print 'Setting false IP...' self.SetStatus('resetting_ip_address') - wiface.SetAddress('0.0.0.0') - liface.SetAddress('0.0.0.0') + iface.SetAddress('0.0.0.0') @abortable def put_iface_down(self, iface): @@ -306,12 +326,11 @@ class ConnectThread(threading.Thread): misc.ExecuteScript(script) @abortable - def flush_routes(self, wiface, liface): + def flush_routes(self, iface): """ Flush the routes for both wired/wireless interfaces. """ self.SetStatus('flushing_routing_table') print 'Flushing the routing table...' - wiface.FlushRoutes() - liface.FlushRoutes() + iface.FlushRoutes() @abortable def set_broadcast_address(self, iface): @@ -365,11 +384,10 @@ class ConnectThread(threading.Thread): self.network.get('search_domain')) @abortable - def release_dhcp_clients(self, wiface, liface): + def release_dhcp_clients(self, iface): """ Release all running dhcp clients. """ print "Releasing DHCP leases..." - wiface.ReleaseDHCP() - liface.ReleaseDHCP() + iface.ReleaseDHCP() @abortable def stop_dhcp_clients(self, iface): @@ -423,6 +441,15 @@ class Wireless(Controller): """ Initialize the class. """ Controller.__init__(self) self._wpa_driver = None + self._wireless_interface = None + self.wiface = None + + def set_wireless_iface(self, value): + self._wireless_interface = value + if self.wiface: + self.wiface.SetInterface(value) + def get_wireless_iface(self): return self._wireless_interface + wireless_interface = property(get_wireless_iface, set_wireless_iface) def set_wpa_driver(self, value): self._wpa_driver = value @@ -475,7 +502,7 @@ class Wireless(Controller): else: return 0 - if not self.wireless_interface: return [] + if not self.wiface: return [] wiface = self.wiface @@ -501,14 +528,13 @@ class Wireless(Controller): network -- network to connect to """ - if not self.wireless_interface: return False + if not self.wiface: return False self.connecting_thread = WirelessConnectThread(network, - self.wireless_interface, self.wired_interface, - self.wpa_driver, self.before_script, self.after_script, - self.disconnect_script, self.global_dns_1, + self.wireless_interface, self.wpa_driver, self.before_script, + self.after_script, self.disconnect_script, self.global_dns_1, self.global_dns_2, self.global_dns_3, self.global_search_dom, - self.wiface, self.liface, debug) + self.wiface, debug) self.connecting_thread.setDaemon(True) self.connecting_thread.start() return True @@ -539,15 +565,6 @@ class Wireless(Controller): """ return self.wiface.GetCurrentNetwork(iwconfig) - - def GetIP(self, ifconfig=""): - """ Get the IP of the interface. - - Returns: - The IP address of the interface in dotted notation. - - """ - return self.wiface.GetIP(ifconfig) def GetBSSID(self): """ Get the BSSID of the current access point. @@ -568,20 +585,11 @@ class Wireless(Controller): return [driver for driver in drivers if BACKEND.IsValidWpaSuppDriver(driver)] - def IsUp(self): - """ Calls the IsUp method for the wireless interface. - - Returns: - True if the interface is up, False otherwise. - - """ - return self.wiface.IsUp() - def StopWPA(self): return self.wiface.StopWPA() def CreateAdHocNetwork(self, essid, channel, ip, enctype, key, - enc_used, ics): + enc_used): """ Create an ad-hoc wireless network. Keyword arguments: @@ -611,34 +619,9 @@ class Wireless(Controller): wiface.SetKey(key) print 'Putting interface up' wiface.Up() - # Just assume that the netmask is 255.255.255.0, it simplifies ICS print 'Setting IP address' wiface.SetAddress(ip, '255.255.255.0') - ip_parts = misc.IsValidIP(ip) - - if ics and ip_parts: - # Set up internet connection sharing here - # Flush the forward tables - misc.Run('iptables -F FORWARD') - misc.Run('iptables -N fw-interfaces') - misc.Run('iptables -N fw-open') - misc.Run('iptables -F fw-interfaces') - misc.Run('iptables -F fw-open') - misc.Run('iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS \ - --clamp-mss-to-pmtu') - misc.Run('iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT') - misc.Run('iptables -A FORWARD -j fw-interfaces ') - misc.Run('iptables -A FORWARD -j fw-open ') - misc.Run('iptables -A FORWARD -j REJECT --reject-with icmp-host-unreachable') - misc.Run('iptables -P FORWARD DROP') - misc.Run('iptables -A fw-interfaces -i ' + self.wireless_interface + ' -j ACCEPT') - net_ip = '.'.join(ip_parts[0:3]) + '.0' - misc.Run('iptables -t nat -A POSTROUTING -s ' + net_ip + \ - '/255.255.255.0 -o ' + self.wired_interface + \ - ' -j MASQUERADE') - misc.Run('echo 1 > /proc/sys/net/ipv4/ip_forward') # Enable routing - def DetectWirelessInterface(self): """ Detect available wireless interfaces. @@ -664,24 +647,8 @@ class Wireless(Controller): Resets it's IP address, and puts the interface down then up. """ - wiface = self.wiface - if self.disconnect_script not in (None, ""): - print 'Running wireless network disconnect script' - misc.ExecuteScript(self.disconnect_script) - - wiface.ReleaseDHCP() - wiface.StopWPA() - wiface.SetAddress('0.0.0.0') - wiface.Down() - wiface.Up() - - def EnableInterface(self): - """ Puts the interface up. """ - return self.wiface.Up() - - def DisableInterface(self): - """ Puts the interface down. """ - return self.wiface.Down() + Controller.Disconnect(self) + self.StopWPA() def SetWPADriver(self, driver): """ Sets the wpa_supplicant driver associated with the interface. """ @@ -695,15 +662,14 @@ class WirelessConnectThread(ConnectThread): """ - def __init__(self, network, wireless, wired, wpa_driver, - before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3, gsearch_dom, wiface, liface, debug=False): + def __init__(self, network, wireless, wpa_driver, before_script, + after_script, disconnect_script, gdns1, gdns2, gdns3, + gsearch_dom, wiface, debug=False): """ Initialise the thread with network information. Keyword arguments: network -- the network to connect to wireless -- name of the wireless interface - wired -- name of the wired interface wpa_driver -- type of wireless interface before_script -- script to run before bringing up the interface after_script -- script to run after bringing up the interface @@ -713,9 +679,9 @@ class WirelessConnectThread(ConnectThread): gdns3 -- global DNS server 3 """ - ConnectThread.__init__(self, network, wireless, wired, - before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3, gsearch_dom, wiface, liface, debug) + ConnectThread.__init__(self, network, wireless, before_script, + after_script, disconnect_script, gdns1, gdns2, + gdns3, gsearch_dom, wiface, debug) self.wpa_driver = wpa_driver @@ -733,8 +699,7 @@ class WirelessConnectThread(ConnectThread): 5. Get/set IP address and DNS servers. """ - wiface = self.wiface - liface = self.liface + wiface = self.iface self.is_connecting = True # Run pre-connection script. @@ -742,10 +707,10 @@ class WirelessConnectThread(ConnectThread): # Take down interface and clean up previous connections. self.put_iface_down(wiface) - self.release_dhcp_clients(wiface, liface) - self.reset_ip_addresses(wiface, liface) + self.release_dhcp_clients(wiface) + self.reset_ip_addresses(wiface) self.stop_dhcp_clients(wiface) - self.flush_routes(wiface, liface) + self.flush_routes(wiface) # Generate PSK and authenticate if needed. if self.wpa_driver != 'ralink legacy': @@ -769,7 +734,8 @@ class WirelessConnectThread(ConnectThread): if self.network.get('enctype'): self.SetStatus('validating_authentication') if not wiface.ValidateAuthentication(time.time()): - self.abort_connection('bad_pass') + if not self.connect_result: + self.abort_connection('bad_pass') # Set up gateway, IP address, and DNS servers. self.set_broadcast_address(wiface) @@ -801,7 +767,7 @@ class WirelessConnectThread(ConnectThread): if self.network.get('key') and 'wpa' in self.network.get('enctype'): self.SetStatus('generating_psk') print 'Generating psk...' - self.network['psk'] = self.wiface.GeneratePSK(self.network) + self.network['psk'] = wiface.GeneratePSK(self.network) if not self.network.get('psk'): self.network['psk'] = self.network['key'] @@ -823,6 +789,8 @@ class Wired(Controller): Controller.__init__(self) self.wpa_driver = None self._link_detect = None + self._wired_interface = None + self.liface = None def set_link_detect(self, value): self._link_detect = value @@ -831,6 +799,14 @@ class Wired(Controller): def get_link_detect(self): return self._link_detect link_detect = property(get_link_detect, set_link_detect) + + def set_wired_iface(self, value): + self._wired_interface = value + if self.liface: + self.liface.SetInterface(value) + def get_wired_iface(self): return self._wired_interface + wired_interface = property(get_wired_iface, set_wired_iface) + def set_iface(self, value): self.liface = value def get_iface(self): @@ -860,13 +836,11 @@ class Wired(Controller): network -- network to connect to """ - if not self.wired_interface: return False + if not self.liface: return False self.connecting_thread = WiredConnectThread(network, - self.wireless_interface, self.wired_interface, - self.before_script, self.after_script, - self.disconnect_script, self.global_dns_1, - self.global_dns_2, self.global_dns_3, self.global_search_dom, - self.wiface, self.liface, debug) + self.wired_interface, self.before_script, self.after_script, + self.disconnect_script, self.global_dns_1, self.global_dns_2, + self.global_dns_3, self.global_search_dom, self.liface, debug) self.connecting_thread.setDaemon(True) self.connecting_thread.start() return self.connecting_thread @@ -878,54 +852,6 @@ class Wired(Controller): except IndexError: return None - def GetIP(self, ifconfig=""): - """ Get the IP of the interface. - - Returns: - The IP address of the interface in dotted notation. - - """ - return self.liface.GetIP(ifconfig) - - def Disconnect(self): - """ Disconnect from the network. """ - liface = self.liface - if self.disconnect_script != None: - print 'Running wired disconnect script' - misc.Run(self.disconnect_script) - - liface.ReleaseDHCP() - liface.SetAddress('0.0.0.0') - liface.Down() - liface.Up() - - def IsUp(self): - """ Calls the IsUp method for the wired interface. - - Returns: - True if the interface is up, False otherwise. - - """ - return self.liface.IsUp() - - def EnableInterface(self): - """ Puts the interface up. - - Returns: - True if the interface was put up succesfully, False otherwise. - - """ - return self.liface.Up() - - def DisableInterface(self): - """ Puts the interface down. - - Returns: - True if the interface was put down succesfully, False otherwise. - - """ - return self.liface.Down() - class WiredConnectThread(ConnectThread): """ A thread class to perform the connection to a wired network. @@ -934,9 +860,9 @@ class WiredConnectThread(ConnectThread): to the specified network. """ - def __init__(self, network, wireless, wired, - before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3, gsearch_dom, wiface, liface, debug=False): + def __init__(self, network, wireless, before_script, after_script, + disconnect_script, gdns1, gdns2, gdns3, gsearch_dom, liface, + debug=False): """ Initialise the thread with network information. Keyword arguments: @@ -951,9 +877,9 @@ class WiredConnectThread(ConnectThread): gdns3 -- global DNS server 3 """ - ConnectThread.__init__(self, network, wireless, wired, - before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3, gsearch_dom, wiface, liface, debug) + ConnectThread.__init__(self, network, wired, before_script, + after_script, disconnect_script, gdns1, gdns2, + gdns3, gsearch_dom, liface, debug) def run(self): """ The main function of the connection thread. @@ -969,8 +895,7 @@ class WiredConnectThread(ConnectThread): 5. Run post-connection script. """ - wiface = self.wiface - liface = self.liface + liface = self.iface self.is_connecting = True @@ -979,10 +904,10 @@ class WiredConnectThread(ConnectThread): # Take down interface and clean up previous connections. self.put_iface_down(liface) - self.release_dhcp_clients(wiface, liface) - self.reset_ip_addresses(wiface, liface) - self.stop_dhcp_clients(wiface) - self.flush_routes(wiface, liface) + self.release_dhcp_clients(liface) + self.reset_ip_addresses(liface) + self.stop_dhcp_clients(liface) + self.flush_routes(liface) # Bring up interface. self.put_iface_up(liface) diff --git a/wicd/wicd-daemon.py b/wicd/wicd-daemon.py index 7d7a047..2c75d9c 100644 --- a/wicd/wicd-daemon.py +++ b/wicd/wicd-daemon.py @@ -83,10 +83,8 @@ class WicdDaemon(dbus.service.Object): self.wired = networking.Wired() self.config = ConfigManager(os.path.join(wpath.etc, "manager-settings.conf")) - self.wired_bus= WiredDaemon(bus_name, self, wired=self.wired, - wifi=self.wifi) - self.wireless_bus = WirelessDaemon(bus_name, self, wired=self.wired, - wifi=self.wifi) + self.wired_bus= WiredDaemon(bus_name, self, wired=self.wired) + self.wireless_bus = WirelessDaemon(bus_name, self, wifi=self.wifi) self.forced_disconnect = False self.need_profile_chooser = False self.current_interface = None @@ -107,11 +105,6 @@ class WicdDaemon(dbus.service.Object): # need a fresh scan, just feed them the old one. A fresh scan # can be done by calling Scan(fresh=True). self.LastScan = '' - - # Kind of hackish way to set correct wnettools interfaces. - #TODO remove the need for this. - self.wifi.liface = self.wired.liface - self.wired.wiface = self.wifi.wiface signal.signal(signal.SIGTERM, self.DaemonClosing) self.DaemonStarting() @@ -147,7 +140,6 @@ class WicdDaemon(dbus.service.Object): """ Sets the wired interface for the daemon to use. """ print "setting wired interface %s" % (str(interface)) self.wired.wired_interface = noneToBlankString(interface) - self.wifi.wired_interface = noneToBlankString(interface) self.config.set("Settings", "wired_interface", interface, True) @dbus.service.method('org.wicd.daemon') @@ -155,7 +147,6 @@ class WicdDaemon(dbus.service.Object): """ Sets the wireless interface the daemon will use. """ print "setting wireless interface %s" % (str(interface)) self.wifi.wireless_interface = noneToBlankString(interface) - self.wired.wireless_interface = noneToBlankString(interface) self.config.set("Settings", "wireless_interface", interface, True) @dbus.service.method('org.wicd.daemon') @@ -359,10 +350,11 @@ class WicdDaemon(dbus.service.Object): self.wifi.connecting_thread.should_die = True self.wifi.StopDHCP() self.wifi.StopWPA() + self.wifi.connecting_thread.connect_result = 'aborted' if self.wired.connecting_thread: self.wired.connecting_thread.should_die = True self.wired.StopDHCP() - #misc.Run("killall dhclient pump dhcpcd-bin dhclient3 wpa_supplicant") + self.wired.connecting_thread.connect_result = 'aborted' @dbus.service.method('org.wicd.daemon') def GetCurrentInterface(self): @@ -726,7 +718,7 @@ class WicdDaemon(dbus.service.Object): @dbus.service.signal(dbus_interface="org.wicd.daemon",signature='s') def ConnectResultsSent(self, result): - print "Sending connectiong attempt result %s" % result + print "Sending connection attempt result %s" % result @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='') def LaunchChooser(self): @@ -845,13 +837,12 @@ class WicdDaemon(dbus.service.Object): class WirelessDaemon(dbus.service.Object): """ DBus interface for wireless connection operations. """ - def __init__(self, bus_name, daemon, wired=None, wifi=None, debug=False): + def __init__(self, bus_name, daemon, wifi=None, debug=False): """ Intitialize the wireless DBus interface. """ dbus.service.Object.__init__(self, bus_name=bus_name, object_path='/org/wicd/daemon/wireless') self.hidden_essid = None self.daemon = daemon - self.wired = wired self.wifi = wifi self.debug_mode = debug self.forced_disconnect = False @@ -906,8 +897,7 @@ class WirelessDaemon(dbus.service.Object): def CreateAdHocNetwork(self, essid, channel, ip, enctype, key, encused, ics): """ Creates an ad-hoc network using user inputted settings. """ - self.wifi.CreateAdHocNetwork(essid, channel, ip, enctype, key, encused, - ics) + self.wifi.CreateAdHocNetwork(essid, channel, ip, enctype, key, encused) @dbus.service.method('org.wicd.daemon.wireless') def GetKillSwitchEnabled(self): @@ -1197,13 +1187,12 @@ class WirelessDaemon(dbus.service.Object): class WiredDaemon(dbus.service.Object): """ DBus interface for wired connection operations. """ - def __init__(self, bus_name, daemon, wired=None, wifi=None, debug=False): + def __init__(self, bus_name, daemon, wired=None, debug=False): """ Intitialize the wireless DBus interface. """ dbus.service.Object.__init__(self, bus_name=bus_name, object_path="/org/wicd/daemon/wired") self.daemon = daemon self.wired = wired - self.wifi = wifi self.debug_mode = debug self.forced_disconnect = False self.WiredNetwork = {} From 2c24f4b0dbb5633f81f322cec5d1ca025301ffc6 Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Mon, 22 Dec 2008 00:20:42 -0500 Subject: [PATCH 6/6] Fix some issues with wired networks caused by refactoring. Add missing return statement. --- wicd/gui.py | 5 +++-- wicd/networking.py | 14 ++++++++++---- wicd/wicd-daemon.py | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/wicd/gui.py b/wicd/gui.py index 2957166..83d709a 100644 --- a/wicd/gui.py +++ b/wicd/gui.py @@ -297,10 +297,11 @@ class appGui(object): 'org.wicd.daemon') bus.add_signal_receiver(self.handle_connection_results, 'ConnectResultsSent', 'org.wicd.daemon') - bus.add_signal_receiver(handle_no_dbus, "DaemonClosing", - "org.wicd.daemon") bus.add_signal_receiver(lambda: setup_dbus(force=False), "DaemonStarting", "org.wicd.daemon") + if standalone: + bus.add_signal_receiver(handle_no_dbus, "DaemonClosing", + "org.wicd.daemon") try: gobject.timeout_add_seconds(1, self.update_statusbar) except: diff --git a/wicd/networking.py b/wicd/networking.py index 180da9d..47b7e53 100644 --- a/wicd/networking.py +++ b/wicd/networking.py @@ -391,9 +391,8 @@ class ConnectThread(threading.Thread): @abortable def stop_dhcp_clients(self, iface): - """ Stop and running DHCP clients, as well as wpa_supplicant. """ - print 'Stopping wpa_supplicant and any DHCP clients' - iface.StopWPA() + """ Stop and running DHCP clients. """ + print 'Stopping DHCP clients' BACKEND.StopDHCP() def connect_aborted(self, reason): @@ -710,6 +709,7 @@ class WirelessConnectThread(ConnectThread): self.release_dhcp_clients(wiface) self.reset_ip_addresses(wiface) self.stop_dhcp_clients(wiface) + self.stop_wpa(wiface) self.flush_routes(wiface) # Generate PSK and authenticate if needed. @@ -752,6 +752,12 @@ class WirelessConnectThread(ConnectThread): self.connect_result = "Success" self.is_connecting = False + @abortable + def stop_wpa(self, wiface): + """ Stops wpa_supplicant. """ + print 'Stopping wpa_supplicant' + wiface.StopWPA() + @abortable def generate_psk_and_authenticate(self, wiface): """ Generates a PSK and authenticates if necessary. @@ -860,7 +866,7 @@ class WiredConnectThread(ConnectThread): to the specified network. """ - def __init__(self, network, wireless, before_script, after_script, + def __init__(self, network, wired, before_script, after_script, disconnect_script, gdns1, gdns2, gdns3, gsearch_dom, liface, debug=False): """ Initialise the thread with network information. diff --git a/wicd/wicd-daemon.py b/wicd/wicd-daemon.py index 2c75d9c..5129653 100644 --- a/wicd/wicd-daemon.py +++ b/wicd/wicd-daemon.py @@ -312,7 +312,7 @@ class WicdDaemon(dbus.service.Object): @dbus.service.method('org.wicd.daemon') def GetAutoReconnect(self): """ Returns the value of self.auto_reconnect. See SetAutoReconnect. """ - do = bool(self.auto_reconnect) + return bool(self.auto_reconnect) @dbus.service.method('org.wicd.daemon') def SetAutoReconnect(self, value):