1
0
mirror of https://github.com/gryf/wicd.git synced 2026-01-29 11:55:45 +01:00

Experimental: Apply changes involving setup.py

* Added setup.py from trunk
 * Updated various information files (AUTHORS, README, etc)
 * Update the Wicd icon
 * Move stuff around to match trunk's layout
This commit is contained in:
compwiz18
2008-08-23 20:14:43 +00:00
parent 2261b25101
commit 0844386017
91 changed files with 2945 additions and 1793 deletions

44
wicd/autoconnect.py Normal file
View File

@@ -0,0 +1,44 @@
#!/usr/bin/python
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import dbus
import time
import gobject
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
def reply_handle():
loop.quit()
def error_handle(e):
loop.quit()
print daemon.Hello()
time.sleep(3)
daemon.SetSuspend(False)
if not daemon.CheckIfConnecting():
print daemon.AutoConnect(True, reply_handler=reply_handle,
error_handler=error_handle)
daemon.SetForcedDisconnect(False)
loop = gobject.MainLoop()
loop.run()

192
wicd/configscript.py Executable file
View File

@@ -0,0 +1,192 @@
#!/usr/bin/env python
""" Configure the scripts for a particular network.
Script for configuring the scripts for a network passed in as a
command line argument. This needs to run a separate process because
editing scripts requires root access, and the GUI/Tray are typically
run as the current user.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import sys
import os
import gtk
import ConfigParser
import dbus
import gtk.glade
import wicd.wpath as wpath
import wicd.misc as misc
_ = misc.get_gettext()
language = {}
language['configure_scripts'] = _("Configure Scripts")
language['before_script'] = _("Pre-connection Script")
language['after_script'] = _("Post-connection Script")
language['disconnect_script'] = _("Disconnection Script")
bus = dbus.SystemBus()
# Connect to the daemon
try:
print 'Attempting to connect tray to daemon...'
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
print 'Success.'
except Exception:
print 'Daemon not running...'
misc.PromptToStartDaemon()
sys.exit(1)
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')
wireless_conf = wpath.etc + 'wireless-settings.conf'
wired_conf = wpath.etc + 'wired-settings.conf'
def none_to_blank(text):
""" Converts special string cases to a blank string.
If text is None, 'None', or '' then this method will
return '', otherwise it will just return str(text).
"""
if text in (None, "None", ""):
return ""
else:
return str(text)
def blank_to_none(text):
""" Convert an empty or null string to 'None'. """
if text in ("", None):
return "None"
else:
return str(text)
def get_val(con, network, option, default="None"):
""" Returns the specified option for the given network.
Returns the value stored in the config file for the given option,
unless the option isn't stored yet, in which case the default value
provided is stored and then returned.
Keyword arguments:
network -- The section to search.
option -- The option to search for.
deafult -- The default value to store/return if the option isn't found.
"""
if not con.has_option(network, option):
con.set(network, option, default)
return con.get(network, option)
def get_script_info(network, network_type):
""" Read script info from disk and load it into the configuration dialog """
info = {}
con = ConfigParser.ConfigParser()
if network_type == "wired":
con.read(wired_conf)
if con.has_section(network):
info["pre_entry"] = get_val(con, network, "beforescript")
info["post_entry"] = get_val(con, network, "afterscript")
info["disconnect_entry"] = get_val(con, network, "disconnectscript")
else:
bssid = wireless.GetWirelessProperty(int(network), "bssid")
con.read(wireless_conf)
if con.has_section(bssid):
info["pre_entry"] = get_val(con, bssid, "beforescript")
info["post_entry"] = get_val(con, bssid, "afterscript")
info["disconnect_entry"] = get_val(con, bssid, "disconnectscript")
return info
def write_scripts(network, network_type, script_info):
""" Writes script info to disk and loads it into the daemon. """
con = ConfigParser.ConfigParser()
if network_type == "wired":
con.read(wired_conf)
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 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. """
if len(argv) < 2:
print 'Network id to configure is missing, aborting.'
sys.exit(1)
network = argv[1]
network_type = argv[2]
script_info = get_script_info(network, network_type)
gladefile = wpath.etc + "wicd.glade"
wTree = gtk.glade.XML(gladefile)
dialog = wTree.get_widget("configure_script_dialog")
wTree.get_widget("pre_label").set_label(language['before_script'] + ":")
wTree.get_widget("post_label").set_label(language['after_script'] + ":")
wTree.get_widget("disconnect_label").set_label(language['disconnect_script']
+ ":")
wTree.get_widget("window1").hide()
pre_entry = wTree.get_widget("pre_entry")
post_entry = wTree.get_widget("post_entry")
disconnect_entry = wTree.get_widget("disconnect_entry")
pre_entry.set_text(none_to_blank(script_info.get("pre_entry")))
post_entry.set_text(none_to_blank(script_info.get("post_entry")))
disconnect_entry.set_text(none_to_blank(script_info.get("disconnect_entry")))
dialog.show_all()
result = dialog.run()
if result == 1:
script_info["pre_entry"] = blank_to_none(pre_entry.get_text())
script_info["post_entry"] = blank_to_none(post_entry.get_text())
script_info["disconnect_entry"] = blank_to_none(disconnect_entry.get_text())
write_scripts(network, network_type, script_info)
dialog.destroy()
if __name__ == '__main__':
if os.getuid() != 0:
print "Root privileges are required to configure scripts. Exiting."
sys.exit(0)
main(sys.argv)

1463
wicd/daemon.py Normal file

File diff suppressed because it is too large Load Diff

0
wicd/dbusmanager.py Normal file
View File

903
wicd/gui.py Normal file
View File

@@ -0,0 +1,903 @@
#!/usr/bin/python
""" Wicd GUI module.
Module containg all the code (other than the tray icon) related to the
Wicd user interface.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
import sys
import time
import gobject
import pango
import gtk
import gtk.glade
from dbus import DBusException
from dbus import version as dbus_version
import wicd.misc
import wicd.wpath
from wicd.misc import noneToString, noneToBlankString, stringToBoolean, checkboxTextboxToggle
from wicd.netentry import WiredNetworkEntry, WirelessNetworkEntry
from wicd.prefs import PreferencesDialog
from wicd.dbusmanager import DBusManager
if __name__ == '__main__':
wpath.chdir(__file__)
try:
import pygtk
pygtk.require("2.0")
except:
pass
if not dbus_version or (dbus_version < (0, 80, 0)):
import dbus.glib
else:
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
proxy_obj, daemon, wireless, wired, bus, config = [None for x in
range(0, 6)]
language = misc.get_language_list_gui()
def setup_dbus(dbus_man=None):
global bus, daemon, wireless, wired, config, dbus_manager
if dbus_man:
dbus_manager = dbus_man
else:
dbus_manager = DBusManager()
try:
dbus_manager.connect_to_dbus()
except DBusException:
print "Can't connect to the daemon, trying to start it automatically..."
misc.PromptToStartDaemon()
try:
dbus_manager.connect_to_dbus()
except DBusException:
error(None, "Could not connect to wicd's D-Bus interface. " +
"Make sure the daemon is started.")
sys.exit(1)
bus = dbus_manager.get_bus()
dbus_ifaces = dbus_manager.get_dbus_ifaces()
daemon = dbus_ifaces['daemon']
wireless = dbus_ifaces['wireless']
wired = dbus_ifaces['wired']
config = dbus_ifaces['config']
return True
def error(parent, message):
""" 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()
########################################
##### GTK EXTENSION CLASSES
########################################
class SmallLabel(gtk.Label):
def __init__(self, text=''):
gtk.Label.__init__(self, text)
self.set_size_request(50, -1)
class LabelEntry(gtk.HBox):
""" A label on the left with a textbox on the right. """
def __init__(self,text):
gtk.HBox.__init__(self)
self.entry = gtk.Entry()
self.entry.set_size_request(200, -1)
self.label = SmallLabel()
self.label.set_text(text)
self.label.set_size_request(170, -1)
self.pack_start(self.label, fill=False, expand=False)
self.pack_start(self.entry, fill=False, expand=False)
self.label.show()
self.entry.show()
self.entry.connect('focus-out-event', self.hide_characters)
self.entry.connect('focus-in-event', self.show_characters)
self.auto_hide_text = False
self.show()
def set_text(self, text):
# For compatibility...
self.entry.set_text(text)
def get_text(self):
return self.entry.get_text()
def set_auto_hidden(self, value):
self.entry.set_visibility(False)
self.auto_hide_text = value
def show_characters(self, widget=None, event=None):
# When the box has focus, show the characters
if self.auto_hide_text and widget:
self.entry.set_visibility(True)
def set_sensitive(self, value):
self.entry.set_sensitive(value)
self.label.set_sensitive(value)
def hide_characters(self, widget=None, event=None):
# When the box looses focus, hide them
if self.auto_hide_text and widget:
self.entry.set_visibility(False)
class GreyLabel(gtk.Label):
""" Creates a grey gtk.Label. """
def __init__(self):
gtk.Label.__init__(self)
def set_label(self, text):
self.set_markup("<span color=\"#666666\"><i>" + text + "</i></span>")
self.set_alignment(0, 0)
class WiredProfileChooser:
""" Class for displaying the wired profile chooser. """
def __init__(self):
""" Initializes and runs the wired profile chooser. """
# Import and init WiredNetworkEntry to steal some of the
# functions and widgets it uses.
wired_net_entry = WiredNetworkEntry(dbus_manager.get_dbus_ifaces())
dialog = gtk.Dialog(title = language['wired_network_found'],
flags = gtk.DIALOG_MODAL,
buttons = (gtk.STOCK_CONNECT, 1,
gtk.STOCK_CANCEL, 2))
dialog.set_has_separator(False)
dialog.set_size_request(400, 150)
instruct_label = gtk.Label(language['choose_wired_profile'] + ':\n')
stoppopcheckbox = gtk.CheckButton(language['stop_showing_chooser'])
wired_net_entry.is_full_gui = False
instruct_label.set_alignment(0, 0)
stoppopcheckbox.set_active(False)
# Remove widgets that were added to the normal WiredNetworkEntry
# so that they can be added to the pop-up wizard.
wired_net_entry.vbox_top.remove(wired_net_entry.hbox_temp)
wired_net_entry.vbox_top.remove(wired_net_entry.profile_help)
dialog.vbox.pack_start(instruct_label, fill=False, expand=False)
dialog.vbox.pack_start(wired_net_entry.profile_help, False, False)
dialog.vbox.pack_start(wired_net_entry.hbox_temp, False, False)
dialog.vbox.pack_start(stoppopcheckbox, False, False)
dialog.show_all()
wired_profiles = wired_net_entry.combo_profile_names
wired_net_entry.profile_help.hide()
if wired_net_entry.profile_list != None:
wired_profiles.set_active(0)
print "wired profiles found"
else:
print "no wired profiles found"
wired_net_entry.profile_help.show()
response = dialog.run()
if response == 1:
print 'reading profile ', wired_profiles.get_active_text()
config.ReadWiredNetworkProfile(wired_profiles.get_active_text())
wired.ConnectWired()
else:
if stoppopcheckbox.get_active():
daemon.SetForcedDisconnect(True)
dialog.destroy()
class appGui(object):
""" The main wicd GUI class. """
def __init__(self, dbus_man=None, standalone=False):
""" Initializes everything needed for the GUI. """
if not standalone:
setup_dbus(dbus_man)
gladefile = "data/wicd.glade"
self.wTree = gtk.glade.XML(gladefile)
dic = { "refresh_clicked" : self.refresh_networks,
"quit_clicked" : self.exit,
"disconnect_clicked" : self.disconnect_all,
"main_exit" : self.exit,
"cancel_clicked" : self.cancel_connect,
"connect_clicked" : self.connect_hidden,
"preferences_clicked" : self.settings_dialog,
"about_clicked" : self.about_dialog,
"create_adhoc_network_button_button" : self.create_adhoc_network,
"on_iface_menu_enable_wireless" : self.on_enable_wireless,
"on_iface_menu_disable_wireless" : self.on_disable_wireless,
"on_iface_menu_enable_wired" : self.on_enable_wired,
"on_iface_menu_disable_wired" : self.on_disable_wired,}
self.wTree.signal_autoconnect(dic)
# Set some strings in the GUI - they may be translated
label_instruct = self.wTree.get_widget("label_instructions")
label_instruct.set_label(language['select_a_network'])
probar = self.wTree.get_widget("progressbar")
probar.set_text(language['connecting'])
self.window = self.wTree.get_widget("window1")
self.network_list = self.wTree.get_widget("network_list_vbox")
self.status_area = self.wTree.get_widget("connecting_hbox")
self.status_bar = self.wTree.get_widget("statusbar")
self.status_area.hide_all()
if os.path.exists(wpath.etc + "wicd.png"):
self.window.set_icon_from_file(wpath.etc + "wicd.png")
self.statusID = None
self.first_dialog_load = True
self.is_visible = True
self.pulse_active = False
self.standalone = standalone
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)
self.window.connect('key-release-event', self.key_event)
if not wireless.IsWirelessUp():
self.wTree.get_widget("iface_menu_disable_wireless").hide()
else:
self.wTree.get_widget("iface_menu_enable_wireless").hide()
if not wired.IsWiredUp():
self.wTree.get_widget("iface_menu_disable_wired").hide()
else:
self.wTree.get_widget("iface_menu_enable_wired").hide()
size = config.ReadWindowSize("main")
width = size[0]
height = size[1]
if width > -1 and height > -1:
self.window.resize(int(width), int(height))
gobject.timeout_add(400, self.update_statusbar)
def create_adhoc_network(self, widget=None):
""" Shows a dialog that creates a new adhoc network. """
print "Starting the Ad-Hoc Network Creation Process..."
dialog = gtk.Dialog(title = language['create_adhoc_network'],
flags = gtk.DIALOG_MODAL,
buttons=(gtk.STOCK_OK, 1, gtk.STOCK_CANCEL, 2))
dialog.set_has_separator(False)
dialog.set_size_request(400, -1)
self.chkbox_use_encryption = gtk.CheckButton(language['use_wep_encryption'])
self.chkbox_use_encryption.set_active(False)
ip_entry = LabelEntry(language['ip'] + ':')
essid_entry = LabelEntry(language['essid'] + ':')
channel_entry = LabelEntry(language['channel'] + ':')
self.key_entry = LabelEntry(language['key'] + ':')
self.key_entry.set_auto_hidden(True)
self.key_entry.set_sensitive(False)
chkbox_use_ics = gtk.CheckButton(language['use_ics'])
self.chkbox_use_encryption.connect("toggled",
self.toggle_encrypt_check)
channel_entry.entry.set_text('3')
essid_entry.entry.set_text('My_Adhoc_Network')
ip_entry.entry.set_text('169.254.12.10') # Just a random IP
vbox_ah = gtk.VBox(False, 0)
vbox_ah.pack_start(self.chkbox_use_encryption, False, False)
vbox_ah.pack_start(self.key_entry, False, False)
vbox_ah.show()
dialog.vbox.pack_start(essid_entry)
dialog.vbox.pack_start(ip_entry)
dialog.vbox.pack_start(channel_entry)
dialog.vbox.pack_start(chkbox_use_ics)
dialog.vbox.pack_start(vbox_ah)
dialog.vbox.set_spacing(5)
dialog.show_all()
response = dialog.run()
if response == 1:
wireless.CreateAdHocNetwork(essid_entry.entry.get_text(),
channel_entry.entry.get_text(),
ip_entry.entry.get_text(), "WEP",
self.key_entry.entry.get_text(),
self.chkbox_use_encryption.get_active(),
False) #chkbox_use_ics.get_active())
dialog.destroy()
def toggle_encrypt_check(self, widget=None):
""" Toggles the encryption key entry box for the ad-hoc dialog. """
self.key_entry.set_sensitive(self.chkbox_use_encryption.get_active())
def disconnect_all(self, widget=None):
""" Disconnects from any active network. """
daemon.Disconnect()
def about_dialog(self, widget, event=None):
""" Displays an about dialog. """
dialog = gtk.AboutDialog()
dialog.set_name("Wicd")
dialog.set_version(daemon.Hello())
dialog.set_authors([ "Adam Blackburn", "Dan O'Reilly" ])
dialog.set_website("http://wicd.sourceforge.net")
dialog.run()
dialog.destroy()
def key_event (self, widget, event=None):
""" Handle key-release-events. """
if event.state & gtk.gdk.CONTROL_MASK and \
gtk.gdk.keyval_name(event.keyval) in ["w", "q"]:
self.exit()
def settings_dialog(self, widget, event=None):
""" Displays a general settings dialog. """
pref = PreferencesDialog(self.wTree, dbus_manager.get_dbus_ifaces())
if pref.run() == 1:
pref.save_results()
pref.hide()
def connect_hidden(self, widget):
""" Prompts the user for a hidden network, then scans for it. """
dialog = gtk.Dialog(title=language['hidden_network'],
flags=gtk.DIALOG_MODAL,
buttons=(gtk.STOCK_CONNECT, 1, gtk.STOCK_CANCEL, 2))
dialog.set_has_separator(False)
lbl = gtk.Label(language['hidden_network_essid'])
textbox = gtk.Entry()
dialog.vbox.pack_start(lbl)
dialog.vbox.pack_start(textbox)
dialog.show_all()
button = dialog.run()
if button == 1:
answer = textbox.get_text()
dialog.destroy()
self.refresh_networks(None, True, answer)
else:
dialog.destroy()
def on_enable_wireless(self, widget):
""" Called when the Enable Wireless Interface button is clicked. """
success = wireless.EnableWirelessInterface()
if success:
enable_item = self.wTree.get_widget("iface_menu_enable_wireless")
disable_item = self.wTree.get_widget("iface_menu_disable_wireless")
enable_item.hide()
disable_item.show()
else:
error(self.window, "Failed to enable wireless interface.")
def on_disable_wireless(self, widget):
""" Called when the Disable Wireless Interface button is clicked. """
success = wireless.DisableWirelessInterface()
if success:
enable_item = self.wTree.get_widget("iface_menu_enable_wireless")
disable_item = self.wTree.get_widget("iface_menu_disable_wireless")
enable_item.show()
disable_item.hide()
else:
error(self.window, "Failed to disable wireless interface.")
def on_enable_wired(self, widget):
""" Called when the Enable Wired Interface button is clicked. """
success = wired.EnableWiredInterface()
if success:
enable_item = self.wTree.get_widget("iface_menu_enable_wired")
disable_item = self.wTree.get_widget("iface_menu_disable_wired")
enable_item.hide()
disable_item.show()
else:
error(self.window, "Failed to enable wired interface.")
def on_disable_wired(self, widget):
""" Called when the Disable Wired Interface button is clicked. """
success = wired.DisableWiredInterface()
if success:
enable_item = self.wTree.get_widget("iface_menu_enable_wired")
disable_item = self.wTree.get_widget("iface_menu_disable_wired")
enable_item.show()
disable_item.hide()
else:
error(self.window, "Failed to disable wired interface.")
def cancel_connect(self, widget):
""" Alerts the daemon to cancel the connection process. """
#should cancel a connection if there
#is one in progress
cancel_button = self.wTree.get_widget("cancel_button")
cancel_button.set_sensitive(False)
daemon.CancelConnect()
# Prevents automatic reconnecting if that option is enabled
daemon.SetForcedDisconnect(True)
def pulse_progress_bar(self):
""" Pulses the progress bar while connecting to a network. """
if not self.pulse_active:
return False
if not self.is_visible:
return True
try:
self.wTree.get_widget("progressbar").pulse()
except:
pass
return True
def update_statusbar(self):
""" Updates the status bar. """
if not self.is_visible:
return True
fast = self.fast
wired_connecting = wired.CheckIfWiredConnecting()
wireless_connecting = wireless.CheckIfWirelessConnecting()
self.connecting = wired_connecting or wireless_connecting
if self.connecting:
if not self.pulse_active:
self.pulse_active = True
gobject.timeout_add(100, self.pulse_progress_bar)
self.network_list.set_sensitive(False)
self.status_area.show_all()
if self.statusID:
self.status_bar.remove(1, self.statusID)
if wireless_connecting:
if not fast:
iwconfig = wireless.GetIwconfig()
else:
iwconfig = ''
self.set_status(wireless.GetCurrentNetwork(iwconfig, fast) + ': ' +
language[str(wireless.CheckWirelessConnectingMessage())])
if wired_connecting:
self.set_status(language['wired_network'] + ': ' +
language[str(wired.CheckWiredConnectingMessage())])
return True
else:
if self.pulse_active:
self.pulse_progress_bar()
self.pulse_active = False
self.network_list.set_sensitive(True)
self.status_area.hide_all()
if self.statusID:
self.status_bar.remove(1, self.statusID)
# Determine connection status.
if self.check_for_wired(wired.GetWiredIP(fast)):
return True
if not fast:
iwconfig = wireless.GetIwconfig()
else:
iwconfig = ''
if self.check_for_wireless(iwconfig,
wireless.GetWirelessIP(fast)):
return True
self.set_status(language['not_connected'])
return True
def update_connect_buttons(self, state=None, x=None, force_check=False):
""" Updates the connect/disconnect buttons for each network entry. """
if not state:
state, x = daemon.GetConnectionStatus()
if self.prev_state != state or force_check:
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. """
if wired_ip and wired.CheckPluggedIn(self.fast):
self.set_status(language['connected_to_wired'].replace('$A',
wired_ip))
return True
else:
return False
def check_for_wireless(self, iwconfig, wireless_ip):
""" Determine if wireless is active, and if yes, set the status. """
if not wireless_ip:
return False
network = wireless.GetCurrentNetwork(iwconfig, self.fast)
if not network:
return False
network = str(network)
if daemon.GetSignalDisplayType() == 0:
strength = wireless.GetCurrentSignalStrength(iwconfig, self.fast)
else:
strength = wireless.GetCurrentDBMStrength(iwconfig, self.fast)
if strength is None:
return False
strength = str(strength)
ip = str(wireless_ip)
self.set_status(language['connected_to_wireless'].replace
('$A', network).replace
('$B', daemon.FormatSignalForPrinting(strength)).replace
('$C', wireless_ip))
return True
def set_status(self, msg):
""" Sets the status bar message for the GUI. """
self.statusID = self.status_bar.push(1, msg)
def dbus_scan_finished(self):
""" Calls for a non-fresh update of the gui window.
This method is called after the daemon runs an automatic
rescan.
"""
if not self.connecting:
self.refresh_networks(fresh=False)
def dbus_scan_started(self):
self.network_list.set_sensitive(False)
def refresh_networks(self, widget=None, fresh=True, hidden=None):
""" Refreshes the network list.
If fresh=True, scans for wireless networks and displays the results.
If a ethernet connection is available, or the user has chosen to,
displays a Wired Network entry as well.
If hidden isn't None, will scan for networks after running
iwconfig <wireless interface> essid <hidden>.
"""
print "refreshing..."
self.network_list.set_sensitive(False)
self.wait_for_events()
printLine = False # We don't print a separator by default.
# Remove stuff already in there.
for z in self.network_list:
self.network_list.remove(z)
z.destroy()
del z
if wired.CheckPluggedIn(self.fast) or wired.GetAlwaysShowWiredInterface():
printLine = True # In this case we print a separator.
wirednet = WiredNetworkEntry(dbus_manager.get_dbus_ifaces())
self.network_list.pack_start(wirednet, False, False)
wirednet.connect_button.connect("button-press-event", self.connect,
"wired", 0, wirednet)
wirednet.disconnect_button.connect("button-press-event", self.disconnect,
"wired", 0, wirednet)
wirednet.advanced_button.connect("button-press-event",
self.edit_advanced, "wired", 0,
wirednet)
# Scan
if fresh:
# Even if it is None, it can still be passed.
wireless.SetHiddenNetworkESSID(noneToString(hidden))
wireless.Scan()
num_networks = wireless.GetNumberOfNetworks()
instruct_label = self.wTree.get_widget("label_instructions")
if num_networks > 0:
instruct_label.show()
for x in range(0, num_networks):
if printLine:
sep = gtk.HSeparator()
self.network_list.pack_start(sep, padding=10, fill=False,
expand=False)
sep.show()
else:
printLine = True
tempnet = WirelessNetworkEntry(x, dbus_manager.get_dbus_ifaces())
self.network_list.pack_start(tempnet, False, False)
tempnet.connect_button.connect("button-press-event",
self.connect, "wireless", x,
tempnet)
tempnet.disconnect_button.connect("button-press-event",
self.disconnect, "wireless",
x, tempnet)
tempnet.advanced_button.connect("button-press-event",
self.edit_advanced, "wireless",
x, tempnet)
else:
instruct_label.hide()
if wireless.GetKillSwitchEnabled():
label = gtk.Label(language['killswitch_enabled'] + ".")
else:
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):
""" Verifies and saves the settings for the network entry. """
entry = networkentry.advanced_dialog
entlist = []
# First make sure all the Addresses entered are valid.
if entry.chkbox_static_ip.get_active():
entlist = [ent for ent in [entry.txt_ip, entry.txt_netmask,
entry.txt_gateway]]
if entry.chkbox_static_dns.get_active() and \
not entry.chkbox_global_dns.get_active():
entlist.append(entry.txt_dns_1)
# Only append additional dns entries if they're entered.
for ent in [entry.txt_dns_2, entry.txt_dns_3]:
if ent.get_text() != "":
entlist.append(ent)
for lblent in entlist:
if not misc.IsValidIP(lblent.get_text()):
error(self.window, language['invalid_address'].
replace('$A', lblent.label.get_label()))
return False
# Now save the settings.
if nettype == "wireless":
if not self.save_wireless_settings(networkid, entry, networkentry):
return False
elif nettype == "wired":
if not self.save_wired_settings(entry):
return False
return True
def save_wired_settings(self, entry):
""" Saved wired network settings. """
if entry.chkbox_static_ip.get_active():
entry.set_net_prop("ip", noneToString(entry.txt_ip.get_text()))
entry.set_net_prop("netmask", noneToString(entry.txt_netmask.get_text()))
entry.set_net_prop("gateway", noneToString(entry.txt_gateway.get_text()))
else:
entry.set_net_prop("ip", '')
entry.set_net_prop("netmask", '')
entry.set_net_prop("gateway", '')
if entry.chkbox_static_dns.get_active() and \
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()))
elif entry.chkbox_static_dns.get_active() and \
entry.chkbox_global_dns.get_active():
entry.set_net_prop('use_static_dns', True)
entry.set_net_prop('use_global_dns', True)
else:
entry.set_net_prop('use_static_dns', False)
entry.set_net_prop("dns1", '')
entry.set_net_prop("dns2", '')
entry.set_net_prop("dns3", '')
config.SaveWiredNetworkProfile(entry.prof_name)
return True
def save_wireless_settings(self, networkid, entry, netent):
""" Save wireless network settings. """
# Check encryption info
if entry.chkbox_encryption.get_active():
print "setting encryption info..."
encryption_info = entry.encryption_info
encrypt_methods = misc.LoadEncryptionMethods()
entry.set_net_prop("enctype",
encrypt_methods[entry.combo_encryption.
get_active()][1])
for x in encryption_info:
if encryption_info[x].get_text() == "":
error(self.window, language['encrypt_info_missing'])
return False
entry.set_net_prop(x, noneToString(encryption_info[x].
get_text()))
elif not entry.chkbox_encryption.get_active() and \
wireless.GetWirelessProperty(networkid, "encryption"):
error(self.window, language['enable_encryption'])
return False
else:
print 'encryption is ' + str(wireless.GetWirelessProperty(networkid,
"encryption"))
print "no encryption specified..."
entry.set_net_prop("enctype", "None")
entry.set_net_prop("automatic",
noneToString(netent.chkbox_autoconnect.get_active()))
# Save IP info
if entry.chkbox_static_ip.get_active():
entry.set_net_prop("ip", noneToString(entry.txt_ip.get_text()))
entry.set_net_prop("netmask",
noneToString(entry.txt_netmask.get_text()))
entry.set_net_prop("gateway",
noneToString(entry.txt_gateway.get_text()))
else:
# Blank the values
entry.set_net_prop("ip", '')
entry.set_net_prop("netmask", '')
entry.set_net_prop("gateway", '')
# Save DNS info
if entry.chkbox_static_dns.get_active() and \
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()))
elif entry.chkbox_static_dns.get_active() and \
entry.chkbox_global_dns.get_active():
entry.set_net_prop('use_static_dns', True)
entry.set_net_prop('use_global_dns', True)
else:
entry.set_net_prop('use_static_dns', False)
entry.set_net_prop('use_global_dns', False)
entry.set_net_prop('dns1', '')
entry.set_net_prop('dns2', '')
entry.set_net_prop('dns3', '')
if entry.chkbox_global_settings.get_active():
entry.set_net_prop('use_settings_globally', True)
else:
entry.set_net_prop('use_settings_globally', False)
config.RemoveGlobalEssidEntry(networkid)
config.SaveWirelessNetworkProfile(networkid)
return True
def edit_advanced(self, widget, event, ttype, networkid, networkentry):
""" Display the advanced settings dialog.
Displays the advanced settings dialog and saves any changes made.
If errors occur in the settings, an error message will be displayed
and the user won't be able to save the changes until the errors
are fixed.
"""
dialog = networkentry.advanced_dialog
dialog.set_values()
dialog.show_all()
while True:
if self.run_settings_dialog(dialog, ttype, networkid, networkentry):
break
dialog.hide()
def run_settings_dialog(self, dialog, nettype, networkid, networkentry):
""" Runs the settings dialog.
Runs the settings dialog and returns True if settings are saved
successfully, and false otherwise.
"""
result = dialog.run()
if result == gtk.RESPONSE_ACCEPT:
if self.save_settings(nettype, networkid, networkentry):
return True
else:
return False
return True
def check_encryption_valid(self, networkid, entry):
""" Make sure that encryption settings are properly filled in. """
# Make sure no entries are left blank
if entry.chkbox_encryption.get_active():
encryption_info = entry.encryption_info
for x in encryption_info:
if encryption_info[x].get_text() == "":
error(self.window, language['encrypt_info_missing'])
return False
# Make sure the checkbox is checked when it should be
elif not entry.chkbox_encryption.get_active() and \
wireless.GetWirelessProperty(networkid, "encryption"):
error(self.window, language['enable_encryption'])
return False
return True
def connect(self, widget, event, nettype, networkid, networkentry):
""" Initiates the connection process in the daemon. """
cancel_button = self.wTree.get_widget("cancel_button")
cancel_button.set_sensitive(True)
if nettype == "wireless":
if not self.check_encryption_valid(networkid,
networkentry.advanced_dialog):
return False
wireless.ConnectWireless(networkid)
elif nettype == "wired":
wired.ConnectWired()
self.update_statusbar()
def disconnect(self, widget, event, nettype, networkid, networkentry):
""" Disconnects from the given network.
Keyword arguments:
widget -- The disconnect button that was pressed.
event -- unused
nettype -- "wired" or "wireless", depending on the network entry type.
networkid -- unused
networkentry -- The NetworkEntry containing the disconnect button.
"""
widget.hide()
networkentry.connect_button.show()
if nettype == "wired":
wired.DisconnectWired()
else:
wireless.DisconnectWireless()
def wait_for_events(self, amt=0):
""" Wait for any pending gtk events to finish before moving on.
Keyword arguments:
amt -- a number specifying the number of ms to wait before checking
for pending events.
"""
time.sleep(amt)
while gtk.events_pending():
gtk.main_iteration()
def exit(self, widget=None, event=None):
""" Hide the wicd GUI.
This method hides the wicd GUI and writes the current window size
to disc for later use. This method normally does NOT actually
destroy the GUI, it just hides it.
"""
self.window.hide()
[width, height] = self.window.get_size()
config.WriteWindowSize(width, height, "main")
if self.standalone:
self.window.destroy()
sys.exit(0)
self.is_visible = False
daemon.SetGUIOpen(False)
self.wait_for_events()
return True
def show_win(self):
""" Brings the GUI out of the hidden state.
Method to show the wicd GUI, alert the daemon that it is open,
and refresh the network list.
"""
self.window.show()
self.wait_for_events()
self.is_visible = True
daemon.SetGUIOpen(True)
self.wait_for_events(0.1)
self.window.grab_focus()
gobject.idle_add(self.refresh_networks)
if __name__ == '__main__':
setup_dbus()
app = appGui(standalone=True)
bus.add_signal_receiver(app.dbus_scan_finished, 'SendEndScanSignal',
'org.wicd.daemon')
bus.add_signal_receiver(app.dbus_scan_started, 'SendStartScanSignal',
'org.wicd.daemon')
bus.add_signal_receiver(app.update_connect_buttons, 'StatusChanged',
'org.wicd.daemon')
gtk.main()

175
wicd/logfile.py Normal file
View File

@@ -0,0 +1,175 @@
#!/usr/bin/python
#
# Copyright (C) 1999-2006 Keith Dart <keith@kdart.com>
# Copyright (C) 2008 Dan O'Reilly <oreilldf@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
"""
Managing logfile rotation. A ManagedLog object is a file-like object that
rotates itself when a maximum size is reached.
"""
import sys
import os
import time
class SizeError(IOError):
pass
class LogFile(file):
"""LogFile(name, [mode="w"], [maxsize=360000])
Opens a new file object. After writing <maxsize> bytes a SizeError will be
raised. """
def __init__(self, name, mode="a", maxsize=360000):
super(LogFile, self).__init__(name, mode)
self.maxsize = maxsize
self.eol = True
try:
self.written = os.fstat(self.fileno())[6]
except OSError:
self.written = 0
def write(self, data):
self.written += len(data)
data = data.decode('utf-8').encode('utf-8')
if len(data) <= 0: return
if self.eol:
super(LogFile, self).write(self.get_time() + ' :: ')
self.eol = False
if data[-1] == '\n':
self.eol = True
data = data[:-1]
super(LogFile, self).write(data.replace(
'\n', '\n' + self.get_time() + ' :: '))
if self.eol:
super(LogFile, self).write('\n')
self.flush()
if self.written > self.maxsize:
raise SizeError
def get_time(self):
""" Return a string with the current time nicely formatted.
The format of the returned string is yyyy/mm/dd HH:MM:SS
"""
x = time.localtime()
return ''.join([
str(x[0]).rjust(4, '0'), '/', str(x[1]).rjust(2, '0'), '/',
str(x[2]).rjust(2, '0'), ' ', str(x[3]).rjust(2, '0'), ':',
str(x[4]).rjust(2, '0'), ':', str(x[5]).rjust(2, '0')])
def rotate(self):
return rotate(self)
def note(self, text):
"""Writes a specially formated note text to the file.The note starts
with the string '\\n#*=' so you can easily filter them. """
self.write("\n#*===== %s =====\n" % (text,))
class ManagedLog(object):
"""ManagedLog(name, [maxsize=360000], [maxsave=9])
A ManagedLog instance is a persistent log object. Write data with the
write() method. The log size and rotation is handled automatically.
"""
def __init__(self, name, maxsize=360000, maxsave=3):
self._lf = LogFile(name, "a", maxsize)
self.maxsave = maxsave
def __repr__(self):
return "%s(%r, %r, %r)" % (self.__class__.__name__, self._lf.name,
self._lf.maxsize, self.maxsave)
def write(self, data):
try:
self._lf.write(data)
except SizeError:
self._lf = rotate(self._lf, self.maxsave)
def note(self, data):
try:
self._lf.note(data)
except SizeError:
self._lf = rotate(self._lf, self.maxsave)
def written(self):
return self._lf.written
def rotate(self):
self._lf = rotate(self._lf, self.maxsave)
# auto-delegate remaining methods (but you should not read or seek an open
# log file).
def __getattr__(self, name):
return getattr(self._lf, name)
# useful for logged stdout for daemon processes
class ManagedStdio(ManagedLog):
def write(self, data):
try:
self._lf.write(data)
except SizeError:
sys.stdout.flush()
sys.stderr.flush()
self._lf = rotate(self._lf, self.maxsave)
fd = self._lf.fileno()
os.dup2(fd, 1)
os.dup2(fd, 2)
sys.stdout = sys.stderr = self
def rotate(fileobj, maxsave=9):
name = fileobj.name
mode = fileobj.mode
maxsize = fileobj.maxsize
fileobj.close()
shiftlogs(name, maxsave)
return LogFile(name, mode, maxsize)
# assumes basename logfile is closed.
def shiftlogs(basename, maxsave):
topname = "%s.%d" % (basename, maxsave)
if os.path.isfile(topname):
os.unlink(topname)
for i in range(maxsave, 0, -1):
oldname = "%s.%d" % (basename, i)
newname = "%s.%d" % (basename, i+1)
try:
os.rename(oldname, newname)
except OSError:
pass
try:
os.rename(basename, "%s.1" % (basename))
except OSError:
pass
def open(name, maxsize=360000, maxsave=9):
return ManagedLog(name, maxsize, maxsave)
def writelog(logobj, data):
try:
logobj.write(data)
except SizeError:
return rotate(logobj)
else:
return logobj

493
wicd/misc.py Normal file
View File

@@ -0,0 +1,493 @@
""" Misc - miscellaneous functions for wicd """
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
import locale
import gettext
import sys
from subprocess import Popen, STDOUT, PIPE
import subprocess
import commands
import wicd.wpath as wpath
if __name__ == '__main__':
wpath.chdir(__file__)
NOT_CONNECTED = 0
CONNECTING = 1
WIRELESS = 2
WIRED = 3
SUSPENDED = 4
AUTO = 0
DHCLIENT = 1
DHCPCD = 2
PUMP = 3
ETHTOOL = 1
MIITOOL = 2
IP = 1
ROUTE = 2
class WicdError(Exception):
pass
def Run(cmd, include_stderr=False, return_pipe=False):
""" Run a command.
Runs the given command, returning either the output
of the program, or a pipe to read output from.
keyword arguments --
cmd - The command to execute
include_std_err - Boolean specifying if stderr should
be included in the pipe to the cmd.
return_pipe - Boolean specifying if a pipe to the
command should be returned. If it is
false, all that will be returned is
one output string from the command.
"""
cmd = to_unicode(str(cmd))
if include_stderr:
err = STDOUT
fds = True
else:
err = None
fds = False
f = Popen(cmd, shell=True, stdout=PIPE, stderr=err, close_fds=fds)
if return_pipe:
return f.stdout
else:
return f.communicate()[0]
def LaunchAndWait(cmd):
""" Launches the given program with the given arguments, then blocks. """
subprocess.call(cmd)
def IsValidIP(ip):
""" Make sure an entered IP is valid """
if ip != None:
if ip.count('.') == 3:
ipNumbers = ip.split('.')
for number in ipNumbers:
if not number.isdigit() or int(number) > 255:
return False
return ipNumbers
return False
def PromptToStartDaemon():
""" Prompt the user to start the daemon """
daemonloc = wpath.bin + 'launchdaemon.sh'
sudo_prog = choose_sudo_prog()
if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
msg = '--message'
else:
msg = '--caption'
sudo_args = [sudo_prog, msg,
'Wicd needs to access your computer\'s network cards.',
daemonloc]
os.spawnvpe(os.P_WAIT, sudo_prog, sudo_args, os.environ)
def RunRegex(regex, string):
""" runs a regex search on a string """
m = regex.search(string)
if m:
return m.groups()[0]
else:
return None
def WriteLine(my_file, text):
""" write a line to a file """
my_file.write(text + "\n")
def ExecuteScript(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 """
if not os.path.exists(filename):
return None
my_file = open(filename,'r')
data = my_file.read().strip()
my_file.close()
return str(data)
def to_bool(var):
""" Convert a string to type bool, but make "False"/"0" become False. """
if var in ("False", "0"):
var = False
else:
var = bool(var)
return var
def Noneify(variable):
""" Convert string types to either None or booleans"""
#set string Nones to real Nones
if variable in ("None", "", None):
return None
if variable in ("False", "0"):
return False
if variable in ("True", "1"):
return True
return variable
def ParseEncryption(network):
""" Parse through an encryption template file
Parses an encryption template, reading in a network's info
and creating a config file for it
"""
enctemplate = open("encryption/templates/" + network["enctype"])
template = enctemplate.readlines()
# Set these to nothing so that we can hold them outside the loop
z = "ap_scan=1\n"
# Loop through the lines in the template, selecting ones to use
for y, x in enumerate(template):
x = x.strip("\n")
if y > 4:
# replace values
x = x.replace("$_SCAN","0")
for t in network:
# Don't bother if z's value is None cause it will cause errors
if Noneify(network[t]) is not None:
x = x.replace("$_" + str(t).upper(), str(network[t]))
z = z + "\n" + x
# Write the data to the files then chmod them so they can't be read
# by normal users.
file = open(wpath.networks + network["bssid"].replace(":", "").lower(), "w")
os.chmod(wpath.networks + network["bssid"].replace(":", "").lower(), 0600)
os.chown(wpath.networks + network["bssid"].replace(":", "").lower(), 0, 0)
# We could do this above, but we'd like to read protect
# them before we write, so that it can't be read.
file.write(z)
file.close()
def LoadEncryptionMethods():
""" Load encryption methods from configuration files
Loads all the encryption methods from the template files
in /encryption/templates into a data structure. To be
loaded, the template must be listed in the "active" file.
"""
def parse_ent(line, key):
return line.replace(key, "").replace("=", "").strip()
encryptionTypes = []
try:
enctypes = open("encryption/templates/active","r").readlines()
except IOError, e:
print "Fatal Error: template index file is missing."
raise IOError(e)
# Parse each encryption method
for x in enctypes:
x = x.strip()
try:
f = open("encryption/templates/" + x, "r")
except IOError:
print 'Failed to load encryption type ' + str(x)
continue
line = f.readlines()
f.close()
cur_type = {}
cur_type[0] = parse_ent(line[0], "name")
cur_type[1] = x
cur_type[2] = {}
# Find the line containing our required fields.
i = 1
try:
while not line[i].startswith("require"):
i += 1
except IndexError:
print "Bad encryption template: Couldn't find 'require' line"
requiredFields = parse_ent(line[i], "require")
requiredFields = requiredFields.split(" ")
# Get the required fields.
index = -1
for current in requiredFields:
# The pretty names will start with an * so we can
# separate them with that.
if current[0] == "*":
# Make underscores spaces
# and remove the *
cur_type[2][index][0] = current.replace("_", " ").lstrip("*")
else:
# Add to the list of things that are required.
index = len(cur_type[2])
cur_type[2][index] = {}
cur_type[2][index][1] = current
# Add the current type to the dict of encryption types.
encryptionTypes.append(cur_type)
return encryptionTypes
def noneToString(text):
""" Convert None, "None", or "" to string type "None"
Used for putting text in a text box. If the value to put in is 'None',
the box will be blank.
"""
if text in (None, ""):
return "None"
else:
return str(text)
def get_gettext():
""" Set up gettext for translations. """
# Borrowed from an excellent post on how to do this at
# http://www.learningpython.com/2006/12/03/translating-your-pythonpygtk-application/
local_path = os.path.realpath(os.path.dirname(sys.argv[0])) + \
'/translations'
langs = []
lc, encoding = locale.getdefaultlocale()
if (lc):
langs = [lc]
osLanguage = os.environ.get('LANGUAGE', None)
if (osLanguage):
langs += osLanguage.split(":")
langs += ["en_US"]
lang = gettext.translation('wicd', local_path, languages=langs,
fallback=True)
_ = lang.gettext
return _
def to_unicode(x):
""" Attempts to convert a string to utf-8. """
try: # This may never fail, but let's be safe
encoding = locale.getpreferredencoding()
except:
# Just guess utf-8 if it fails.
encoding = 'utf-8'
ret = x.decode(encoding, 'replace').encode('utf-8')
return ret
def RenameProcess(new_name):
if sys.platform != 'linux2':
print 'Unsupported platform'
return False
try:
import ctypes
is_64 = os.path.exists('/lib64/libc.so.6')
if is_64:
libc = ctypes.CDLL('/lib64/libc.so.6')
else:
libc = ctypes.CDLL('/lib/libc.so.6')
libc.prctl(15, new_name, 0, 0, 0)
return True
except:
return False
def detect_desktop_environment():
desktop_environment = 'generic'
if os.environ.get('KDE_FULL_SESSION') == 'true':
desktop_environment = 'kde'
elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
desktop_environment = 'gnome'
else:
try:
info = commands.getoutput('xprop -root _DT_SAVE_MODE')
if ' = "xfce4"' in info:
desktop_environment = 'xfce'
except (OSError, RuntimeError):
pass
return desktop_environment
def choose_sudo_prog():
desktop_env = detect_desktop_environment()
env_path = os.environ['PATH'].split(":")
if desktop_env == "kde":
paths = []
for p in env_path:
paths.extend([p + '/kdesu', p + '/kdesudo', p + '/ktsuss'])
else:
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
raise WicdError("Couldn't find graphical sudo program.")
def get_language_list_gui():
""" Returns a dict of translatable strings used by the GUI.
translations are done at http://wicd.net/translator. Please
translate if you can.
"""
_ = get_gettext()
language = {}
language['connect'] = _("Connect")
language['ip'] = _("IP")
language['netmask'] = _("Netmask")
language['gateway'] = _('Gateway')
language['dns'] = _('DNS')
language['use_static_ip'] = _('Use Static IPs')
language['use_static_dns'] = _('Use Static DNS')
language['use_encryption'] = _('Use Encryption')
language['advanced_settings'] = _('Advanced Settings')
language['wired_network'] = _('Wired Network')
language['wired_network_instructions'] = _('To connect to a wired network,'
' you must create a network profile. To create a network profile, type a'
' name that describes this network, and press Add.')
language['automatic_connect'] = _('Automatically connect to this network')
language['secured'] = _('Secured')
language['unsecured'] = _('Unsecured')
language['channel'] = _('Channel')
language['preferences'] = _('Preferences')
language['wpa_supplicant_driver'] = _('WPA Supplicant Driver')
language['wireless_interface'] = _('Wireless Interface')
language['wired_interface'] = _('Wired Interface')
language['hidden_network'] = _('Hidden Network')
language['hidden_network_essid'] = _('Hidden Network ESSID')
language['connected_to_wireless'] = _('Connected to $A at $B (IP: $C)')
language['connected_to_wired'] = _('Connected to wired network (IP: $A)')
language['not_connected'] = _('Not connected')
language['no_wireless_networks_found'] = _('No wireless networks found.')
language['killswitch_enabled'] = _('Wireless Kill Switch Enabled')
language['key'] = _('Key')
language['username'] = _('Username')
language['password'] = _('Password')
language['anonymous_identity'] = _('Anonymous Identity')
language['identity'] = _('Identity')
language['authentication'] = _('Authentication')
language['path_to_pac_file'] = _('Path to PAC File')
language['select_a_network'] = _('Choose from the networks below:')
language['connecting'] = _('Connecting...')
language['wired_always_on'] = _('Always show wired interface')
language['auto_reconnect'] = _('Automatically reconnect on connection loss')
language['create_adhoc_network'] = _('Create an Ad-Hoc Network')
language['essid'] = _('ESSID')
language['use_wep_encryption'] = _('Use Encryption (WEP only)')
language['before_script'] = _('Run script before connect')
language['after_script'] = _('Run script after connect')
language['disconnect_script'] = _('Run disconnect script')
language['script_settings'] = _('Scripts')
language['use_ics'] = _('Activate Internet Connection Sharing')
language['madwifi_for_adhoc'] = _('Check if using madwifi/atheros drivers')
language['default_wired'] = _('Use as default profile (overwrites any previous default)')
language['use_debug_mode'] = _('Enable debug mode')
language['use_global_dns'] = _('Use global DNS servers')
language['use_default_profile'] = _('Use default profile on wired autoconnect')
language['show_wired_list'] = _('Prompt for profile on wired autoconnect')
language['use_last_used_profile'] = _('Use last used profile on wired autoconnect')
language['choose_wired_profile'] = _('Select or create a wired profile to connect with')
language['wired_network_found'] = _('Wired connection detected')
language['stop_showing_chooser'] = _('Stop Showing Autoconnect pop-up temporarily')
language['display_type_dialog'] = _('Use dBm to measure signal strength')
language['scripts'] = _('Scripts')
language['invalid_address'] = _('Invalid address in $A entry.')
language['global_settings'] = _('Use these settings for all networks sharing this essid')
language['encrypt_info_missing'] = _('Required encryption information is missing.')
language['enable_encryption'] = _('This network requires encryption to be enabled.')
language['wicd_auto_config'] = _('Automatic (recommended)')
language["gen_settings"] = _("General Settings")
language["ext_programs"] = _("External Programs")
language["dhcp_client"] = _("DHCP Client")
language["wired_detect"] = _("Wired Link Detection")
language["route_flush"] = _("Route Table Flushing")
language['0'] = _('0')
language['1'] = _('1')
language['2'] = _('2')
language['3'] = _('3')
language['4'] = _('4')
language['5'] = _('5')
language['6'] = _('6')
language['7'] = _('7')
language['8'] = _('8')
language['9'] = _('9')
language['interface_down'] = _('Putting interface down...')
language['resetting_ip_address'] = _('Resetting IP address...')
language['interface_up'] = _('Putting interface up...')
language['setting_encryption_info'] = _('Setting encryption info')
language['removing_old_connection'] = _('Removing old connection...')
language['generating_psk'] = _('Generating PSK...')
language['generating_wpa_config'] = _('Generating WPA configuration file...')
language['flushing_routing_table'] = _('Flushing the routing table...')
language['configuring_interface'] = _('Configuring wireless interface...')
language['validating_authentication'] = _('Validating authentication...')
language['setting_broadcast_address'] = _('Setting broadcast address...')
language['setting_static_dns'] = _('Setting static DNS servers...')
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['aborted'] = _('Connection Cancelled')
language['bad_pass'] = _('Connection Failed: Bad password')
language['done'] = _('Done connecting...')
return language
def get_language_list_tray():
_ = get_gettext()
language = {}
language['connected_to_wireless'] = _('Connected to $A at $B (IP: $C)')
language['connected_to_wired'] = _('Connected to wired network (IP: $A)')
language['not_connected'] = _('Not connected')
language['killswitch_enabled'] = _('Wireless Kill Switch Enabled')
language['connecting'] = _('Connecting')
language['wired'] = _('Wired Network')
language['scanning'] = _('Scanning')
return language
def noneToBlankString(text):
""" Converts NoneType or "None" to a blank string. """
if text in (None, "None"):
return ""
else:
return str(text)
def stringToNone(text):
""" Performs opposite function of noneToString. """
if text in ("", None, "None"):
return None
else:
return str(text)
def stringToBoolean(text):
""" Turns a string representation of a bool to a boolean if needed. """
if text in ("True", "1"):
return True
if text in ("False", "0"):
return False
return text
def checkboxTextboxToggle(checkbox, textboxes):
# Really bad practice, but checkbox == self
for textbox in textboxes:
textbox.set_sensitive(checkbox.get_active())

299
wicd/monitor.py Executable file
View File

@@ -0,0 +1,299 @@
#!/usr/bin/env python
""" monitor -- connection monitoring process
This process is spawned as a child of the daemon, and is responsible
for monitoring connection status and initiating autoreconnection
when appropriate.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import dbus
import gobject
import time
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 wicd.wpath as wpath
import wicd.misc as misc
misc.RenameProcess("wicd-monitor")
if __name__ == '__main__':
wpath.chdir(__file__)
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')
wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless')
class ConnectionStatus(object):
""" Class for monitoring the computer's connection status. """
def __init__(self):
""" Initialize variables needed for the connection status methods. """
self.last_strength = -2
self.displayed_strength = -1
self.still_wired = False
self.network = ''
self.tried_reconnect = False
self.connection_lost_counter = 0
self.last_state = misc.NOT_CONNECTED
self.reconnecting = False
self.reconnect_tries = 0
self.last_reconnect_time = time.time()
self.signal_changed = False
# This determines if we use ioctl or external programs
self.fast = True
self.iwconfig = ""
def check_for_wired_connection(self, wired_ip):
""" Checks for an active wired connection.
Checks for and updates the tray icon for an active wired connection
Returns True if wired connection is active, false if inactive.
"""
if wired_ip and wired.CheckPluggedIn(self.fast):
# Only change the interface if it's not already set for wired
if not self.still_wired:
daemon.SetCurrentInterface(daemon.GetWiredInterface())
self.still_wired = True
return True
# Wired connection isn't active
self.still_wired = False
return False
def check_for_wireless_connection(self, wireless_ip):
""" Checks for an active wireless connection.
Checks for and updates the tray icon for an active
wireless connection. Returns True if wireless connection
is active, and False otherwise.
"""
# Make sure we have an IP before we do anything else.
if wireless_ip is None:
return False
if self.fast:
self.iwconfig = ''
else:
self.iwconfig = wireless.GetIwconfig()
# Reset this, just in case.
self.tried_reconnect = False
# Try getting signal strength, and default to 0
# if something goes wrong.
try:
if daemon.GetSignalDisplayType() == 0:
wifi_signal = int(wireless.GetCurrentSignalStrength(self.iwconfig,
self.fast))
else:
wifi_signal = int(wireless.GetCurrentDBMStrength(self.iwconfig,
self.fast))
except:
wifi_signal = 0
if wifi_signal == 0:
# If we have no signal, increment connection loss counter.
# If we haven't gotten any signal 4 runs in a row (12 seconds),
# try to reconnect.
self.connection_lost_counter += 1
print self.connection_lost_counter
if self.connection_lost_counter >= 4:
self.connection_lost_counter = 0
return False
else: # If we have a signal, reset the counter
self.connection_lost_counter = 0
# Only update if the signal strength has changed because doing I/O
# calls is expensive, and the icon flickers.
if (wifi_signal != self.last_strength or
self.network != wireless.GetCurrentNetwork(self.iwconfig,
self.fast)):
self.last_strength = wifi_signal
self.signal_changed = True
daemon.SetCurrentInterface(daemon.GetWirelessInterface())
return True
def update_connection_status(self):
""" Updates the tray icon and current connection status.
Determines the current connection state and sends a dbus signal
announcing when the status changes. Also starts the automatic
reconnection process if necessary.
"""
wired_ip = None
wifi_ip = None
try:
if daemon.GetSuspend():
print "Suspended."
state = misc.SUSPENDED
self.update_state(state)
return True
# Determine what our current state is.
# Check for wired.
wired_ip = wired.GetWiredIP(self.fast)
wired_found = self.check_for_wired_connection(wired_ip)
if wired_found:
self.update_state(misc.WIRED, wired_ip=wired_ip)
return True
# Check for wireless
wifi_ip = wireless.GetWirelessIP(self.fast)
#self.iwconfig = wireless.GetIwconfig()
self.signal_changed = False
wireless_found = self.check_for_wireless_connection(wifi_ip)
if wireless_found:
self.update_state(misc.WIRELESS, wifi_ip=wifi_ip)
return True
# Are we currently connecting?
if daemon.CheckIfConnecting():
state = misc.CONNECTING
else: # No connection at all.
state = misc.NOT_CONNECTED
if self.last_state == misc.WIRELESS:
from_wireless = True
else:
from_wireless = False
self.auto_reconnect(from_wireless)
self.update_state(state)
except dbus.exceptions.DBusException, e:
print 'Ignoring DBus Error: ' + str(e)
finally:
return True
def update_state(self, state, wired_ip=None, wifi_ip=None):
""" Set the current connection state. """
# Set our connection state/info.
iwconfig = self.iwconfig
fast = self.fast
if state == misc.NOT_CONNECTED:
info = [""]
elif state == misc.SUSPENDED:
info = [""]
elif state == misc.CONNECTING:
if wired.CheckIfWiredConnecting():
info = ["wired"]
else:
info = ["wireless", wireless.GetCurrentNetwork(iwconfig, fast)]
elif state == misc.WIRELESS:
self.reconnect_tries = 0
info = [wifi_ip, wireless.GetCurrentNetwork(iwconfig, fast),
str(wireless.GetPrintableSignalStrength(iwconfig, fast)),
str(wireless.GetCurrentNetworkID(iwconfig, fast))]
elif state == misc.WIRED:
self.reconnect_tries = 0
info = [wired_ip]
else:
print 'ERROR: Invalid state!'
return True
daemon.SetConnectionStatus(state, info)
# Send a D-Bus signal announcing status has changed if necessary.
if state != self.last_state or \
(state == misc.WIRELESS and self.signal_changed):
daemon.EmitStatusChanged(state, info)
self.last_state = state
return True
def auto_reconnect(self, from_wireless=None):
""" Automatically reconnects to a network if needed.
If automatic reconnection is turned on, this method will
attempt to first reconnect to the last used wireless network, and
should that fail will simply run AutoConnect()
"""
if self.reconnecting:
return
# Some checks to keep reconnect retries from going crazy.
if self.reconnect_tries > 2 and \
time.time() - self.last_reconnect_time < 30:
return
self.reconnecting = True
daemon.SetCurrentInterface('')
if daemon.ShouldAutoReconnect():
print 'Starting automatic reconnect process'
self.last_reconnect_time = time.time()
self.reconnect_tries += 1
# If we just lost a wireless connection, try to connect to that
# network again. Otherwise just call Autoconnect.
cur_net_id = wireless.GetCurrentNetworkID(self.iwconfig, self.fast)
if from_wireless and cur_net_id > -1:
print 'Trying to reconnect to last used wireless ' + \
'network'
wireless.ConnectWireless(cur_net_id)
else:
daemon.AutoConnect(True, reply_handler=reply_handle,
error_handler=err_handle)
self.reconnecting = False
def rescan_networks(self):
""" Calls a wireless scan. """
try:
if daemon.GetSuspend() or daemon.CheckIfConnecting():
return True
wireless.Scan()
except dbus.exceptions.DBusException, e:
print 'dbus exception while attempting rescan: %s' % str(e)
finally:
return True
def reply_handle():
""" Just a dummy function needed for asynchronous dbus calls. """
pass
def err_handle(error):
""" Just a dummy function needed for asynchronous dbus calls. """
pass
def main():
""" Starts the connection monitor.
Starts a ConnectionStatus instance, sets the status to update
every two seconds, and sets a wireless scan to be called every
two minutes.
"""
monitor = ConnectionStatus()
gobject.timeout_add(2000, monitor.update_connection_status)
#gobject.timeout_add(120000, monitor.rescan_networks)
mainloop = gobject.MainLoop()
mainloop.run()
if __name__ == '__main__':
main()

927
wicd/netentry.py Normal file
View File

@@ -0,0 +1,927 @@
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import gtk
import wicd.misc as misc
from wicd.misc import noneToString, stringToNone, noneToBlankString, stringToBoolean
import wicd.wpath as wpath
language = misc.get_language_list_gui()
# These get set when a NetworkEntry is instantiated.
daemon, wireless, wired, vpn_session, config = [None for x in range(0, 5)]
def error(parent, message):
""" 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()
class SmallLabel(gtk.Label):
def __init__(self, text=''):
gtk.Label.__init__(self, text)
self.set_size_request(50, -1)
class LabelEntry(gtk.HBox):
""" A label on the left with a textbox on the right. """
def __init__(self, text):
gtk.HBox.__init__(self)
self.entry = gtk.Entry()
self.entry.set_size_request(200, -1)
self.label = SmallLabel()
self.label.set_text(text)
self.label.set_size_request(170, -1)
self.pack_start(self.label, fill=False, expand=False)
self.pack_start(self.entry, fill=False, expand=False)
self.label.show()
self.entry.show()
self.entry.connect('focus-out-event', self.hide_characters)
self.entry.connect('focus-in-event', self.show_characters)
self.auto_hide_text = False
self.show()
def set_text(self, text):
# For compatibility...
self.entry.set_text(text)
def get_text(self):
return self.entry.get_text()
def set_auto_hidden(self, value):
self.entry.set_visibility(False)
self.auto_hide_text = value
def show_characters(self, widget=None, event=None):
# When the box has focus, show the characters
if self.auto_hide_text and widget:
self.entry.set_visibility(True)
def set_sensitive(self, value):
self.entry.set_sensitive(value)
self.label.set_sensitive(value)
def hide_characters(self, widget=None, event=None):
# When the box looses focus, hide them
if self.auto_hide_text and widget:
self.entry.set_visibility(False)
class GreyLabel(gtk.Label):
""" Creates a grey gtk.Label. """
def __init__(self):
gtk.Label.__init__(self)
def set_label(self, text):
self.set_markup("<span color=\"#666666\"><i>" + text + "</i></span>")
self.set_alignment(0, 0)
class AdvancedSettingsDialog(gtk.Dialog):
def __init__(self):
""" Build the base advanced settings dialog.
This class isn't used by itself, instead it is used as a parent for
the WiredSettingsDialog and WirelessSettingsDialog.
"""
gtk.Dialog.__init__(self, title=language['advanced_settings'],
flags=gtk.DIALOG_MODAL, buttons=(gtk.STOCK_CANCEL,
gtk.RESPONSE_REJECT,
gtk.STOCK_OK,
gtk.RESPONSE_ACCEPT))
# Set up the Advanced Settings Dialog.
self.txt_ip = LabelEntry(language['ip'])
self.txt_ip.entry.connect('focus-out-event', self.set_defaults)
self.txt_netmask = LabelEntry(language['netmask'])
self.txt_gateway = LabelEntry(language['gateway'])
self.txt_dns_1 = LabelEntry(language['dns'] + ' ' + language['1'])
self.txt_dns_2 = LabelEntry(language['dns'] + ' ' + language['2'])
self.txt_dns_3 = LabelEntry(language['dns'] + ' ' + language['3'])
self.chkbox_static_ip = gtk.CheckButton(language['use_static_ip'])
self.chkbox_static_dns = gtk.CheckButton(language['use_static_dns'])
self.chkbox_global_dns = gtk.CheckButton(language['use_global_dns'])
self.hbox_dns = gtk.HBox(False, 0)
self.hbox_dns.pack_start(self.chkbox_static_dns)
self.hbox_dns.pack_start(self.chkbox_global_dns)
self.vbox.pack_start(self.chkbox_static_ip, fill=False, expand=False)
self.vbox.pack_start(self.txt_ip, fill=False, expand=False)
self.vbox.pack_start(self.txt_netmask, fill=False, expand=False)
self.vbox.pack_start(self.txt_gateway, fill=False, expand=False)
self.vbox.pack_start(self.hbox_dns, fill=False, expand=False)
self.vbox.pack_start(self.txt_dns_1, fill=False, expand=False)
self.vbox.pack_start(self.txt_dns_2, fill=False, expand=False)
self.vbox.pack_start(self.txt_dns_3, fill=False, expand=False)
# Connect the events to the actions
self.chkbox_static_ip.connect("toggled", self.toggle_ip_checkbox)
self.chkbox_static_dns.connect("toggled", self.toggle_dns_checkbox)
self.chkbox_global_dns.connect("toggled", self.toggle_global_dns_checkbox)
# Start with all disabled, then they will be enabled later.
self.chkbox_static_ip.set_active(False)
self.chkbox_static_dns.set_active(False)
def set_defaults(self, widget=None, event=None):
""" Put some default values into entries to help the user out. """
ipAddress = self.txt_ip.get_text() # For easy typing :)
netmask = self.txt_netmask
gateway = self.txt_gateway
ip_parts = misc.IsValidIP(ipAddress)
if ip_parts:
if stringToNone(gateway.get_text()) is None: # Make sure the gateway box is blank
# Fill it in with a .1 at the end
gateway.set_text('.'.join(ip_parts[0:3]) + '.1')
if stringToNone(netmask.get_text()) is None: # Make sure the netmask is blank
netmask.set_text('255.255.255.0') # Fill in the most common one
elif ipAddress != "":
error(None, "Invalid IP Address Entered.")
def reset_static_checkboxes(self):
# Enable the right stuff
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)
else:
self.chkbox_static_ip.set_active(False)
self.chkbox_static_dns.set_active(False)
self.chkbox_static_dns.set_sensitive(True)
if stringToNone(self.txt_dns_1.get_text()):
self.chkbox_static_dns.set_active(True)
else:
self.chkbox_static_dns.set_active(False)
# This will properly disable unused boxes.
self.toggle_ip_checkbox()
self.toggle_dns_checkbox()
self.toggle_global_dns_checkbox()
def toggle_ip_checkbox(self, widget=None):
"""Toggle entries/checkboxes based on the static IP checkbox. """
# Should disable the static IP text boxes, and also enable the DNS
# checkbox when disabled and disable when enabled.
if self.chkbox_static_ip.get_active():
self.chkbox_static_dns.set_active(True)
self.chkbox_static_dns.set_sensitive(False)
else:
self.chkbox_static_dns.set_sensitive(True)
#self.chkbox_static_dns.set_active(False)
self.txt_ip.set_sensitive(self.chkbox_static_ip.get_active())
self.txt_netmask.set_sensitive(self.chkbox_static_ip.get_active())
self.txt_gateway.set_sensitive(self.chkbox_static_ip.get_active())
def toggle_dns_checkbox(self, widget=None):
""" Toggle entries and checkboxes based on the static dns checkbox. """
# Should disable the static DNS boxes
if self.chkbox_static_ip.get_active():
self.chkbox_static_dns.set_active(self.chkbox_static_ip.
get_active())
self.chkbox_static_dns.set_sensitive(False)
self.chkbox_global_dns.set_sensitive(self.chkbox_static_dns.
get_active())
if self.chkbox_static_dns.get_active():
# If global dns is on, don't use local dns
self.txt_dns_1.set_sensitive(not self.chkbox_global_dns.get_active())
self.txt_dns_2.set_sensitive(not self.chkbox_global_dns.get_active())
self.txt_dns_3.set_sensitive(not self.chkbox_global_dns.get_active())
else:
self.txt_dns_1.set_sensitive(False)
self.txt_dns_2.set_sensitive(False)
self.txt_dns_3.set_sensitive(False)
self.chkbox_global_dns.set_active(False)
def toggle_global_dns_checkbox(self, widget=None):
""" Set the DNS entries' sensitivity based on the Global checkbox. """
if daemon.GetUseGlobalDNS() and self.chkbox_static_dns.get_active():
self.txt_dns_1.set_sensitive(not self.chkbox_global_dns.get_active())
self.txt_dns_2.set_sensitive(not self.chkbox_global_dns.get_active())
self.txt_dns_3.set_sensitive(not self.chkbox_global_dns.get_active())
def destroy_called(self):
""" Clean up everything.
This might look excessive, but it was the only way to prevent
memory leakage.
"""
for obj in vars(self):
if hasattr(obj, "destroy"):
obj.destroy()
if hasattr(obj, "__del__"):
obj.__del__()
else:
del obj
super(AdvancedSettingsDialog, self).destroy()
self.destroy()
del self
class WiredSettingsDialog(AdvancedSettingsDialog):
def __init__(self, name):
""" Build the wired settings dialog. """
AdvancedSettingsDialog.__init__(self)
self.des = self.connect("destroy", self.destroy_called)
self.prof_name = name
def set_net_prop(self, option, value):
""" Sets the given option to the given value for this network. """
wired.SetWiredProperty(option, value)
def set_values(self):
""" Fill in the Gtk.Entry objects with the correct values. """
self.txt_ip.set_text(self.format_entry("ip"))
self.txt_netmask.set_text(self.format_entry("netmask"))
self.txt_gateway.set_text(self.format_entry("gateway"))
self.txt_dns_1.set_text(self.format_entry("dns1"))
self.txt_dns_2.set_text(self.format_entry("dns2"))
self.txt_dns_3.set_text(self.format_entry("dns3"))
self.reset_static_checkboxes()
def format_entry(self, label):
""" Helper method to fetch and format wired properties. """
return noneToBlankString(wired.GetWiredProperty(label))
def destroy_called(self):
""" Clean up everything.
This might look excessive, but it was the only way to prevent
memory leakage.
"""
self.disconnect(self.des)
for obj in vars(self):
if hasattr(obj, "destroy"):
obj.destroy()
if hasattr(obj, "__del__"):
obj.__del__()
else:
del obj
super(WiredSettingsDialog, self).destroy_called()
self.destroy()
del self
class WirelessSettingsDialog(AdvancedSettingsDialog):
def __init__(self, networkID):
""" Build the wireless settings dialog. """
AdvancedSettingsDialog.__init__(self)
# Set up encryption stuff
self.networkID = networkID
self.combo_encryption = gtk.combo_box_new_text()
self.chkbox_encryption = gtk.CheckButton(language['use_encryption'])
self.chkbox_global_settings = gtk.CheckButton(language['global_settings'])
# Make the vbox to hold the encryption stuff.
self.vbox_encrypt_info = gtk.VBox(False, 0)
self.toggle_encryption()
self.chkbox_encryption.set_active(False)
self.combo_encryption.set_sensitive(False)
self.encrypt_types = misc.LoadEncryptionMethods()
# Build the encryption menu
activeID = -1 # Set the menu to this item when we are done
for x, enc_type in enumerate(self.encrypt_types):
self.combo_encryption.append_text(enc_type[0])
if enc_type[1] == wireless.GetWirelessProperty(networkID,
"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.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)
self.vbox.pack_start(self.vbox_encrypt_info, False, False)
# Connect signals.
self.chkbox_encryption.connect("toggled", self.toggle_encryption)
self.combo_encryption.connect("changed", self.change_encrypt_method)
self.des = self.connect("destroy", self.destroy_called)
def destroy_called(self):
""" Clean up everything.
This might look excessive, but it was the only way to prevent
memory leakage.
"""
self.disconnect(self.des)
for obj in vars(self):
if hasattr(obj, "destroy"):
obj.destroy()
if hasattr(obj, "__del__"):
obj.__del__()
else:
del obj
super(WirelessSettingsDialog, self).destroy_called()
self.destroy()
del self
def set_net_prop(self, option, value):
""" Sets the given option to the given value for this network. """
wireless.SetWirelessProperty(self.networkID, option, value)
def set_values(self):
""" Set the various network settings to the right values. """
networkID = self.networkID
self.txt_ip.set_text(self.format_entry(networkID,"ip"))
self.txt_netmask.set_text(self.format_entry(networkID,"netmask"))
self.txt_gateway.set_text(self.format_entry(networkID,"gateway"))
self.chkbox_global_dns.set_active(bool(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()
self.chkbox_encryption.set_active(bool(wireless.GetWirelessProperty(networkID,
'encryption')))
self.chkbox_global_settings.set_active(bool(wireless.GetWirelessProperty(networkID,
'use_settings_globally')))
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.combo_encryption.set_active(0)
self.change_encrypt_method()
def format_entry(self, networkid, label):
""" Helper method for fetching/formatting wireless properties. """
return noneToBlankString(wireless.GetWirelessProperty(networkid, label))
def toggle_encryption(self, widget=None):
""" Toggle the encryption combobox based on the encryption checkbox. """
active = self.chkbox_encryption.get_active()
self.vbox_encrypt_info.set_sensitive(active)
self.combo_encryption.set_sensitive(active)
def change_encrypt_method(self, widget=None):
""" Load all the entries for a given encryption method. """
for z in self.vbox_encrypt_info:
z.destroy() # Remove stuff in there already
ID = self.combo_encryption.get_active()
methods = misc.LoadEncryptionMethods()
self.encryption_info = {}
# If nothing is selected, select the first entry.
if ID == -1:
self.combo_encryption.set_active(0)
ID = 0
opts = methods[ID][2]
for x in opts:
box = None
if language.has_key(opts[x][0]):
box = LabelEntry(language[opts[x][0].lower().replace(' ','_')])
else:
box = LabelEntry(opts[x][0].replace('_',' '))
box.set_auto_hidden(True)
self.vbox_encrypt_info.pack_start(box)
#add the data to any array, so that the information
#can be easily accessed by giving the name of the wanted
#data
self.encryption_info[opts[x][1]] = box.entry
box.entry.set_text(noneToBlankString(
wireless.GetWirelessProperty(self.networkID, opts[x][1])))
self.vbox_encrypt_info.show_all()
class NetworkEntry(gtk.HBox):
def __init__(self, dbus_ifaces):
""" Base network entry class.
Provides gtk objects used by both the WiredNetworkEntry and
WirelessNetworkEntry classes.
"""
global daemon, wired, wireless, config
daemon = dbus_ifaces["daemon"]
wired = dbus_ifaces["wired"]
wireless = dbus_ifaces["wireless"]
config = dbus_ifaces["config"]
gtk.HBox.__init__(self, False, 2)
self.expander = gtk.Expander()
self.image = gtk.Image()
self.pack_start(self.image, False, False)
# Set up the Connect button
self.connect_button = gtk.Button(stock=gtk.STOCK_CONNECT)
self.connect_hbox = gtk.HBox(False, 2)
self.connect_hbox.pack_start(self.connect_button, False, False)
self.connect_hbox.show()
# Set up the Disconnect button
self.disconnect_button = gtk.Button(stock=gtk.STOCK_DISCONNECT)
self.connect_hbox.pack_start(self.disconnect_button, False, False)
# Set up the VBox that goes in the gtk.Expander
self.expander_vbox = gtk.VBox(False, 1)
self.expander_vbox.show()
self.expander_vbox.pack_start(self.expander)
self.expander_vbox.pack_start(self.connect_hbox, False, False)
self.pack_end(self.expander_vbox)
# Set up the advanced settings button
self.advanced_button = gtk.Button()
self.advanced_image = gtk.Image()
self.advanced_image.set_from_stock(gtk.STOCK_EDIT, 4)
self.advanced_image.set_padding(4, 0)
self.advanced_button.set_alignment(.5, .5)
self.advanced_button.set_label(language['advanced_settings'])
self.advanced_button.set_image(self.advanced_image)
# Set up the script settings button
self.script_button = gtk.Button()
self.script_image = gtk.Image()
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)
self.script_button.set_label(language['scripts'])
self.settings_hbox = gtk.HBox(False, 3)
self.settings_hbox.set_border_width(5)
self.settings_hbox.pack_start(self.script_button, False, False)
self.settings_hbox.pack_start(self.advanced_button, False, False)
self.vbox_top = gtk.VBox(False, 0)
self.vbox_top.pack_end(self.settings_hbox, False, False)
aligner = gtk.Alignment(xscale=1.0)
aligner.add(self.vbox_top)
aligner.set_padding(0, 0, 15, 0)
self.expander.add(aligner)
def destroy_called(self, *args):
""" Clean up everything.
This might look excessive, but it was the only way to prevent
memory leakage.
"""
for obj in vars(self):
try: obj.destroy()
except: pass
if hasattr(obj, '__del__'):
obj.__del__()
else:
del obj
for obj in vars(super(NetworkEntry, self)):
try: obj.destroy()
except: pass
if hasattr(obj, '__del__'):
obj.__del__()
else:
del obj
super(NetworkEntry, self).destroy()
self.destroy()
class WiredNetworkEntry(NetworkEntry):
def __init__(self, dbus_ifaces):
""" Load the wired network entry. """
NetworkEntry.__init__(self, dbus_ifaces)
# Center the picture and pad it a bit
self.image.set_alignment(.5, 0)
self.image.set_size_request(60, -1)
self.image.set_from_icon_name("network-wired", 6)
self.image.show()
self.expander.show()
self.connect_button.show()
self.expander.set_label(language['wired_network'])
#self.reset_static_checkboxes()
self.is_full_gui = True
self.button_add = gtk.Button(stock=gtk.STOCK_ADD)
self.button_delete = gtk.Button(stock=gtk.STOCK_DELETE)
self.profile_help = gtk.Label(language['wired_network_instructions'])
self.chkbox_default_profile = gtk.CheckButton(language['default_wired'])
# Build the profile list.
self.combo_profile_names = gtk.combo_box_entry_new_text()
self.profile_list = config.GetWiredProfileList()
if self.profile_list:
for x in self.profile_list:
self.combo_profile_names.append_text(x)
# Format the profile help label.
self.profile_help.set_justify(gtk.JUSTIFY_LEFT)
self.profile_help.set_line_wrap(True)
# Pack the various VBox objects.
self.hbox_temp = gtk.HBox(False, 0)
self.hbox_def = gtk.HBox(False, 0)
self.vbox_top.pack_start(self.profile_help, True, True)
self.vbox_top.pack_start(self.hbox_def)
self.vbox_top.pack_start(self.hbox_temp)
self.hbox_temp.pack_start(self.combo_profile_names, True, True)
self.hbox_temp.pack_start(self.button_add, False, False)
self.hbox_temp.pack_start(self.button_delete, False, False)
self.hbox_def.pack_start(self.chkbox_default_profile, False, False)
# Connect events
self.button_add.connect("clicked", self.add_profile)
self.button_delete.connect("clicked", self.remove_profile)
self.chkbox_default_profile.connect("toggled",
self.toggle_default_profile)
self.combo_profile_names.connect("changed", self.change_profile)
self.script_button.connect("button-press-event", self.edit_scripts)
# Toggle the default profile checkbox to the correct state.
if stringToBoolean(wired.GetWiredProperty("default")):
self.chkbox_default_profile.set_active(True)
else:
self.chkbox_default_profile.set_active(False)
# Show everything, but hide the profile help label.
self.show_all()
self.profile_help.hide()
self.advanced_dialog = WiredSettingsDialog(self.combo_profile_names.get_active_text())
# Display the default profile if it exists.
if self.profile_list is not None:
prof = config.GetDefaultWiredNetwork()
if prof != None: # Make sure the default profile gets displayed.
i = 0
while self.combo_profile_names.get_active_text() != prof:
self.combo_profile_names.set_active(i)
i += 1
else:
self.combo_profile_names.set_active(0)
print "wired profiles found"
self.expander.set_expanded(False)
else:
print "no wired profiles found"
if not wired.GetAlwaysShowWiredInterface():
self.expander.set_expanded(True)
self.profile_help.show()
self.check_enable()
self.wireddis = self.connect("destroy", self.destroy_called)
def destroy_called(self, *args):
""" Clean up everything.
This might look excessive, but it was the only way to prevent
memory leakage.
"""
self.disconnect(self.wireddis)
self.advanced_dialog.destroy_called()
del self.advanced_dialog
for obj in vars(self):
if hasattr(obj, "destroy"):
obj.destroy()
if hasattr(obj, '__del__'):
obj.__del__()
else:
del obj
super(WiredNetworkEntry, self).destroy_called()
self.destroy()
del self
def edit_scripts(self, widget=None, event=None):
""" Launch the script editting dialog. """
profile = self.combo_profile_names.get_active_text()
try:
sudo_prog = misc.choose_sudo_prog()
msg = "You must enter your password to configure scripts"
if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
msg_flag = "-m"
else:
msg_flag = "--caption"
misc.LaunchAndWait([sudo_prog, msg_flag, msg, "./configscript.py",
profile, "wired"])
except misc.WicdError:
error("Could not find a graphical sudo program." + \
" Script editor could not be launched.")
def check_enable(self):
""" Disable objects if the profile list is empty. """
profile_list = config.GetWiredProfileList()
if profile_list == None:
self.button_delete.set_sensitive(False)
self.connect_button.set_sensitive(False)
self.advanced_button.set_sensitive(False)
self.script_button.set_sensitive(False)
def update_connect_button(self, state, apbssid=None):
""" Update the connection/disconnect button for this entry. """
if state == misc.WIRED:
self.disconnect_button.show()
self.connect_button.hide()
else:
self.disconnect_button.hide()
self.connect_button.show()
def add_profile(self, widget):
""" Add a profile to the profile list. """
print "adding profile"
profile_name = self.combo_profile_names.get_active_text()
profile_list = config.GetWiredProfileList()
if profile_list:
if profile_name in profile_list:
return False
if profile_name != "":
self.profile_help.hide()
config.CreateWiredNetworkProfile(profile_name)
self.combo_profile_names.prepend_text(profile_name)
self.combo_profile_names.set_active(0)
self.advanced_dialog.prof_name = profile_name
if self.is_full_gui:
self.button_delete.set_sensitive(True)
self.connect_button.set_sensitive(True)
self.advanced_button.set_sensitive(True)
self.script_button.set_sensitive(True)
def remove_profile(self, widget):
""" Remove a profile from the profile list. """
print "removing profile"
profile_name = self.combo_profile_names.get_active_text()
config.DeleteWiredNetworkProfile(profile_name)
self.combo_profile_names.remove_text(self.combo_profile_names.
get_active())
self.combo_profile_names.set_active(0)
self.advanced_dialog.prof_name = self.combo_profile_names.get_active_text()
if not config.GetWiredProfileList():
self.profile_help.show()
entry = self.combo_profile_names.child
entry.set_text("")
if self.is_full_gui:
self.button_delete.set_sensitive(False)
self.advanced_button.set_sensitive(False)
self.script_button.set_sensitive(False)
self.connect_button.set_sensitive(False)
else:
self.profile_help.hide()
def toggle_default_profile(self, widget):
""" Change the default profile. """
if self.chkbox_default_profile.get_active():
# Make sure there is only one default profile at a time
config.UnsetWiredDefault()
wired.SetWiredProperty("default",
self.chkbox_default_profile.get_active())
config.SaveWiredNetworkProfile(self.combo_profile_names.get_active_text())
def change_profile(self, widget):
""" Called when a new profile is chosen from the list. """
# Make sure the name doesn't change everytime someone types something
if self.combo_profile_names.get_active() > -1:
if not self.is_full_gui:
return
profile_name = self.combo_profile_names.get_active_text()
config.ReadWiredNetworkProfile(profile_name)
self.advanced_dialog.txt_ip.set_text(self.format_entry("ip"))
self.advanced_dialog.txt_netmask.set_text(self.format_entry("netmask"))
self.advanced_dialog.txt_gateway.set_text(self.format_entry("gateway"))
self.advanced_dialog.txt_dns_1.set_text(self.format_entry("dns1"))
self.advanced_dialog.txt_dns_2.set_text(self.format_entry("dns2"))
self.advanced_dialog.txt_dns_3.set_text(self.format_entry("dns3"))
self.advanced_dialog.prof_name = profile_name
is_default = wired.GetWiredProperty("default")
self.chkbox_default_profile.set_active(stringToBoolean(is_default))
def format_entry(self, label):
""" Help method for fetching/formatting wired properties. """
return noneToBlankString(wired.GetWiredProperty(label))
class WirelessNetworkEntry(NetworkEntry):
def __init__(self, networkID, dbus_ifaces):
""" Build the wireless network entry. """
NetworkEntry.__init__(self, dbus_ifaces)
self.networkID = networkID
self.image.set_padding(0, 0)
self.image.set_alignment(.5, 0)
self.image.set_size_request(60, -1)
self.image.set_from_icon_name("network-wired", 6)
self.essid = wireless.GetWirelessProperty(networkID, "essid")
print "ESSID : " + self.essid
# Make the combo box.
self.lbl_strength = GreyLabel()
self.lbl_encryption = GreyLabel()
self.lbl_mac = GreyLabel()
self.lbl_channel = GreyLabel()
self.lbl_mode = GreyLabel()
self.hbox_status = gtk.HBox(False, 5)
self.chkbox_autoconnect = gtk.CheckButton(language['automatic_connect'])
# Set the values of the network info labels.
self.set_signal_strength(wireless.GetWirelessProperty(networkID,
'quality'),
wireless.GetWirelessProperty(networkID,
'strength'))
self.set_mac_address(wireless.GetWirelessProperty(networkID, 'bssid'))
self.set_mode(wireless.GetWirelessProperty(networkID, 'mode'))
self.set_channel(wireless.GetWirelessProperty(networkID, 'channel'))
self.set_encryption(wireless.GetWirelessProperty(networkID,
'encryption'),
wireless.GetWirelessProperty(networkID,
'encryption_method'))
# The the expander label.
self.expander.set_use_markup(True)
self.expander.set_label(self._escape(self.essid) + " " +
self.lbl_strength.get_label() + " " +
self.lbl_encryption.get_label() + " " +
self.lbl_mac.get_label())
# Pack the network status HBox.
self.hbox_status.pack_start(self.lbl_strength, True, True)
self.hbox_status.pack_start(self.lbl_encryption, True, True)
self.hbox_status.pack_start(self.lbl_mac, True, True)
self.hbox_status.pack_start(self.lbl_mode, True, True)
self.hbox_status.pack_start(self.lbl_channel, True, True)
# Add the wireless network specific parts to the NetworkEntry
# VBox objects.
self.vbox_top.pack_start(self.chkbox_autoconnect, False, False)
self.vbox_top.pack_start(self.hbox_status, True, True)
if stringToBoolean(self.format_entry(networkID, "automatic")):
self.chkbox_autoconnect.set_active(True)
else:
self.chkbox_autoconnect.set_active(False)
# Connect signals.
self.chkbox_autoconnect.connect("toggled", self.update_autoconnect)
self.script_button.connect("button-press-event", self.edit_scripts)
# Show everything
self.show_all()
self.advanced_dialog = WirelessSettingsDialog(networkID)
self.wifides = self.connect("destroy", self.destroy_called)
def _escape(self, val):
return val.replace("&", "&amp;").replace("<", "&lt;").\
replace(">","&gt;").replace("'", "&apos;").replace('"', "&quot;")
def destroy_called(self, *args):
""" Clean up everything.
This might look excessive, but it was the only way to prevent
memory leakage.
"""
self.disconnect(self.wifides)
self.advanced_dialog.destroy_called()
del self.advanced_dialog
for obj in vars(self):
if hasattr(obj, "destroy"):
obj.destroy()
if hasattr(obj, '__del__'):
obj.__del__()
else:
del obj
super(WirelessNetworkEntry, self).destroy_called()
self.destroy()
del self
def set_signal_strength(self, strength, dbm_strength):
""" Set the signal strength displayed in the WirelessNetworkEntry. """
if strength is not None:
strength = int(strength)
else:
strength = -1
if dbm_strength is not None:
dbm_strength = int(dbm_strength)
else:
dbm_strength = -100
display_type = daemon.GetSignalDisplayType()
if daemon.GetWPADriver() == 'ralink legacy' or display_type == 1:
# Use the -xx dBm signal strength to display a signal icon
# I'm not sure how accurately the dBm strength is being
# "converted" to strength bars, so suggestions from people
# for a better way would be welcome.
if dbm_strength >= -60:
signal_img = 'signal-100.png'
elif dbm_strength >= -70:
signal_img = 'signal-75.png'
elif dbm_strength >= -80:
signal_img = 'signal-50.png'
else:
signal_img = 'signal-25.png'
ending = "dBm"
disp_strength = str(dbm_strength)
else:
# Uses normal link quality, should be fine in most cases
if strength > 75:
signal_img = 'signal-100.png'
elif strength > 50:
signal_img = 'signal-75.png'
elif strength > 25:
signal_img = 'signal-50.png'
else:
signal_img = 'signal-25.png'
ending = "%"
disp_strength = str(strength)
self.image.set_from_file(wpath.images + signal_img)
self.lbl_strength.set_label(disp_strength + ending)
def update_connect_button(self, state, apbssid):
""" Update the connection/disconnect button for this entry. """
if not apbssid:
apbssid = wireless.GetApBssid()
if state == misc.WIRELESS and \
apbssid == wireless.GetWirelessProperty(self.networkID, "bssid"):
self.disconnect_button.show()
self.connect_button.hide()
else:
self.disconnect_button.hide()
self.connect_button.show()
def set_mac_address(self, address):
""" Set the MAC address for the WirelessNetworkEntry. """
self.lbl_mac.set_label(str(address))
def set_encryption(self, on, ttype):
""" Set the encryption value for the WirelessNetworkEntry. """
if on and ttype:
self.lbl_encryption.set_label(str(ttype))
if on and not ttype:
self.lbl_encryption.set_label(language['secured'])
if not on:
self.lbl_encryption.set_label(language['unsecured'])
def set_channel(self, channel):
""" Set the channel value for the WirelessNetworkEntry. """
self.lbl_channel.set_label(language['channel'] + ' ' + str(channel))
def set_mode(self, mode):
""" Set the mode value for the WirelessNetworkEntry. """
self.lbl_mode.set_label(str(mode))
def format_entry(self, networkid, label):
""" Helper method for fetching/formatting wireless properties. """
return noneToBlankString(wireless.GetWirelessProperty(networkid, label))
def edit_scripts(self, widget=None, event=None):
""" Launch the script editting dialog. """
try:
sudo_prog = misc.choose_sudo_prog()
msg = "You must enter your password to configure scripts"
if sudo_prog.endswith("gksu") or sudo_prog.endswith("ktsuss"):
msg_flag = "-m"
else:
msg_flag = "--caption"
misc.LaunchAndWait([sudo_prog, msg_flag, msg, "./configscript.py",
str(self.networkID), "wireless"])
except IOError:
error("Could not find a graphical sudo program." + \
" Script editor could no be launched.")
def update_autoconnect(self, widget=None):
""" Called when the autoconnect checkbox is toggled. """
wireless.SetWirelessProperty(self.networkID, "automatic",
noneToString(self.chkbox_autoconnect.
get_active()))
config.SaveWirelessNetworkProperty(self.networkID, "automatic")

933
wicd/networking.py Normal file
View File

@@ -0,0 +1,933 @@
#!/usr/bin/env python
""" networking - Provides wrappers for common network operations
This module provides wrappers of the common network tasks as well as
threads to perform the actual connecting to networks.
class Controller() -- Parent class to Wireless and Wired
class ConnectThread() -- Parent class to WirelessConnectThread and
WiredConnectThread
class Wireless() -- Wrapper for various wireless functions
class Wired() -- Wrapper for various wired functions
class WirelessConnectThread() -- Connection thread for wireless
interface
class WiredConnectThread() -- Connection thread for wired
interface
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
# Copyright (C) 2007 Byron Hillis
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
# Much thanks to wieman01 for help and support with various types of encyption.
# Also thanks to foxy123, yopnono, and the many others who reported bugs helped
# and helped keep this project moving.
#
import re
import threading
import thread
import time
import wicd.misc as misc
import wicd.wnettools as wnettools
import wicd.wpath as wpath
if __name__ == '__main__':
wpath.chdir(__file__)
class Controller(object):
""" Parent class for the different interface types. """
def __init__(self):
""" Initialise the class. """
self.global_dns_1 = None
self.global_dns_2 = None
self.global_dns_3 = None
self._wired_interface = None
self._wireless_interface = None
self._dhcp_client = None
self._flush_tool = None
self._debug = None
self.connecting_thread = None
self.before_script = None
self.after_script = None
self.disconnect_script = None
self.driver = None
self.wiface = None
self.liface = 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
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
def set_debug(self, value):
self._debug = value
if self.wiface:
self.wiface.SetDebugMode(value)
if self.liface:
self.liface.SetDebugMode(value)
def get_debug(self):
return self._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()
def get_dhcp_client(self):
return self._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
def get_flush_tool(self):
return self._flush_tool
wireless_interface = property(get_wireless_iface, set_wireless_iface)
wired_interface = property(get_wired_iface, set_wired_iface)
debug = property(get_debug, set_debug)
flush_tool = property(get_flush_tool, set_flush_tool)
dhcp_client = property(get_dhcp_client, set_dhcp_client)
class ConnectThread(threading.Thread):
""" A class to perform network connections in a multi-threaded way.
Useless on it's own, this class provides the generic functions
necessary for connecting using a separate thread.
"""
is_connecting = None
connecting_thread = None
should_die = False
lock = thread.allocate_lock()
def __init__(self, network, wireless, wired, before_script, after_script,
disconnect_script, gdns1, gdns2, gdns3, wiface, liface, debug):
""" Initialise the required object variables and the thread.
Keyword arguments:
network -- the network to connect to
wireless -- name of the wireless interface
wired -- name of the wired interface
before_script -- script to run before bringing up the interface
after_script -- script to run after bringing up the interface
disconnect_script -- script to run after disconnection
gdns1 -- global DNS server 1
gdns2 -- global DNS server 2
gdns3 -- global DNS server 3
debug -- debug mode status
"""
threading.Thread.__init__(self)
self.network = network
self.wireless_interface = wireless
self.wired_interface = wired
self.is_connecting = False
self.is_aborted = False
self.abort_msg = None
self.before_script = before_script
self.after_script = after_script
self.disconnect_script = disconnect_script
self.should_die = False
self.abort_reason = ""
self.global_dns_1 = gdns1
self.global_dns_2 = gdns2
self.global_dns_3 = gdns3
self.wiface = wiface
self.liface = liface
self.connecting_message = None
self.debug = debug
self.SetStatus('interface_down')
def SetStatus(self, status):
""" Set the threads current status message in a thread-safe way.
Keyword arguments:
status -- the current connection status
"""
self.lock.acquire()
try:
self.connecting_message = status
finally:
self.lock.release()
def GetStatus(self):
""" Get the threads current status message in a thread-safe way.
Returns:
The current connection status.
"""
self.lock.acquire()
try:
message = self.connecting_message
finally:
self.lock.release()
return message
def reset_ip_addresses(self, wiface, liface):
""" Resets the IP addresse for both wired/wireless interfaces.
Sets a false ip so that when we set the real one, the correct
routing entry is created.
"""
print 'Setting false IP...'
self.SetStatus('resetting_ip_address')
wiface.SetAddress('0.0.0.0')
liface.SetAddress('0.0.0.0')
def put_iface_down(self, iface):
""" Puts the given interface down. """
print 'Putting interface down'
self.SetStatus('interface_down')
iface.Down()
def run_script_if_needed(self, script, msg):
""" Execute a given script if needed.
Keyword arguments:
script -- the script to execute, or None/'' if there isn't one.
msg -- the name of the script to display in the log.
"""
if script:
print 'Executing %s script' % (msg)
misc.ExecuteScript(script)
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()
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'])
def set_ip_address(self, iface):
""" Set the IP address for the given interface.
Assigns a static IP if one is requested, otherwise calls DHCP.
"""
if self.network.get('ip'):
self.SetStatus('setting_static_ip')
print 'Setting static IP : ' + self.network['ip']
iface.SetAddress(self.network['ip'], self.network['netmask'])
print 'Setting default gateway : ' + self.network['gateway']
iface.SetDefaultRoute(self.network['gateway'])
else:
# Run dhcp...
self.SetStatus('running_dhcp')
print "Running DHCP"
dhcp_status = iface.StartDHCP()
if dhcp_status in ['no_dhcp_offers', 'dhcp_failed']:
self.abort_connection(dhcp_status)
return
def set_dns_addresses(self):
""" Set the DNS address(es).
If static DNS servers or global DNS servers are specified, set them.
Otherwise do nothing.
"""
if self.network.get('use_global_dns'):
wnettools.SetDNS(misc.Noneify(self.global_dns_1),
misc.Noneify(self.global_dns_2),
misc.Noneify(self.global_dns_3))
elif self.network.get('use_static_dns') and (self.network.get('dns1') or
self.network.get('dns2') or self.network.get('dns3')):
self.SetStatus('setting_static_dns')
wnettools.SetDNS(self.network.get('dns1'), self.network.get('dns2'),
self.network.get('dns3'))
def connect_aborted(self, reason):
""" Sets the thread status to aborted in a thread-safe way.
Sets the status to aborted, and also delays returning for
a few seconds to make sure the message is readable
"""
if self.abort_reason:
reason = self.abort_reason
self.SetStatus(reason)
self.is_aborted = True
self.abort_msg = reason
self.is_connecting = False
print 'exiting connection thread'
def abort_connection(self, reason=""):
""" Schedule a connection abortion for the given reason. """
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()
wnettools.StopDHCP()
def abort_if_needed(self):
""" Abort the thread is it has been requested. """
if self.should_die:
self.connect_aborted('aborted')
thread.exit()
def put_iface_up(self, iface):
""" Bring up given interface. """
print 'Putting interface up...'
self.SetStatus('interface_up')
iface.Up()
class Wireless(Controller):
""" A wrapper for common wireless interface functions. """
def __init__(self):
""" Initialize the class. """
Controller.__init__(self)
self._wpa_driver = None
self.wiface = wnettools.WirelessInterface(self.wireless_interface,
self.debug, self.wpa_driver)
def set_wpa_driver(self, value):
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 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.
Keyword arguments:
essid -- The essid of a hidden network
Returns:
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
if not self.wireless_interface: return []
wiface = self.wiface
# Prepare the interface for scanning
wiface.Up()
# If there is a hidden essid then set it now, so that when it is
# scanned it will be recognized.
essid = misc.Noneify(essid)
if essid is not None:
print 'Setting hidden essid' + essid
wiface.SetEssid(essid)
aps = wiface.GetNetworks()
aps.sort(cmp=comp, reverse=True)
return aps
def Connect(self, network, debug=False):
""" Spawn a connection thread to connect to the network.
Keyword arguments:
network -- network to connect to
"""
if not self.wireless_interface: 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.global_dns_2, self.global_dns_3, self.wiface, self.liface,
debug)
self.connecting_thread.setDaemon(True)
self.connecting_thread.start()
return True
def GetSignalStrength(self, iwconfig=None, fast=False):
""" Get signal strength of the current network.
Returns:
The current signal strength.
"""
return self.wiface.GetSignalStrength(iwconfig, fast)
def GetDBMStrength(self, iwconfig=None, fast=False):
""" Get the dBm signal strength of the current network.
Returns:
The current dBm signal strength.
"""
return self.wiface.GetDBMStrength(iwconfig, fast)
def GetCurrentNetwork(self, iwconfig=None, fast=False):
""" Get current network name.
Returns:
The name of the currently connected network.
"""
return self.wiface.GetCurrentNetwork(iwconfig, fast)
def GetIP(self, fast=False):
""" Get the IP of the interface.
Returns:
The IP address of the interface in dotted notation.
"""
return self.wiface.GetIP(fast)
def GetBSSID(self, fast=True):
""" Get the BSSID of the current access point.
Returns:
The MAC Adress of the active access point as a string, or
None the BSSID can't be found.
"""
return self.wiface.GetBSSID(fast)
def GetIwconfig(self):
""" Get the out of iwconfig. """
return self.wiface.GetIwconfig()
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 CreateAdHocNetwork(self, essid, channel, ip, enctype, key,
enc_used, ics):
""" Create an ad-hoc wireless network.
Keyword arguments:
essid -- essid of the ad-hoc network
channel -- channel of the ad-hoc network
ip -- ip of the ad-hoc network
enctype -- unused
key -- key of the ad-hoc network
enc_used -- encrytion enabled on ad-hoc network
ics -- enable internet connection sharing
"""
wiface = self.wiface
print 'Creating ad-hoc network'
print 'Killing dhclient and wpa_supplicant'
wnettools.StopDHCP()
wiface.StopWPA()
print 'Putting wireless interface down'
wiface.Down()
print 'Setting mode, channel, and essid'
wiface.SetMode('ad-hoc')
wiface.SetChannel(channel)
wiface.SetEssid(essid)
# Right now it just assumes you're using WEP
if enc_used:
print 'Setting encryption key'
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.
Returns:
The first available wireless interface.
"""
return wnettools.GetWirelessInterfaces()
def GetKillSwitchStatus(self):
""" Get the current status of the Killswitch.
Returns:
True if the killswitch is on, False otherwise.
"""
return self.wiface.GetKillSwitchStatus()
def Disconnect(self):
""" Disconnect the given iface.
Executes the disconnect script associated with a given interface,
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.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()
def SetWPADriver(self, driver):
""" Sets the wpa_supplicant driver associated with the interface. """
self.wiface.SetWpaDriver(driver)
class WirelessConnectThread(ConnectThread):
""" A thread class to perform the connection to a wireless network.
This thread, when run, will perform the necessary steps to connect
to the specified network.
"""
def __init__(self, network, wireless, wired, wpa_driver,
before_script, after_script, disconnect_script, gdns1,
gdns2, gdns3, wiface, liface, 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
disconnect_script -- script to run after disconnection
gdns1 -- global DNS server 1
gdns2 -- global DNS server 2
gdns3 -- global DNS server 3
"""
ConnectThread.__init__(self, network, wireless, wired,
before_script, after_script, disconnect_script, gdns1,
gdns2, gdns3, wiface, liface, debug)
self.wpa_driver = wpa_driver
def run(self):
""" The main function of the connection thread.
This function performs the necessary calls to connect to the
specified network, using the information provided. The following
indicates the steps taken.
1. Run pre-connection script.
2. Take down the interface and clean up any previous
connections.
3. Generate a PSK if required and authenticate.
4. Associate with the WAP.
5. Get/set IP address and DNS servers.
"""
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()
# 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.
if self.wpa_driver != 'ralink legacy':
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'])
wiface.Associate(self.network['essid'], self.network['channel'],
self.network['bssid'])
# Authenticate after association for Ralink legacy cards.
if self.wpa_driver == 'ralink legacy':
if self.network.get('key'):
wiface.Authenticate(self.network)
# Validate Authentication.
if self.network.get('enctype'):
self.SetStatus('validating_authentication')
if not wiface.ValidateAuthentication(time.time(),
fast=self.is_fast):
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(fast=self.is_fast))
self.is_connecting = False
def generate_psk_and_authenticate(self, wiface):
""" Generates a PSK and authenticates if necessary.
Generates a PSK using wpa_passphrase, and starts the authentication
process if encryption is on.
"""
def _sanitize(key):
""" Escapes characters wpa_supplicant doesn't handle properly. """
new_key = []
blacklist = ["$", "`", "\""]
for c in key:
if c in blacklist:
new_key.append("\\" + c)
else:
new_key.append(c)
return ''.join(new_key)
# Check to see if we need to generate a PSK (only for non-ralink
# cards).
if self.network.get('key'):
self.SetStatus('generating_psk')
print 'Generating psk...'
key_pattern = re.compile('network={.*?\spsk=(.*?)\n}.*',
re.I | re.M | re.S)
self.network['psk'] = misc.RunRegex(key_pattern,
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')
print 'Attempting to authenticate...'
wiface.Authenticate(self.network)
class Wired(Controller):
""" A wrapper for common wired interface functions. """
def __init__(self):
""" Initialise the class. """
Controller.__init__(self)
self.wpa_driver = None
self._link_detect = None
self.liface = wnettools.WiredInterface(self.wired_interface, self.debug)
def set_link_detect(self, value):
self._link_detect = value
if self.liface:
self.liface.link_detect = value
def get_link_detect(self): return self._link_detect
link_detect = property(get_link_detect, set_link_detect)
#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.
Returns:
The status of the physical connection link.
"""
return self.liface.GetPluggedIn(fast)
def Connect(self, network, debug=False):
""" Spawn a connection thread to connect to the network.
Keyword arguments:
network -- network to connect to
"""
if not self.wired_interface: 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.wiface, self.liface,
debug)
self.connecting_thread.setDaemon(True)
self.connecting_thread.start()
return True
def GetIP(self, fast=False):
""" Get the IP of the interface.
Returns:
The IP address of the interface in dotted notation.
"""
return self.liface.GetIP(fast)
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.
This thread, when run, will perform the necessary steps to connect
to the specified network.
"""
def __init__(self, network, wireless, wired,
before_script, after_script, disconnect_script, gdns1,
gdns2, gdns3, wiface, liface, 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
before_script -- script to run before bringing up the interface
after_script -- script to run after bringing up the interface
disconnect_script -- script to run after disconnection
gdns1 -- global DNS server 1
gdns2 -- global DNS server 2
gdns3 -- global DNS server 3
"""
ConnectThread.__init__(self, network, wireless, wired,
before_script, after_script, disconnect_script, gdns1,
gdns2, gdns3, wiface, liface, debug)
def run(self):
""" The main function of the connection thread.
This function performs the necessary calls to connect to the
specified network, using the information provided. The following
indicates the steps taken.
1. Run pre-connection script.
2. Take down the interface and clean up any previous
connections.
3. Bring up the interface.
4. Get/set IP address and DNS servers.
5. Run post-connection script.
"""
wiface = self.wiface
liface = self.liface
self.is_connecting = True
#TODO pass is_fast in.
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()
# 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')
self.SetStatus('done')
print 'Connecting thread exiting.'
if self.debug:
print "IP Address is: " + str(liface.GetIP(fast=self.is_fast))
self.is_connecting = False

268
wicd/prefs.py Normal file
View File

@@ -0,0 +1,268 @@
#!/usr/bin/python
""" Wicd Preferences Dialog.
Displays the main settings dialog window for wicd.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import gtk
import gobject
import pango
import wicd.misc
from wicd.misc import checkboxTextboxToggle, noneToBlankString
daemon = None
wireless = None
wired = None
config = None
language = misc.get_language_list_gui()
class PreferencesDialog(object):
def __init__(self, wTree, dbus):
global daemon, wireless, wired, config
daemon = dbus['daemon']
wireless = dbus['wireless']
wired = dbus['wired']
config = dbus['config']
self.wTree = wTree
self.prep_settings_diag()
self.build_preferences_diag()
def build_preferences_diag(self):
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=""):
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'])
size = config.ReadWindowSize("pref")
width = size[0]
height = size[1]
if width > -1 and height > -1:
self.dialog.resize(int(width), int(height))
self.wiredcheckbox = setup_label("pref_always_check",
'wired_always_on')
self.wiredcheckbox.set_active(wired.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()
flush_list[flush_method].set_active(True)
if wired.GetWiredAutoConnectMethod() == 1:
self.usedefaultradiobutton.set_active(True)
elif wired.GetWiredAutoConnectMethod() == 2:
self.showlistradiobutton.set_active(True)
elif wired.GetWiredAutoConnectMethod() == 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):
if x == def_driver: #and not found:
found = True
user_driver_index = i
self.wpadrivercombo.remove_text(i)
self.wpadrivercombo.append_text(x)
# Set the active choice here. Doing it before all the items are
# added the combobox causes the choice to be reset.
if found:
self.wpadrivercombo.set_active(user_driver_index)
else:
# 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.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))
dns_addresses = daemon.GetGlobalDNSAddresses()
self.useGlobalDNSCheckbox.set_active(daemon.GetUseGlobalDNS())
self.dns1Entry.set_text(noneToBlankString(dns_addresses[0]))
self.dns2Entry.set_text(noneToBlankString(dns_addresses[1]))
self.dns3Entry.set_text(noneToBlankString(dns_addresses[2]))
if not daemon.GetUseGlobalDNS():
self.dns1Entry.set_sensitive(False)
self.dns2Entry.set_sensitive(False)
self.dns3Entry.set_sensitive(False)
self.wTree.get_widget("notebook2").set_current_page(0)
def run(self):
return self.dialog.run()
def hide(self):
self.dialog.hide()
def show_all(self):
self.show_all()
def save_results(self):
daemon.SetUseGlobalDNS(self.useGlobalDNSCheckbox.get_active())
daemon.SetGlobalDNS(self.dns1Entry.get_text(), self.dns2Entry.get_text(),
self.dns3Entry.get_text())
daemon.SetWirelessInterface(self.entryWirelessInterface.get_text())
daemon.SetWiredInterface(self.entryWiredInterface.get_text())
daemon.SetWPADriver(self.wpadrivers[self.wpadrivercombo.get_active()])
wired.SetAlwaysShowWiredInterface(self.wiredcheckbox.get_active())
daemon.SetAutoReconnect(self.reconnectcheckbox.get_active())
daemon.SetDebugMode(self.debugmodecheckbox.get_active())
daemon.SetSignalDisplayType(self.displaytypecheckbox.get_active())
if self.showlistradiobutton.get_active():
wired.SetWiredAutoConnectMethod(2)
elif self.lastusedradiobutton.get_active():
wired.SetWiredAutoConnectMethod(3)
else:
wired.SetWiredAutoConnectMethod(1)
# External Programs Tab
if self.dhcpautoradio.get_active():
dhcp_client = misc.AUTO
elif self.dhclientradio.get_active():
dhcp_client = misc.DHCLIENT
elif self.dhcpcdradio.get_active():
dhcp_client = misc.DHCPCD
else:
dhcp_client = misc.PUMP
daemon.SetDHCPClient(dhcp_client)
if self.linkautoradio.get_active():
link_tool = misc.AUTO
elif self.ethtoolradio.get_active():
link_tool = misc.ETHTOOL
else:
link_tool = misc.MIITOOL
daemon.SetLinkDetectionTool(link_tool)
if self.flushautoradio.get_active():
flush_tool = misc.AUTO
elif self.ipflushradio.get_active():
flush_tool = misc.IP
else:
flush_tool = misc.ROUTE
daemon.SetFlushTool(flush_tool)
[width, height] = self.dialog.get_size()
config.WriteWindowSize(width, height, "pref")
def set_label(self, glade_str, label):
""" Sets the label for the given widget in wicd.glade. """
self.wTree.get_widget(glade_str).set_label(label)
def prep_settings_diag(self):
""" Set up anything that doesn't have to be persisted later. """
# 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"])
self.wTree.get_widget("dhcp_client_label").set_label(language["dhcp_client"])
self.wTree.get_widget("wired_detect_label").set_label(language["wired_detect"])
self.wTree.get_widget("route_flush_label").set_label(language["route_flush"])
entryWiredAutoMethod = self.wTree.get_widget("pref_wired_auto_label")
entryWiredAutoMethod.set_label('Wired Autoconnect Setting:')
entryWiredAutoMethod.set_alignment(0, 0)
atrlist = pango.AttrList()
atrlist.insert(pango.AttrWeight(pango.WEIGHT_BOLD, 0, 50))
entryWiredAutoMethod.set_attributes(atrlist)
self.set_label("pref_dns1_label", language['dns'] + ' ' + language['1'])
self.set_label("pref_dns2_label", language['dns'] + ' ' + language['2'])
self.set_label("pref_dns3_label", language['dns'] + ' ' + language['3'])
self.set_label("pref_wifi_label", language['wireless_interface'] + ':')
self.set_label("pref_wired_label", language['wired_interface'] + ':')
self.set_label("pref_driver_label", language['wpa_supplicant_driver'] + ':')

38
wicd/suspend.py Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/python
""" Suspends the wicd daemon.
Sets a flag in the daemon that will stop it from monitoring networkg status.
Used for when a laptop enters hibernation/suspension.
"""
#
# Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import dbus
import dbus.service
bus = dbus.SystemBus()
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
if __name__ == '__main__':
daemon.Disconnect()
daemon.SetForcedDisconnect(False)
daemon.SetSuspend(True)

697
wicd/wicd.py Executable file
View File

@@ -0,0 +1,697 @@
#!/usr/bin/env python
""" wicd - wireless connection daemon frontend implementation
This module implements a usermode frontend for wicd. It updates connection
information, provides an (optional) tray icon, and allows for launching of
the wicd GUI and Wired Profile Chooser.
class TrayIcon() -- Parent class of TrayIconGUI and IconConnectionInfo.
class TrayConnectionInfo() -- Child class of TrayIcon which provides
and updates connection status.
class TrayIconGUI() -- Child class of TrayIcon which implements the tray.
icon itself. Parent class of StatusTrayIconGUI and EggTrayIconGUI.
class StatusTrayIconGUI() -- Implements the tray icon using a
gtk.StatusIcon.
class EggTrayIconGUI() -- Implements the tray icon using egg.trayicon.
def usage() -- Prints usage information.
def main() -- Runs the wicd frontend main loop.
"""
#
# Copyright (C) 2007 - 2008 Adam Blackburn
# Copyright (C) 2007 - 2008 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import sys
import gtk
import gobject
import getopt
import os
import pango
from dbus import DBusException
from dbus import version as dbus_version
# Wicd specific imports
import wicd.wpath as wpath
import wicd.misc as misc
import wicd.gui as gui
from wicd.dbusmanager import DBusManager
# Import egg.trayicon if we're using an older gtk version
if not (gtk.gtk_version[0] >= 2 and gtk.gtk_version[1] >= 10):
try:
import egg.trayicon
USE_EGG = True
except ImportError:
print 'Unable to load wicd.py: Missing egg.trayicon module.'
sys.exit(1)
else:
USE_EGG = False
if not dbus_version or (dbus_version < (0, 80, 0)):
import dbus.glib
else:
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
misc.RenameProcess("wicd-client")
if __name__ == '__main__':
wpath.chdir(__file__)
dbus_manager = None
daemon = None
wireless = None
wired = None
wired = None
config = None
language = misc.get_language_list_tray()
class NetworkMenuItem(gtk.ImageMenuItem):
def __init__(self, lbl, is_active=False):
gtk.ImageMenuItem.__init__(self)
self.label = gtk.Label(lbl)
if is_active:
atrlist = pango.AttrList()
atrlist.insert(pango.AttrWeight(pango.WEIGHT_BOLD, 0, 50))
self.label.set_attributes(atrlist)
self.label.set_justify(gtk.JUSTIFY_LEFT)
self.label.set_alignment(0, 0)
self.add(self.label)
self.label.show()
class TrayIcon:
""" Base Tray Icon class.
Base Class for implementing a tray icon to display network status.
"""
def __init__(self, use_tray, animate):
if USE_EGG:
self.tr = self.EggTrayIconGUI(use_tray)
else:
self.tr = self.StatusTrayIconGUI(use_tray)
self.icon_info = self.TrayConnectionInfo(self.tr, use_tray, animate)
class TrayConnectionInfo:
""" Class for updating the tray icon status. """
def __init__(self, tr, use_tray=True, animate=True):
""" Initialize variables needed for the icon status methods. """
self.last_strength = -2
self.still_wired = False
self.network = ''
self.tried_reconnect = False
self.connection_lost_counter = 0
self.tr = tr
self.use_tray = use_tray
self.last_sndbytes = -1
self.last_rcvbytes = -1
self.max_snd_gain = 10000
self.max_rcv_gain = 10000
self.animate = animate
self.update_tray_icon()
def wired_profile_chooser(self):
""" Launch the wired profile chooser. """
gui.WiredProfileChooser()
daemon.SetNeedWiredProfileChooser(False)
def set_wired_state(self, info):
""" Sets the icon info for a wired state. """
wired_ip = info[0]
self.tr.set_from_file(wpath.images + "wired.png")
self.tr.set_tooltip(language['connected_to_wired'].replace('$A',
wired_ip))
def set_wireless_state(self, info):
""" Sets the icon info for a wireless state. """
lock = ''
wireless_ip = info[0]
self.network = info[1]
strength = info[2]
cur_net_id = int(info[3])
sig_string = daemon.FormatSignalForPrinting(str(strength))
if wireless.GetWirelessProperty(cur_net_id, "encryption"):
lock = "-lock"
self.tr.set_tooltip(language['connected_to_wireless']
.replace('$A', self.network)
.replace('$B', sig_string)
.replace('$C', str(wireless_ip)))
self.set_signal_image(int(strength), lock)
def set_connecting_state(self, info):
""" Sets the icon info for a connecting state. """
if info[0] == 'wired' and len(info) == 1:
cur_network = language['wired']
else:
cur_network = info[1]
self.tr.set_tooltip(language['connecting'] + " to " +
cur_network + "...")
self.tr.set_from_file(wpath.images + "no-signal.png")
def set_not_connected_state(self, info):
""" Set the icon info for the not connected state. """
self.tr.set_from_file(wpath.images + "no-signal.png")
if wireless.GetKillSwitchEnabled():
status = (language['not_connected'] + " (" +
language['killswitch_enabled'] + ")")
else:
status = language['not_connected']
self.tr.set_tooltip(status)
def update_tray_icon(self, state=None, info=None):
""" Updates the tray icon and current connection status. """
if not self.use_tray: return False
if not state or not info:
[state, info] = daemon.GetConnectionStatus()
if state == misc.WIRED:
self.set_wired_state(info)
elif state == misc.WIRELESS:
self.set_wireless_state(info)
elif state == misc.CONNECTING:
self.set_connecting_state(info)
elif state in (misc.SUSPENDED, misc.NOT_CONNECTED):
self.set_not_connected_state(info)
else:
print 'Invalid state returned!!!'
return False
return True
def set_signal_image(self, wireless_signal, lock):
""" Sets the tray icon image for an active wireless connection. """
if self.animate:
prefix = self.get_bandwidth_state()
else:
prefix = ''
if daemon.GetSignalDisplayType() == 0:
if wireless_signal > 75:
signal_img = "high-signal"
elif wireless_signal > 50:
signal_img = "good-signal"
elif wireless_signal > 25:
signal_img = "low-signal"
else:
signal_img = "bad-signal"
else:
if wireless_signal >= -60:
signal_img = "high-signal"
elif wireless_signal >= -70:
signal_img = "good-signal"
elif wireless_signal >= -80:
signal_img = "low-signal"
else:
signal_img = "bad-signal"
img_file = ''.join([wpath.images, prefix, signal_img, lock, ".png"])
self.tr.set_from_file(img_file)
def get_bandwidth_state(self):
""" Determines what network activity state we are in. """
transmitting = False
receiving = False
dev_dir = '/sys/class/net/'
wiface = daemon.GetWirelessInterface()
for fldr in os.listdir(dev_dir):
if fldr == wiface:
dev_dir = dev_dir + fldr + "/statistics/"
break
try:
rcvbytes = int(open(dev_dir + "rx_bytes", "r").read().strip())
sndbytes = int(open(dev_dir + "tx_bytes", "r").read().strip())
except IOError:
sndbytes = None
rcvbytes = None
if not rcvbytes or not sndbytes:
return 'idle-'
# Figure out receiving data info.
activity = self.is_network_active(rcvbytes, self.max_rcv_gain,
self.last_rcvbytes)
receiving = activity[0]
self.max_rcv_gain = activity[1]
self.last_rcvbytes = activity[2]
# Figure out out transmitting data info.
activity = self.is_network_active(sndbytes, self.max_snd_gain,
self.last_sndbytes)
transmitting = activity[0]
self.max_snd_gain = activity[1]
self.last_sndbytes = activity[2]
if transmitting and receiving:
return 'both-'
elif transmitting:
return 'transmitting-'
elif receiving:
return 'receiving-'
else:
return 'idle-'
def is_network_active(self, bytes, max_gain, last_bytes):
""" Determines if a network is active.
Determines if a network is active by looking at the
number of bytes sent since the previous check. This method
is generic, and can be used to determine activity in both
the sending and receiving directions.
Returns:
A tuple containing three elements:
1) a boolean specifying if the network is active.
2) an int specifying the maximum gain the network has had.
3) an int specifying the last recorded number of bytes sent.
"""
active = False
if last_bytes == -1:
last_bytes = bytes
elif bytes > (last_bytes + float(max_gain / 20.0)):
last_bytes = bytes
active = True
gain = bytes - last_bytes
if gain > max_gain:
max_gain = gain
return (active, max_gain, last_bytes)
class TrayIconGUI:
""" Base Tray Icon UI class.
Implements methods and variables used by both egg/StatusIcon
tray icons.
"""
def __init__(self, use_tray):
menu = """
<ui>
<menubar name="Menubar">
<menu action="Menu">
<menu action="Connect">
</menu>
<separator/>
<menuitem action="About"/>
<menuitem action="Quit"/>
</menu>
</menubar>
</ui>
"""
actions = [
('Menu', None, 'Menu'),
('Connect', gtk.STOCK_CONNECT, "Connect"),
('About', gtk.STOCK_ABOUT, '_About...', None,
'About wicd-tray-icon', self.on_about),
('Quit',gtk.STOCK_QUIT,'_Quit',None,'Quit wicd-tray-icon',
self.on_quit),
]
actg = gtk.ActionGroup('Actions')
actg.add_actions(actions)
self.manager = gtk.UIManager()
self.manager.insert_action_group(actg, 0)
self.manager.add_ui_from_string(menu)
self.menu = (self.manager.get_widget('/Menubar/Menu/About').
props.parent)
self.gui_win = None
self.current_icon_path = None
self.dbus_available = True
self.use_tray = use_tray
def on_activate(self, data=None):
""" Opens the wicd GUI. """
try:
self.toggle_wicd_gui()
except dbus.DBusException:
self.dbus_available = False
gui.error(None, "Could not connect to wicd daemon. Unable to load GUI")
def on_quit(self, widget=None):
""" Closes the tray icon. """
sys.exit(0)
def on_about(self, data=None):
""" Opens the About Dialog. """
dialog = gtk.AboutDialog()
dialog.set_name('Wicd Tray Icon')
dialog.set_version('2.0')
dialog.set_comments('An icon that shows your network connectivity')
dialog.set_website('http://wicd.net')
dialog.run()
dialog.destroy()
def _add_item_to_menu(self, net_menu, lbl, type_,
n_id, is_connecting, is_active):
""" Add an item to the network list submenu. """
def network_selected(widget, net_type, net_id):
""" Callback method for a menu item selection. """
if net_type == "__wired__":
wired.ConnectWired()
else:
wireless.ConnectWireless(net_id)
item = NetworkMenuItem(lbl, is_active)
image = gtk.Image()
if type_ == "__wired__":
image.set_from_icon_name("network-wired", 2)
else:
pb = gtk.gdk.pixbuf_new_from_file_at_size(self._get_img(n_id),
20, 20)
image.set_from_pixbuf(pb)
del pb
item.set_image(image)
del image
item.connect("activate", network_selected, type_, n_id)
net_menu.append(item)
item.show()
if is_connecting:
item.set_sensitive(False)
del item
def _get_img(self, net_id):
""" Determines which image to use for the wireless entries. """
def fix_strength(val, default):
""" Assigns given strength to a default value if needed. """
return val is not None and int(val) or default
def get_prop(prop):
return wireless.GetWirelessProperty(net_id, prop)
strength = fix_strength(get_prop("quality"), -1)
dbm_strength = fix_strength(get_prop('strength'), -100)
if daemon.GetWPADriver() == 'ralink legacy' or \
daemon.GetSignalDisplayType() == 1:
if dbm_strength >= -60:
signal_img = 'signal-100.png'
elif dbm_strength >= -70:
signal_img = 'signal-75.png'
elif dbm_strength >= -80:
signal_img = 'signal-50.png'
else:
signal_img = 'signal-25.png'
else:
if strength > 75:
signal_img = 'signal-100.png'
elif strength > 50:
signal_img = 'signal-75.png'
elif strength > 25:
signal_img = 'signal-50.png'
else:
signal_img = 'signal-25.png'
return wpath.images + signal_img
def populate_network_menu(self, data=None):
""" Populates the network list submenu. """
def get_prop(net_id, prop):
return wireless.GetWirelessProperty(net_id, prop)
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
submenu = net_menuitem.get_submenu()
self._clear_menu(submenu)
is_connecting = daemon.CheckIfConnecting()
num_networks = wireless.GetNumberOfNetworks()
[status, info] = daemon.GetConnectionStatus()
if wired.GetAlwaysShowWiredInterface() or \
wired.CheckPluggedIn(True):
if status == misc.WIRED:
is_active = True
else:
is_active = False
self._add_item_to_menu(submenu, "Wired Network", "__wired__",
0, is_connecting, is_active)
sep = gtk.SeparatorMenuItem()
submenu.append(sep)
sep.show()
if num_networks > 0:
for x in range(0, num_networks):
essid = get_prop(x, "essid")
if status == misc.WIRELESS and info[1] == essid:
is_active = True
else:
is_active = False
self._add_item_to_menu(submenu, essid, "wifi", x,
is_connecting, is_active)
net_menuitem.show()
def init_network_menu(self):
net_menuitem = self.manager.get_widget("/Menubar/Menu/Connect/")
submenu = net_menuitem.get_submenu()
self._clear_menu(submenu)
loading_item = gtk.MenuItem(language['scanning'] + "...")
loading_item.set_sensitive(False)
loading_item.show()
submenu.append(loading_item)
#net_menuitem.set_submenu(net_menu)
net_menuitem.show()
def _clear_menu(self, menu):
for item in menu.get_children():
menu.remove(item)
item.destroy()
def toggle_wicd_gui(self):
""" Toggles the wicd GUI. """
if not self.gui_win:
self.gui_win = gui.appGui(dbus_manager)
bus = dbus_manager.get_bus()
bus.add_signal_receiver(self.gui_win.dbus_scan_finished,
'SendEndScanSignal',
'org.wicd.daemon')
bus.add_signal_receiver(self.gui_win.dbus_scan_started,
'SendStartScanSignal',
'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:
self.gui_win.exit()
return True
class EggTrayIconGUI(TrayIconGUI):
""" Tray Icon for gtk < 2.10.
Uses the deprecated egg.trayicon module to implement the tray icon.
Since it relies on a deprecated module, this class is only used
for machines running versions of GTK < 2.10.
"""
def __init__(self, use_tray=True):
"""Initializes the tray icon"""
TrayIcon.TrayIconGUI.__init__(self, use_tray)
self.use_tray = use_tray
if not use_tray:
self.toggle_wicd_gui()
return
self.tooltip = gtk.Tooltips()
self.eb = gtk.EventBox()
self.tray = egg.trayicon.TrayIcon("WicdTrayIcon")
self.pic = gtk.Image()
self.tooltip.set_tip(self.eb, "Initializing wicd...")
self.pic.set_from_file("images/no-signal.png")
self.eb.connect('button_press_event', self.tray_clicked)
self.eb.add(self.pic)
self.tray.add(self.eb)
self.tray.show_all()
def tray_clicked(self, widget, event):
""" Handles tray mouse click events. """
if event.button == 1:
self.toggle_wicd_gui()
elif event.button == 3:
self.populate_network_menu()
self.menu.popup(None, None, None, event.button, event.time)
def set_from_file(self, val=None):
""" Calls set_from_file on the gtk.Image for the tray icon. """
if not self.use_tray: return
self.pic.set_from_file(val)
def set_tooltip(self, val):
""" Set the tooltip for this tray icon.
Sets the tooltip for the gtk.ToolTips associated with this
tray icon.
"""
if not self.use_tray: return
self.tooltip.set_tip(self.eb, val)
class StatusTrayIconGUI(gtk.StatusIcon, TrayIconGUI):
""" Class for creating the wicd tray icon on gtk > 2.10.
Uses gtk.StatusIcon to implement a tray icon.
"""
def __init__(self, use_tray=True):
TrayIcon.TrayIconGUI.__init__(self, use_tray)
self.use_tray = use_tray
if not use_tray:
self.toggle_wicd_gui()
return
gtk.StatusIcon.__init__(self)
self.current_icon_path = ''
self.set_visible(True)
self.connect('activate', self.on_activate)
self.connect('popup-menu', self.on_popup_menu)
self.set_from_file(wpath.images + "no-signal.png")
self.set_tooltip("Initializing wicd...")
def on_popup_menu(self, status, button, timestamp):
""" Opens the right click menu for the tray icon. """
self.init_network_menu()
wireless.Scan(reply_handler=self.populate_network_menu,
error_handler=lambda x: x)
self.menu.popup(None, None, None, button, timestamp)
def set_from_file(self, path = None):
""" Sets a new tray icon picture. """
if not self.use_tray: return
if path != self.current_icon_path:
self.current_icon_path = path
gtk.StatusIcon.set_from_file(self, path)
def usage():
""" Print usage information. """
print """
wicd 1.50
wireless (and wired) connection daemon front-end.
Arguments:
\t-n\t--no-tray\tRun wicd without the tray icon.
\t-h\t--help\t\tPrint this help information.
\t-a\t--no-animate\tRun the tray without network traffic tray animations.
"""
def setup_dbus():
global bus, daemon, wireless, wired, config, dbus_manager
dbus_manager = DBusManager()
try:
dbus_manager.connect_to_dbus()
except DBusException:
print "Can't connect to the daemon, trying to start it automatically..."
misc.PromptToStartDaemon()
try:
dbus_manager.connect_to_dbus()
except DBusException:
gui.error(None, "Could not connect to wicd's D-Bus interface. " +
"Make sure the daemon is started.")
sys.exit(1)
dbus_ifaces = dbus_manager.get_dbus_ifaces()
daemon = dbus_ifaces['daemon']
wireless = dbus_ifaces['wireless']
wired = dbus_ifaces['wired']
config = dbus_ifaces['config']
return True
def main(argv):
""" The main frontend program.
Keyword arguments:
argv -- The arguments passed to the script.
"""
use_tray = True
animate = True
try:
opts, args = getopt.getopt(sys.argv[1:], 'nha', ['help', 'no-tray',
'no-animate'])
except getopt.GetoptError:
# Print help information and exit
usage()
sys.exit(2)
for opt, a in opts:
if opt in ('-h', '--help'):
usage()
sys.exit(0)
elif opt in ('-n', '--no-tray'):
use_tray = False
elif opt in ('-a', '--no-animate'):
animate = False
else:
usage()
sys.exit(2)
print 'Loading...'
setup_dbus()
if not use_tray:
the_gui = gui.appGui()
the_gui.standalone = True
mainloop = gobject.MainLoop()
mainloop.run()
sys.exit(0)
# Set up the tray icon GUI and backend
tray_icon = TrayIcon(use_tray, animate)
# Check to see if wired profile chooser was called before icon
# was launched (typically happens on startup or daemon restart).
if daemon.GetNeedWiredProfileChooser():
daemon.SetNeedWiredProfileChooser(False)
tray_icon.icon_info.wired_profile_chooser()
bus = dbus_manager.get_bus()
bus.add_signal_receiver(tray_icon.icon_info.wired_profile_chooser,
'LaunchChooser', 'org.wicd.daemon')
bus.add_signal_receiver(tray_icon.icon_info.update_tray_icon,
'StatusChanged', 'org.wicd.daemon')
print 'Done.'
while 1:
mainloop = gobject.MainLoop()
try:
mainloop.run()
except DBusException:
print 'Warning. Caught a D-Bus exception! Connection to daemon lost.'
print 'Trying to reconnect...'
sleep(10)
try:
setup_dbus()
except:
pass
if __name__ == '__main__':
main(sys.argv)

1359
wicd/wnettools.py Normal file

File diff suppressed because it is too large Load Diff

31
wicd/wpath.py Normal file
View File

@@ -0,0 +1,31 @@
""" Path configuration and functions for the wicd daemon and gui clients.
chdir() -- Change directory to the location of the current file.
"""
import os
# The path containing the wpath.py file.
current = os.path.dirname(os.path.realpath(__file__)) + '/'
# These paths can easily be modified to handle system wide installs, or
# they can be left as is if all files remain with the source directory
# layout.
lib = current
images = lib + 'images/'
encryption = lib + 'encryption/templates/'
bin = current
etc = current + 'data/'
networks = lib + 'encryption/configurations/'
log = current + 'data/'
def chdir(file):
"""Change directory to the location of the specified file.
Keyword arguments:
file -- the file to switch to (usually __file__)
"""
os.chdir(os.path.dirname(os.path.realpath(file)))