diff --git a/configscript.py b/configscript.py index 49b2c2d..7bfb82b 100755 --- a/configscript.py +++ b/configscript.py @@ -123,27 +123,28 @@ def get_script_info(network, network_type): def write_scripts(network, network_type, script_info): """ Writes script info to disk and loads it into the daemon. """ con = ConfigParser.ConfigParser() - print "Writing scripts, type", network_type + if network_type == "wired": con.read(wired_conf) - if con.has_section(network): - con.set(network, "beforescript", script_info["pre_entry"]) - con.set(network, "afterscript", script_info["post_entry"]) - con.set(network, "disconnectscript", - script_info["disconnect_entry"]) - con.write(open(wired_conf, "w")) - config.ReadWiredNetworkProfile(network) - config.SaveWiredNetworkProfile(network) + if not con.has_section(network): + con.add_section(network) + con.set(network, "beforescript", script_info["pre_entry"]) + con.set(network, "afterscript", script_info["post_entry"]) + con.set(network, "disconnectscript", script_info["disconnect_entry"]) + con.write(open(wired_conf, "w")) + config.ReadWiredNetworkProfile(network) + config.SaveWiredNetworkProfile(network) else: bssid = wireless.GetWirelessProperty(int(network), "bssid") con.read(wireless_conf) - if con.has_section(bssid): - con.set(bssid, "beforescript", script_info["pre_entry"]) - con.set(bssid, "afterscript", script_info["post_entry"]) - con.set(bssid, "disconnectscript", script_info["disconnect_entry"]) - con.write(open(wireless_conf, "w")) - config.ReadWirelessNetworkProfile(int(network)) - config.SaveWirelessNetworkProfile(int(network)) + if not con.has_section(bssid): + con.add_section(bssid) + con.set(bssid, "beforescript", script_info["pre_entry"]) + con.set(bssid, "afterscript", script_info["post_entry"]) + con.set(bssid, "disconnectscript", script_info["disconnect_entry"]) + con.write(open(wireless_conf, "w")) + config.ReadWirelessNetworkProfile(int(network)) + config.SaveWirelessNetworkProfile(int(network)) def main (argv): """ Runs the script configuration dialog. """ @@ -186,6 +187,6 @@ def main (argv): if __name__ == '__main__': if os.getuid() != 0: - print "Root priviledges are required to configure scripts. Exiting." + print "Root privileges are required to configure scripts. Exiting." sys.exit(0) main(sys.argv) diff --git a/daemon.py b/daemon.py index 24bf71a..a636ee6 100644 --- a/daemon.py +++ b/daemon.py @@ -45,9 +45,11 @@ import signal import gobject import dbus import dbus.service -from dbus.mainloop.glib import DBusGMainLoop -if getattr(dbus, 'version', (0, 0, 0)) >= (0, 41, 0): +if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0): import dbus.glib +else: + from dbus.mainloop.glib import DBusGMainLoop + DBusGMainLoop(set_as_default=True) # wicd specific libraries import wpath @@ -155,8 +157,7 @@ class ConnectionWizard(dbus.service.Object): # Make a variable that will hold the wired network profile self.WiredNetwork = {} - # Kind of hackish way to load the secondary wnettools interface - # for both wired and wireless connection managers. + # Kind of hackish way to set correct wnettools interfaces. self.wifi.liface = self.wired.liface self.wired.wiface = self.wifi.wiface @@ -993,7 +994,7 @@ class ConnectionWizard(dbus.service.Object): ################################# @dbus.service.method('org.wicd.daemon.config') - def CreateWiredNetworkProfile(self, profilename): + def CreateWiredNetworkProfile(self, profilename, default=False): """ Creates a wired network profile. """ profilename = misc.to_unicode(profilename) print "Creating wired profile for " + profilename @@ -1012,7 +1013,7 @@ class ConnectionWizard(dbus.service.Object): config.set(profilename, "beforescript", None) config.set(profilename, "afterscript", None) config.set(profilename, "disconnectscript", None) - config.set(profilename, "default", False) + config.set(profilename, "default", default) config.write(open(self.wired_conf, "w")) return True @@ -1081,6 +1082,9 @@ class ConnectionWizard(dbus.service.Object): @dbus.service.method('org.wicd.daemon.config') def SaveWiredNetworkProfile(self, profilename): """ Writes a wired network profile to disk. """ + def write_script_ent(prof, conf, script): + if not conf.has_option(prof, script): + conf.set(prof, script, None) if profilename == "": return "500: Bad Profile name" profilename = misc.to_unicode(profilename) @@ -1091,6 +1095,10 @@ class ConnectionWizard(dbus.service.Object): config.add_section(profilename) for x in self.WiredNetwork: config.set(profilename, x, self.WiredNetwork[x]) + + write_script_ent(profilename, config, "beforescript") + write_script_ent(profilename, config, "afterscript") + write_script_ent(profilename, config, "disconnectscript") config.write(open(self.wired_conf, "w")) return "100: Profile Written" @@ -1125,6 +1133,10 @@ class ConnectionWizard(dbus.service.Object): @dbus.service.method('org.wicd.daemon.config') def SaveWirelessNetworkProfile(self, id): """ Writes a wireless profile to disk. """ + def write_script_ent(prof, conf, script): + if not conf.has_option(prof, script): + conf.set(prof, script, None) + config = ConfigParser.ConfigParser() config.read(self.wireless_conf) cur_network = self.LastScan[id] @@ -1146,7 +1158,16 @@ class ConnectionWizard(dbus.service.Object): config.set(bssid_key, x, cur_network[x]) if cur_network["use_settings_globally"]: config.set(essid_key, x, cur_network[x]) - + + write_script_ent(bssid_key, config, "beforescript") + write_script_ent(bssid_key, config, "afterscript") + write_script_ent(bssid_key, config, "disconnect") + + if cur_network["use_settings_globally"]: + write_script_ent(essid_key, config, "beforescript") + write_script_ent(essid_key, config, "afterscript") + write_script_ent(essid_key, config, "disconnect") + config.write(open(self.wireless_conf, "w")) @dbus.service.method('org.wicd.daemon.config') @@ -1419,7 +1440,7 @@ class ConnectionWizard(dbus.service.Object): print "Wired configuration file not found, creating a default..." # Create the file and a default profile open(self.wired_conf, "w").close() - self.CreateWiredNetworkProfile("wired-default") + self.CreateWiredNetworkProfile("wired-default", default=True) # Hide the files, so the keys aren't exposed. print "chmoding configuration files 0600..." @@ -1445,19 +1466,20 @@ Arguments: \t-s\t--no-scan\tDon't auto-scan/auto-connect. \t-f\t--no-daemon\tDon't daemonize (run in foreground). \t-e\t--no-stderr\tDon't redirect stderr. +\t-n\t--no-poll\tDon't monitor network status. \t-o\t--no-stdout\tDon't redirect stdout. -\t-P\t--pidfile path\tCreate a pidfile at the specified path. \t-h\t--help\t\tPrint this help. """ -def daemonize(write_pid, pidfile): +def daemonize(): """ Disconnect from the controlling terminal. Fork twice, once to disconnect ourselves from the parent terminal and a second time to prevent any files we open from becoming our controlling terminal. - For more info see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012 + For more info see: + http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012 """ # Fork the first time to disconnect from the parent terminal and @@ -1479,10 +1501,7 @@ def daemonize(write_pid, pidfile): try: pid = os.fork() if pid > 0: - if not write_pid: - print "wicd daemon: pid " + str(pid) - else: - print >> open(pidfile,'wt'), str(pid) + print "wicd daemon: pid " + str(pid) sys.exit(0) except OSError, e: print >> sys.stderr, "Fork #2 failed: %d (%s)" % (e.errno, e.strerror) @@ -1502,16 +1521,15 @@ def main(argv): auto_scan = True try: - opts, args = getopt.getopt(sys.argv[1:], 'feosP:', - ['help', 'no-daemon', 'no-stderr', 'no-stdout', 'no-scan', - 'pidfile:']) + opts, args = getopt.getopt(sys.argv[1:], 'fenosP:', + ['help', 'no-daemon', 'no-poll', 'no-stderr', 'no-stdout', + 'no-scan'']) except getopt.GetoptError: # Print help information and exit usage() sys.exit(2) - write_pid = False - pid_file = None + no_poll = False for o, a in opts: if o in ('-h', '--help'): usage() @@ -1524,11 +1542,10 @@ def main(argv): do_daemonize = False if o in ('-s', '--no-scan'): auto_scan = False - if o in ('-P', '--pidfile'): - write_pid = True - pid_file = a + if o in ('-n', '--no-poll'): + no_poll = True - if do_daemonize: daemonize(write_pid, pid_file) + if do_daemonize: daemonize() if redirect_stderr or redirect_stdout: output = LogWriter() if redirect_stdout: sys.stdout = output @@ -1545,11 +1562,10 @@ def main(argv): obj = ConnectionWizard(d_bus_name, auto_connect=auto_scan) gobject.threads_init() - (child_pid, x, x, x) = gobject.spawn_async([wpath.bin + "monitor.py"], + if not no_poll: + (child_pid, x, x, x) = gobject.spawn_async([wpath.bin + "monitor.py"], flags=gobject.SPAWN_CHILD_INHERITS_STDIN) - - - signal.signal(signal.SIGTERM, sigterm_caught) + signal.signal(signal.SIGTERM, sigterm_caught) # Enter the main loop mainloop = gobject.MainLoop() @@ -1569,5 +1585,4 @@ if __name__ == '__main__': print ("Root priviledges are required for the daemon to run properly." + " Exiting.") sys.exit(1) - DBusGMainLoop(set_as_default=True) main(sys.argv) diff --git a/gui.py b/gui.py index 004290c..56e7528 100644 --- a/gui.py +++ b/gui.py @@ -48,29 +48,30 @@ try: except: pass -if getattr(dbus, 'version', (0, 0, 0)) >= (0, 41, 0): +if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0): import dbus.glib +else: + from dbus.mainloop.glib import DBusGMainLoop + DBusGMainLoop(set_as_default=True) bus = dbus.SystemBus() -try: - proxy_obj = bus.get_object("org.wicd.daemon", '/org/wicd/daemon') -except dbus.DBusException, e: - misc.PromptToStartDaemon() - time.sleep(1) - try: - proxy_obj = bus.get_object("org.wicd.daemon", '/org/wicd/daemon') - daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon') - wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless') - wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired') - vpn_session = dbus.Interface(proxy_obj, 'org.wicd.daemon.vpn') - config = dbus.Interface(proxy_obj, 'org.wicd.daemon.config') - dbus_ifaces = {"daemon" : daemon, "wireless" : wireless, "wired" : wired, - "vpn_session" : vpn_session, "config" : config} - except: - proxy_obj = None - +proxy_obj, daemon, wireless, wired, vpn_session, config = [None for x in + range(0, 6)] +dbus_ifaces = {} language = misc.get_language_list_gui() +def setup_dbus(): + global proxy_obj, daemon, wireless, wired, vpn_session, config, dbus_ifaces + proxy_obj = bus.get_object("org.wicd.daemon", '/org/wicd/daemon') + daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon') + wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless') + wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired') + vpn_session = dbus.Interface(proxy_obj, 'org.wicd.daemon.vpn') + config = dbus.Interface(proxy_obj, 'org.wicd.daemon.config') + dbus_ifaces = {"daemon" : daemon, "wireless" : wireless, "wired" : wired, + "vpn_session" : vpn_session, "config" : config} + + def error(parent, message): """ Shows an error dialog """ dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, @@ -201,6 +202,11 @@ class appGui: gladefile = "data/wicd.glade" self.windowname = "gtkbench" self.wTree = gtk.glade.XML(gladefile) + + try: + setup_dbus() + except dbus.DBusException: + pass # wicd.py handles this. dic = { "refresh_clicked" : self.refresh_networks, "quit_clicked" : self.exit, @@ -242,6 +248,7 @@ class appGui: self.wpadrivercombo = None self.connecting = False self.fast = True # Use ioctl instead of external program calls + self.prev_state = None self.refresh_networks(fresh=False) self.window.connect('delete_event', self.exit) @@ -317,7 +324,6 @@ class appGui: def disconnect_all(self, widget=None): """ Disconnects from any active network. """ daemon.Disconnect() - self.update_connect_buttons() def about_dialog(self, widget, event=None): """ Displays an about dialog. """ @@ -337,6 +343,18 @@ class appGui: def settings_dialog(self, widget, event=None): """ Displays a general settings dialog. """ + 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 + dialog = self.wTree.get_widget("pref_dialog") dialog.set_title(language['preferences']) size = config.ReadWindowSize("pref") @@ -416,23 +434,28 @@ class appGui: self.set_label("pref_driver_label", language['wpa_supplicant_driver'] + ':') + # Replacement for the combo box hack + wpadrivercombo = build_combobox("pref_wpa_combobox") + # Hack to get the combo box we need, which you can't do with glade. - wpa_hbox = self.wTree.get_widget("hbox_wpa") - if not self.first_dialog_load: - wpa_hbox.remove(self.wpadrivercombo) - else: - self.first_dialog_load = False - self.wpadrivercombo = gtk.combo_box_new_text() - wpadrivercombo = self.wpadrivercombo # Just to make my life easier - wpa_hbox.pack_end(wpadrivercombo) + #wpa_hbox = self.wTree.get_widget("hbox_wpa") + #if not self.first_dialog_load: + #wpa_hbox.remove(self.wpadrivercombo) + #else: + #self.first_dialog_load = False + #self.wpadrivercombo = gtk.combo_box_new_text() + #wpadrivercombo = self.wpadrivercombo # Just to make my life easier + #wpa_hbox.pack_end(wpadrivercombo) - wpadrivers = ["hostap", "hermes", "madwifi", "atmel", "wext", - "ndiswrapper", "broadcom", "ipw", "ralink legacy"] + wpadrivers = ["wext", "hostap", "madwifi", "atmel", "ndiswrapper", + "ipw", "ralink legacy"] found = False + def_driver = daemon.GetWPADriver() for i, x in enumerate(wpadrivers): - if x == daemon.GetWPADriver() and not found: + if x == def_driver: #and not found: found = True user_driver_index = i + wpadrivercombo.remove_text(i) wpadrivercombo.append_text(x) # Set the active choice here. Doing it before all the items are @@ -441,7 +464,7 @@ class appGui: wpadrivercombo.set_active(user_driver_index) else: # Use wext as default, since normally it is the correct driver. - wpadrivercombo.set_active(4) + wpadrivercombo.set_active(0) self.set_label("pref_wifi_label", language['wireless_interface'] + ':') self.set_label("pref_wired_label", language['wired_interface'] + ':') @@ -658,7 +681,6 @@ class appGui: if self.pulse_active: self.pulse_progress_bar() self.pulse_active = False - self.update_connect_buttons() self.network_list.set_sensitive(True) self.status_area.hide_all() @@ -678,12 +700,18 @@ class appGui: self.set_status(language['not_connected']) return True - def update_connect_buttons(self): + def update_connect_buttons(self, state=None, x=None, force_check=False): """ Updates the connect/disconnect buttons for each network entry. """ - apbssid = wireless.GetApBssid() - for entry in self.network_list: - if hasattr(entry, "update_connect_button"): - entry.update_connect_button(apbssid) + if not state: + state, x = daemon.GetConnectionStatus() + + if self.prev_state != state or force_check: + print 'we actually update now' + apbssid = wireless.GetApBssid() + for entry in self.network_list: + if hasattr(entry, "update_connect_button"): + entry.update_connect_button(state, apbssid) + self.prev_state = state def check_for_wired(self, wired_ip): """ Determine if wired is active, and if yes, set the status. """ @@ -730,7 +758,6 @@ class appGui: rescan. """ - print 'got rescan signal' if not self.connecting: self.refresh_networks(fresh=False) @@ -803,6 +830,7 @@ class appGui: label = gtk.Label(language['no_wireless_networks_found']) self.network_list.pack_start(label) label.show() + self.update_connect_buttons(force_check=True) self.network_list.set_sensitive(True) def save_settings(self, nettype, networkid, networkentry): @@ -855,12 +883,9 @@ class appGui: not entry.chkbox_global_dns.get_active(): entry.set_net_prop('use_static_dns', True) entry.set_net_prop('use_global_dns', False) - entry.set_net_prop("dns1", - noneToString(entry.txt_dns_1.get_text())) - entry.set_net_prop("dns2", - noneToString(entry.txt_dns_2.get_text())) - entry.set_net_prop("dns3", - noneToString(entry.txt_dns_3.get_text())) + entry.set_net_prop("dns1", noneToString(entry.txt_dns_1.get_text())) + entry.set_net_prop("dns2", noneToString(entry.txt_dns_2.get_text())) + entry.set_net_prop("dns3", noneToString(entry.txt_dns_3.get_text())) elif entry.chkbox_static_dns.get_active() and \ entry.chkbox_global_dns.get_active(): entry.set_net_prop('use_static_dns', True) @@ -1073,7 +1098,8 @@ class appGui: if __name__ == '__main__': if not proxy_obj: error("Could not connect to wicd's D-Bus interface. Make sure the " + - "daemon is started") + "daemon is started. If the error persists, please report the" + + "behavior at wicd.net.") sys.exit(1) app = appGui(standalone=True) diff --git a/misc.py b/misc.py index 83601dc..5709d19 100644 --- a/misc.py +++ b/misc.py @@ -22,7 +22,7 @@ import wpath import locale import gettext import sys -from subprocess import * +from subprocess import Popen, STDOUT, PIPE import subprocess import commands @@ -101,7 +101,7 @@ def PromptToStartDaemon(): """ Prompt the user to start the daemon """ daemonloc = wpath.bin + 'launchdaemon.sh' sudo_prog = choose_sudo_prog() - if sudo_prog.endswith("gksu"): + if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"): msg = '--message' else: msg = '-- caption' @@ -123,8 +123,8 @@ def WriteLine(my_file, text): my_file.write(text + "\n") def ExecuteScript(script): - """ Execute a command """ - os.system(script) + """ Execute a command and send its output to the bit bucket. """ + os.system("%s > /dev/null 2>&1" % script) def ReadFile(filename): """ read in a file and return it's contents as a string """ @@ -324,15 +324,16 @@ def detect_desktop_environment(): def choose_sudo_prog(): desktop_env = detect_desktop_environment() - gk_paths = ["/usr/bin/gksu", "/usr/local/bin/gksu", "/bin/gksu"] - kde_paths = ["/usr/bin/kdesu", "/usr/local/bin/kdesu", "/bin/kdesu", - "/usr/bin/kdesudo", "/usr/local/bin/kdesudo", "/bin/kdesudo"] + env_path = os.environ['PATH'].split(":") + if desktop_env == "kde": - paths = kde_paths - paths.extend(gk_paths) + paths = [] + for p in env_path: + paths.extend([p + '/kdesu', p + '/kdesudo', p + '/ktsuss']) else: - paths = gk_paths - paths.extend(kde_paths) + paths = [] + for p in env_path: + paths.extend([p + '/gksu', p + '/ktsuss']) for path in paths: if os.access(path, os.F_OK): return path diff --git a/monitor.py b/monitor.py index 12fc2c8..03725b6 100755 --- a/monitor.py +++ b/monitor.py @@ -27,7 +27,11 @@ when appropriate. import dbus import gobject import time -from dbus.mainloop.glib import DBusGMainLoop +if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0): + import dbus.glib +else: + from dbus.mainloop.glib import DBusGMainLoop + DBusGMainLoop(set_as_default=True) import wpath import misc @@ -37,7 +41,6 @@ misc.RenameProcess("wicd-monitor") if __name__ == '__main__': wpath.chdir(__file__) -DBusGMainLoop(set_as_default=True) proxy_obj = dbus.SystemBus().get_object('org.wicd.daemon', '/org/wicd/daemon') daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon') wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired') @@ -61,7 +64,7 @@ class ConnectionStatus(): # This determines if we use ioctl or external programs self.fast = True - self.iwconfig = '' + self.iwconfig = "" def check_for_wired_connection(self, wired_ip): """ Checks for an active wired connection. diff --git a/netentry.py b/netentry.py index 9b94a68..e1ee232 100644 --- a/netentry.py +++ b/netentry.py @@ -157,7 +157,7 @@ class AdvancedSettingsDialog(gtk.Dialog): def reset_static_checkboxes(self): # Enable the right stuff - if stringToNone(self.txt_ip.get_text()) is not None: + if stringToNone(self.txt_ip.get_text()): self.chkbox_static_ip.set_active(True) self.chkbox_static_dns.set_active(True) self.chkbox_static_dns.set_sensitive(False) @@ -166,7 +166,7 @@ class AdvancedSettingsDialog(gtk.Dialog): self.chkbox_static_dns.set_active(False) self.chkbox_static_dns.set_sensitive(True) - if stringToNone(self.txt_dns_1.get_text()) is not None: + if stringToNone(self.txt_dns_1.get_text()): self.chkbox_static_dns.set_active(True) else: self.chkbox_static_dns.set_active(False) @@ -315,6 +315,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): else: self.combo_encryption.set_active(0) self.change_encrypt_method() + self.vbox.pack_start(self.chkbox_global_settings, False, False) self.vbox.pack_start(self.chkbox_encryption, False, False) self.vbox.pack_start(self.combo_encryption, False, False) @@ -355,25 +356,33 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): self.txt_netmask.set_text(self.format_entry(networkID,"netmask")) self.txt_gateway.set_text(self.format_entry(networkID,"gateway")) - if wireless.GetWirelessProperty(networkID,'use_global_dns'): - self.chkbox_global_dns.set_active(True) - if wireless.GetWirelessProperty(networkID, "dns1") is not None: - self.txt_dns_1.set_text(self.format_entry(networkID, "dns1")) - if wireless.GetWirelessProperty(networkID, 'dns2') is not None: - self.txt_dns_2.set_text(self.format_entry(networkID, "dns2")) - if wireless.GetWirelessProperty(networkID, 'dns3') is not None: - self.txt_dns_3.set_text(self.format_entry(networkID, "dns3")) + self.chkbox_global_dns.set_active(wireless.GetWirelessProperty(networkID, + 'use_global_dns')) + + self.txt_dns_1.set_text(self.format_entry(networkID, "dns1")) + self.txt_dns_2.set_text(self.format_entry(networkID, "dns2")) + self.txt_dns_3.set_text(self.format_entry(networkID, "dns3")) self.reset_static_checkboxes() - if wireless.GetWirelessProperty(networkID, 'encryption'): - self.chkbox_encryption.set_active(True) - else: - self.chkbox_encryption.set_active(False) + self.chkbox_encryption.set_active(wireless.GetWirelessProperty(networkID, + 'encryption')) + self.chkbox_global_settings.set_active(wireless.GetWirelessProperty(networkID, + 'use_settings_globally')) + - if wireless.GetWirelessProperty(networkID, 'use_settings_globally'): - self.chkbox_global_settings.set_active(True) + activeID = -1 # Set the menu to this item when we are done + user_enctype = wireless.GetWirelessProperty(networkID, "enctype") + for x, enc_type in enumerate(self.encrypt_types): + if enc_type[1] == user_enctype: + activeID = x + + self.combo_encryption.set_active(activeID) + if activeID != -1: + self.chkbox_encryption.set_active(True) + self.combo_encryption.set_sensitive(True) + self.vbox_encrypt_info.set_sensitive(True) else: - self.chkbox_global_settings.set_active(False) + self.combo_encryption.set_active(0) self.change_encrypt_method() def format_entry(self, networkid, label): @@ -466,7 +475,7 @@ class NetworkEntry(gtk.HBox): # Set up the script settings button self.script_button = gtk.Button() self.script_image = gtk.Image() - self.script_image.set_from_icon_name('execute', 4) + self.script_image.set_from_stock(gtk.STOCK_EXECUTE, 4) self.script_image.set_padding(4, 0) self.script_button.set_alignment(.5, .5) self.script_button.set_image(self.script_image) @@ -590,7 +599,6 @@ class WiredNetworkEntry(NetworkEntry): self.expander.set_expanded(True) self.profile_help.show() self.check_enable() - self.update_connect_button() self.wireddis = self.connect("destroy", self.destroy_called) def destroy_called(self, *args): @@ -639,9 +647,8 @@ class WiredNetworkEntry(NetworkEntry): self.advanced_button.set_sensitive(False) self.script_button.set_sensitive(False) - def update_connect_button(self, apbssid=None): + def update_connect_button(self, state, apbssid=None): """ Update the connection/disconnect button for this entry. """ - state, x = daemon.GetConnectionStatus() if state == misc.WIRED: self.disconnect_button.show() self.connect_button.hide() @@ -791,7 +798,6 @@ class WirelessNetworkEntry(NetworkEntry): # Show everything self.show_all() self.advanced_dialog = WirelessSettingsDialog(networkID) - self.update_connect_button(wireless.GetApBssid()) self.wifides = self.connect("destroy", self.destroy_called) def _escape(self, val): @@ -862,9 +868,8 @@ class WirelessNetworkEntry(NetworkEntry): self.image.set_from_file(wpath.images + signal_img) self.lbl_strength.set_label(disp_strength + ending) - def update_connect_button(self, apbssid): + def update_connect_button(self, state, apbssid): """ Update the connection/disconnect button for this entry. """ - state, x = daemon.GetConnectionStatus() if state == misc.WIRELESS and apbssid == \ wireless.GetWirelessProperty(self.networkID, "bssid"): self.disconnect_button.show() diff --git a/networking.py b/networking.py index 397a5e6..31ffcfd 100644 --- a/networking.py +++ b/networking.py @@ -316,12 +316,13 @@ class ConnectThread(threading.Thread): 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' + print 'Stopping wpa_supplicant and any DHCP clients' iface.StopWPA() wnettools.StopDHCP() @@ -358,10 +359,12 @@ class Wireless(Controller): wpa_driver = property(get_wpa_driver, set_wpa_driver) - def LoadInterfaces(self): - """ Load the wnettools controls for the wired/wireless interfaces. """ - self.wiface = wnettools.WirelessInterface(self.wireless_interface, - self.debug, self.wpa_driver) + #def LoadInterfaces(self, dhcp_client, flush_tool): + # """ Load the wnettools controls for the wired/wireless interfaces. """ + # #self.wiface = wnettools.WirelessInterface(self.wireless_interface, + # # self.debug, self.wpa_driver) + # self.dhcp_client = dhcp_client + # self.flush_tool = flush_tool def Scan(self, essid=None): """ Scan for available wireless networks. @@ -373,6 +376,22 @@ class Wireless(Controller): A list of available networks sorted by strength. """ + def comp(x, y): + if x.has_key('quality'): + if x['quality'] > y['quality']: + return 1 + elif x['quality'] < y['quality']: + return -1 + else: + return 0 + else: + if x['strength'] < y['strength']: + return 1 + elif x['strength'] > y['strength']: + return -1 + else: + return 0 + wiface = self.wiface # Prepare the interface for scanning @@ -386,8 +405,8 @@ class Wireless(Controller): wiface.SetEssid(essid) aps = wiface.GetNetworks() - #print aps - aps.sort(key=lambda x: x['strength']) + aps.sort(cmp=comp, reverse=True) + return aps def Connect(self, network, debug=False): @@ -621,13 +640,14 @@ class WirelessConnectThread(ConnectThread): wiface = self.wiface liface = self.liface self.is_connecting = True + self.is_fast = True # Run pre-connection script. self.abort_if_needed() self.run_script_if_needed(self.before_script, 'pre-connection') self.abort_if_needed() - # Dake down interface and clean up previous connections. + # Take down interface and clean up previous connections. self.put_iface_down(wiface) self.abort_if_needed() self.release_dhcp_clients(wiface, liface) @@ -659,7 +679,8 @@ class WirelessConnectThread(ConnectThread): # Validate Authentication. if self.network.get('enctype'): self.SetStatus('validating_authentication') - if not wiface.ValidateAuthentication(time.time()): + if not wiface.ValidateAuthentication(time.time(), + fast=self.is_fast): self.abort_connection('bad_pass') self.abort_if_needed() @@ -676,7 +697,7 @@ class WirelessConnectThread(ConnectThread): self.SetStatus('done') print 'Connecting thread exiting.' if self.debug: - print "IP Address is: " + str(wiface.GetIP(fast=True)) + print "IP Address is: " + str(wiface.GetIP(fast=self.is_fast)) self.is_connecting = False def generate_psk_and_authenticate(self, wiface): @@ -709,6 +730,12 @@ class WirelessConnectThread(ConnectThread): misc.Run(''.join(['wpa_passphrase "', self.network['essid'], '" "', _sanitize(self.network['key']), '"']))) + + if not self.network['psk']: + self.network['psk'] = self.network['key'] + print 'WARNING: PSK generation failed! Falling back to ' + \ + 'wireless key.\nPlease report this error to the wicd ' + \ + 'developers!' # Generate the wpa_supplicant file... if self.network.get('enctype'): self.SetStatus('generating_wpa_config') @@ -735,9 +762,12 @@ class Wired(Controller): link_detect = property(get_link_detect, set_link_detect) - def LoadInterfaces(self): - """ Load the wnettools controls for the wired/wireless interfaces. """ - self.liface = wnettools.WiredInterface(self.wired_interface, self.debug) + #def LoadInterfaces(self, dhcp_client, link_tool, flush_tool): + # """ Load the wnettools controls for the wired/wireless interfaces. """ + # #self.liface = wnettools.WiredInterface(self.wired_interface, self.debug) + # self.dhcp_client = dhcp_client + # self.link_detect = link_tool + # self.flush_tool = flush_tool def CheckPluggedIn(self, fast=False): """ Check whether the wired connection is plugged in. @@ -860,6 +890,8 @@ class WiredConnectThread(ConnectThread): liface = self.liface self.is_connecting = True + #TODO pass is_fast in. + self.is_fast = True # Run pre-connection script. self.abort_if_needed() @@ -891,5 +923,5 @@ class WiredConnectThread(ConnectThread): self.SetStatus('done') print 'Connecting thread exiting.' if self.debug: - print "IP Address is: " + str(liface.GetIP(fast=True)) + print "IP Address is: " + str(liface.GetIP(fast=self.is_fast)) self.is_connecting = False diff --git a/wicd.py b/wicd.py index 1220cf3..c7d3b82 100755 --- a/wicd.py +++ b/wicd.py @@ -59,9 +59,12 @@ if not (gtk.gtk_version[0] >= 2 and gtk.gtk_version[1] >= 10): sys.exit(1) else: USE_EGG = False - -if getattr(dbus, 'version', (0, 0, 0)) >= (0, 41, 0): + +if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0): import dbus.glib +else: + from dbus.mainloop.glib import DBusGMainLoop + DBusGMainLoop(set_as_default=True) misc.RenameProcess("wicd") @@ -433,6 +436,8 @@ class TrayIcon: self.gui_win = gui.appGui() bus.add_signal_receiver(self.gui_win.dbus_refresh_networks, 'SendScanSignal', 'org.wicd.daemon') + bus.add_signal_receiver(self.gui_win.update_connect_buttons, + 'StatusChanged', 'org.wicd.daemon') elif not self.gui_win.is_visible: self.gui_win.show_win() else: @@ -555,7 +560,7 @@ def connect_to_dbus(): proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon') print 'Success.' except dbus.DBusException: - gui.error("Could not connect to wicd's D-Bus interface. " + + gui.error(None, "Could not connect to wicd's D-Bus interface. " + "Make sure the daemon is started.") sys.exit(1) @@ -563,6 +568,7 @@ def connect_to_dbus(): wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless') wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired') config = dbus.Interface(proxy_obj, 'org.wicd.daemon.config') + return True def main(argv): """ The main frontend program. @@ -590,12 +596,18 @@ def main(argv): use_tray = False elif opt in ('-a', '--no-animate'): animate = False + else: + usage() + sys.exit(2) print 'Loading...' connect_to_dbus() if not use_tray: - os.spawnlp(os.P_NOWAIT, wpath.bin + 'gui.py') + the_gui = gui.appGui() + the_gui.standalone = True + mainloop = gobject.MainLoop() + mainloop.run() sys.exit(0) # Set up the tray icon GUI and backend diff --git a/wnettools.py b/wnettools.py index c8cee13..9a1e98e 100644 --- a/wnettools.py +++ b/wnettools.py @@ -55,6 +55,7 @@ signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', re.I | re.M | r mode_pattern = re.compile('.*Mode:(.*?)\n', re.I | re.M | re.S) freq_pattern = re.compile('.*Frequency:(.*?)\n', re.I | re.M | re.S) ip_pattern = re.compile(r'inet [Aa]d?dr[^.]*:([^.]*\.[^.]*\.[^.]*\.[0-9]*)', re.S) +bssid_pattern = re.compile('.*Access Point: (([0-9A-Z]{2}:){5}[0-9A-Z]{2})', re.I | re.M | re.S) wep_pattern = re.compile('.*Encryption key:(.*?)\n', re.I | re.M | re.S) altwpa_pattern = re.compile('(wpa_ie)', re.I | re.M | re.S) @@ -132,6 +133,12 @@ def GetWirelessInterfaces(): re.I | re.M | re.S), output) return iface +def GetWiredInterfaces(): + basedir = '/sys/class/net/' + return [iface for iface in os.listdir(basedir) if not 'wireless' \ + in os.listdir(basedir + iface) and \ + open(basedir + iface + "/type").readlines()[0].strip() == "1"] + def _fast_get_wifi_interfaces(): """ Tries to get a wireless interface using /sys/class/net. """ dev_dir = '/sys/class/net/' @@ -500,7 +507,7 @@ class Interface(object): def ReleaseDHCP(self): """ Release the DHCP lease for this interface. """ - cmd = self.DHCP_RELEASE + " " + self.iface + cmd = self.DHCP_RELEASE + " " + self.iface + " 2>/dev/null" misc.Run(cmd) def FlushRoutes(self): @@ -725,6 +732,7 @@ class WirelessInterface(Interface): """ Interface.__init__(self, iface, verbose) self.wpa_driver = wpa_driver + self.scan_iface = None def SetWpaDriver(self, driver): """ Sets the wpa_driver. """ @@ -864,7 +872,7 @@ class WirelessInterface(Interface): except (UnicodeDecodeError, UnicodeEncodeError): print 'Unicode problem with current network essid, ignoring!!' return None - if ap['essid'] == '': + if ap['essid'] in ['', ""]: ap['essid'] = 'Hidden' ap['hidden'] = True else: @@ -1153,13 +1161,21 @@ class WirelessInterface(Interface): cmd = 'iwpriv ' + self.iface + ' ' if self.verbose: print cmd misc.Run(cmd) - - def GetBSSID(self, fast=True): + + def GetBSSID(self, iwconfig=None, fast=True): """ Get the MAC address for the interface. """ if fast: return self._fast_get_bssid() else: - return "" + if not iwconfig: + cmd = 'iwconfig ' + self.iface + if self.verbose: print cmd + output = misc.Run(cmd) + else: + output = iwconfig + + bssid = misc.RunRegex(bssid_pattern, output) + return bssid def _fast_get_bssid(self): """ Gets the MAC address for the connected AP using ioctl calls. """ @@ -1223,7 +1239,7 @@ class WirelessInterface(Interface): if self.verbose: print "SIOCGIWRANGE failed: " + str(e) return None - # This defines the iwfreq struct, used to get singal strength. + # This defines the iwfreq struct, used to get signal strength. fmt = "iiihb6ii4B4Bi32i2i2i2i2i3h8h2b2bhi8i2b3h2i2ihB17x" + 32 * "ihbb" size = struct.calcsize(fmt) data = buff.tostring()