2 # cnetworkmanager: Command Line Interface for NetworkManager
3 # by: http://en.opensuse.org/User:Mvidner
4 # license: http://www.gnu.org/licenses/gpl-2.0.html or later
7 print "cnetworkmanager %s - Command Line Interface for NetworkManager" % VERSION
11 # find other modules in our prefix, if specified
12 if len(sys
.argv
) > 2 and sys
.argv
[1] == "--prefix":
14 sys
.argv
[1:] = sys
.argv
[3:]
15 sys
.path
.append(prefix
+ "/share/cnetworkmanager");
21 from optparse
import OptionParser
27 print "Install python-1-dbus.rpm or or python-dbus.rpm or python-dbus.deb"
32 # todo - only if loop wanted
33 print "Install python-gobject2.rpm or pygobject2.rpm or python-gobject.deb"
35 # python-gnome.rpm has gconf for nm-applet...
39 from dbus
.mainloop
.glib
import DBusGMainLoop
40 DBusGMainLoop(set_as_default
=True)
43 from monitor
import MonitorBase
44 from configparser_knm
import ConfigParserKNM
45 from mkconmap
import *
50 from manager06
import cNM_06
51 from manager07
import cNM_07
52 from device
import cDevice
53 from device06
import cDevice_06
54 from device07
import cDevice_07
56 from ap06
import cAP_06
57 from ap07
import cAP_07
61 bus
= dbus
.SystemBus()
63 # FOOC = connection (service) string
64 # FOOI = interface string
67 # foopi = property interface
68 SSC
= "org.freedesktop.NetworkManagerSystemSettings"
69 USC
= "org.freedesktop.NetworkManagerUserSettings"
70 NMIC
= "org.freedesktop.NetworkManagerInfo"
73 ii
= dbus
.Interface(obj
, 'org.freedesktop.DBus.Introspectable')
77 "Detects NM version and chooses appropriate class"
79 nmo
= bus
.get_object(NMC
, opath
)
80 nmi
= dbus
.Interface(nmo
, NMI
)
82 dummy
= nmi
.getDevices()
83 return cNM_06(opath
, options
)
84 except dbus
.exceptions
.DBusException
, e
:
85 if e
.get_dbus_name() == 'org.freedesktop.DBus.Error.AccessDenied':
87 return cNM_07(opath
, options
)
89 def opath_validchar(c
):
90 # _ is also escaped even though it is valid
92 string
.ascii_letters
.find(c
) != -1 or \
93 string
.digits
.find(c
) != -1
98 # TODO find a more elegant way
99 if not opath_validchar(c
):
105 def opath_unescape(s
):
107 unhex
= lambda xx
: chr(eval("0x"+xx
))
109 return re
.sub("_.._", lambda p
: unhex(p
.group()[1:3]), s
)
111 # this is the client side of the applet; see also UserSettings
113 def __init__(self
, svc
, opath
):
116 self
.so
= bus
.get_object(self
.svc
, self
.opath
)
117 self
.si
= dbus
.Interface(self
.so
, 'org.freedesktop.NetworkManagerSettings')
120 return self
.svc
== SSC
;
123 for conn
in self
.Connections():
128 def DumpSystem(self
):
129 sspi
= dbus
.Interface(self
.so
, PI
)
130 print "Unmanaged Devices"
131 umds
= sspi
.Get(NMI
, "UnmanagedDevices")
134 # dump_settings_conn(svc, conn) umd?
137 def myConnection(self
, opath
):
138 return cConnection(self
.svc
, opath
)
140 def Connections(self
):
141 opaths
= self
.si
.ListConnections()
142 return map(self
.myConnection
, opaths
)
144 NETWORK_TYPE_ALLOWED
= 1
145 class cApplet_06(cApplet
):
146 def __init__(self
, svc
, opath
):
149 self
.io
= bus
.get_object(self
.svc
, self
.opath
)
150 self
.ii
= dbus
.Interface(self
.io
, 'org.freedesktop.NetworkManagerInfo')
155 def myConnection(self
, opath
):
156 return cConnection_06(self
, opath
)
158 # TODO also VPN conns
159 def Connections(self
):
160 names
= self
.ii
.getNetworks(NETWORK_TYPE_ALLOWED
)
161 return map(self
.myConnection
, names
)
164 def __init__(self
, svc
, opath
):
167 self
.co
= bus
.get_object(self
.svc
, self
.opath
)
168 self
.ci
= dbus
.Interface(self
.co
, 'org.freedesktop.NetworkManagerSettings.Connection')
171 print "Conn:", self
.opath
172 settings
= self
.Settings()
175 si
= dbus
.Interface(self
.co
, 'org.freedesktop.NetworkManagerSettings.Connection.Secrets')
176 security
= settings
.Security()
178 print " SECRETS:", security
181 secrets
= cSettings(si
.GetSecrets(security
,[],False))
183 except dbus
.exceptions
.DBusException
, e
:
184 if e
.get_dbus_name() == "org.freedesktop.DBus.Error.AccessDenied":
185 print " Access denied"
188 print " FIXME figure out 802-1x secrets"
191 return cSettings(self
.ci
.GetSettings())
193 def dump_time(unixtime
):
194 return time
.asctime(time
.localtime(unixtime
))
196 class cConnection_06
:
197 def __init__(self
, applet
, id):
202 print "Conn:", self
.id
204 np
= self
.applet
.ii
.getNetworkProperties(self
.id, NETWORK_TYPE_ALLOWED
)
207 print " time:", dump_time(np
[1])
208 print " trusted:", bool(np
[2])
209 print " bssids:", ", ".join(np
[3])
211 print " we_cipher:", enctype
213 print " secret:", np
[5]
215 print " wep_auth_algorithm:", np
[6]
217 print " wpa_psk_key_mgt:", np
[6]
218 print " wpa_psk_wpa_version:", np
[7]
220 return # nm-applet will not tell kfn anyway
221 devp
= "/org/freedesktop/NetworkManager/Devices/ath0" #FIXME
222 netp
= devp
+ "/Networks/" + opath_escape(self
.id)
225 kfn
= self
.applet
.ii
.getKeyForNetwork(devp
, netp
, ssid
, attempt
, newkey
)
230 NM_AUTH_TYPE_WPA_PSK_AUTO
= 0x00000000
231 NM_AUTH_TYPE_NONE
= 0x00000001
232 NM_AUTH_TYPE_WEP40
= 0x00000002
233 NM_AUTH_TYPE_WPA_PSK_TKIP
= 0x00000004
234 NM_AUTH_TYPE_WPA_PSK_CCMP
= 0x00000008
235 NM_AUTH_TYPE_WEP104
= 0x00000010
236 NM_AUTH_TYPE_WPA_EAP
= 0x00000020
237 NM_AUTH_TYPE_LEAP
= 0x00000040
239 IW_AUTH_ALG_OPEN_SYSTEM
= 0x00000001
240 IW_AUTH_ALG_SHARED_KEY
= 0x00000002
241 IW_AUTH_ALG_LEAP
= 0x00000004
244 def __init__(self
, conmap
):
245 #print "INIT", conmap
249 return self
.conmap
["connection"]["type"]
252 return self
.conmap
["connection"]["id"]
256 return self
.conmap
["802-11-wireless"]["ssid"]
259 # probably 802-3-ethernet
264 return self
.conmap
["connection"]["timestamp"]
272 def SeenBssids(self
):
274 return self
.conmap
["802-11-wireless"]["seen-bssids"]
282 return NM_AUTH_TYPE_WEP104
284 return NM_AUTH_TYPE_WPA_PSK_AUTO
286 return NM_AUTH_TYPE_NONE
287 print "Defaulting cipher type to none"
288 return NM_AUTH_TYPE_NONE
292 return self
.conmap
["802-11-wireless-security"]["psk"]
296 return self
.conmap
["802-11-wireless-security"]["wep-key0"]
302 def WepAuthAlgorithm(self
):
303 print "FIXME Defaulting WEP auth alg to open"
304 return IW_AUTH_ALG_OPEN_SYSTEM
307 print "FIXME Defaulting PSK key mgmt to 2"
310 def PskWpaVersion(self
):
311 print "FIXME Defaulting WPA version to 2"
316 return self
.conmap
[self
.Type()]["security"]
320 def isNet(self
, net_name
):
321 return self
.ID() == net_name
or self
.Ssid() == net_name
323 # FIXME check spec/NM what to censor
324 secrets
= dict.fromkeys(["wep-key0", "psk"])
327 "For GetSettings: censor secrets."
330 for n1
, v1
in self
.conmap
.iteritems():
332 for n2
, v2
in v1
.iteritems():
334 if self
.secrets
.has_key(n2
):
340 "For GetSecrets: only secrets."
349 for n1
, v1
in self
.conmap
.iteritems():
351 for n2
, v2
in v1
.iteritems():
352 print " %s: %s" % (n2
, v2
)
354 # server analog of cApplet
355 class UserSettings(dbus
.service
.Object
):
357 def __init__(self
, opath
, conmaps
):
358 dbus
.service
.Object
.__init
__(self
, bus
, opath
)
359 #print "CONMAPS:", conmaps
360 self
.conns
= map(self
.newCon
, conmaps
)
362 def addCon(self
, conmap
):
363 c
= self
.newCon(conmap
)
368 def newCon(self
, conmap
):
369 cpath
= "/MyConnection/%d" % self
.counter
370 self
.counter
= self
.counter
+ 1
371 c
= Connection(cpath
, conmap
)
372 self
.NewConnection(cpath
) # announce it
375 @dbus.service
.method(dbus_interface
='org.freedesktop.NetworkManagerSettings',
376 in_signature
='', out_signature
='ao')
377 def ListConnections(self
):
378 return [c
.__dbus
_object
_path
__ for c
in self
.conns
]
380 #this is for EMITTING a signal, not receiving it
381 @dbus.service
.signal(dbus_interface
='org.freedesktop.NetworkManagerSettings',
383 def NewConnection(self
, opath
):
385 #print "signalling newconn:", opath
387 def GetByNet(self
, net_name
):
388 "Returns connection, or None"
390 if c
.isNet(net_name
):
395 class UserSettings_06(UserSettings
):
397 def __init__(self
, opath
, conmaps
):
398 dbus
.service
.Object
.__init
__(self
, bus
, opath
)
399 #print "CONMAPS:", conmaps
400 self
.conns
= map(self
.newCon
, conmaps
)
403 def newCon(self
, conmap
):
404 cpath
= "/MyConnection/%d" % self
.counter
405 self
.counter
= self
.counter
+ 1
406 c
= Connection_06(cpath
, conmap
)
407 #self.NewConnection(cpath) # announce it
410 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
411 in_signature
="i", out_signature
='as')
412 def getNetworks(self
, i
):
413 # FIXME bytearray to str WHERE?
414 #n = [ssid_str(c.Ssid()) for c in self.conns]
415 n
= [c
.ID() for c
in self
.conns
]
416 print "getNetworks:", n
419 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
420 in_signature
="", out_signature
='ao') # out??
421 def getVPNConnections(self
):
424 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
426 #out_signature='sibasi') #varies
427 def getNetworkProperties(self
, net
, type):
429 # type is 1, NETWORK_TYPE_ALLOWED
430 c
= self
.GetByNet(net
)
432 return c
.getNetworkProperties()
433 print "Oops, could not getNetworkProperties for " + net
436 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
437 in_signature
="oosib")
438 #out_signature="isi") varies
439 def getKeyForNetwork(self
, dev
, net
, ssid
, attempt
, newkey
):
440 print "GKFN", dev
, net
, ssid
, attempt
, bool(newkey
)
442 m
= "Cannot ask for key"
444 raise dbus
.exceptions
.DBusException(m
)
446 snet
= opath_unescape(net
[net
.rfind("/")+1 : ]) # only stuff after /
447 c
= self
.GetByNet(snet
)
449 return c
.getKeyForNetwork()
450 print "Oops, could not getKeyForNetwork " + net
452 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
454 #in_signature="sbs isi", varies
455 def updateNetworkInfo(self
, ssid
, automatic
, bssid
, *security
):
456 print "Connected successfully"
460 print " automatic:", bool(automatic
)
461 print " bssid:", bssid
462 print " security:", security
465 def GetByNet(self
, net_name
):
466 "Returns connection, or None"
468 if c
.isNet(net_name
):
473 # server analog of cConnection
474 class Connection(dbus
.service
.Object
):
475 def __init__(self
, opath
, conmap
):
476 dbus
.service
.Object
.__init
__(self
, bus
, opath
)
477 self
.settings
= cSettings(conmap
)
479 @dbus.service
.method(dbus_interface
='org.freedesktop.NetworkManagerSettings.Connection',
480 sender_keyword
='sender',
481 in_signature
='', out_signature
='a{sa{sv}}')
482 def GetSettings(self
, sender
):
483 #print "Getting settings:", self. __dbus_object_path__
484 # return self.settings.ConMap()
485 # grr, censoring secrets makes NM complain!?
486 # bnc#479566#c3: Until I figure out how to make it work with
487 # censored secrets, only pass the settings to the same user.
488 sender_uid
= bus
.get_unix_user(sender
)
489 if sender_uid
!= 0 and sender_uid
!= os
.geteuid():
490 e
= "User %u is not permitted to read the settings" % sender_uid
492 raise dbus
.exceptions
.DBusException(e
) # could do NM_SETTINGS_ERROR_* instead
493 return self
.settings
.conmap
495 @dbus.service
.method(dbus_interface
='org.freedesktop.NetworkManagerSettings.Connection.Secrets',
496 in_signature
='sasb', out_signature
='a{sa{sv}}')
497 def GetSecrets(self
, tag
, hints
, ask
):
499 print "Getting secrets:", self
.__dbus
_object
_path
__
500 return self
.settings
.SecMap()
502 @dbus.service
.method(dbus_interface
='org.freedesktop.NetworkManagerSettings.Connection',
503 in_signature
='', out_signature
='s')
505 return self
.settings
.ID()
508 return self
.settings
.Ssid()
510 def isNet(self
, net_name
):
511 return self
.settings
.isNet(net_name
)
513 class Connection_06(Connection
):
514 def __init__(self
, opath
, conmap
):
515 dbus
.service
.Object
.__init
__(self
, bus
, opath
)
517 self
.settings
= cSettings(conmap
)
519 # dbus.service.method
520 def getNetworkProperties(self
):
521 # essid, timestamp, ?, bssids, we_cipher, ?, ...
522 # we_cipher=16: i wep_auth_algorithm
523 # we_cipher=0: i wpa_psk_key_mgt, i wpa_psk_wpa_version
524 ssid
= ssid_str(self
.settings
.Ssid())
525 time
= self
.settings
.Timestamp() # last sucessfully connected? seen?
526 trusted
= self
.settings
.Trusted()
527 bssids
= dbus
.Array(self
.settings
.SeenBssids(), signature
="s")
528 r
= [ssid
, time
, trusted
, bssids
]
529 security
= self
.getKeyForNetwork("fake key")
533 # dbus.service.method
534 def getKeyForNetwork(self
, fake
="no"):
536 key
= self
.settings
.Key()
541 cip
= self
.settings
.WeCipher()
542 if cip
== NM_AUTH_TYPE_NONE
:
543 security
= tuple([cip
])
544 elif cip
== NM_AUTH_TYPE_WEP40
or cip
== NM_AUTH_TYPE_WEP104
:
545 wep_auth_algorithm
= self
.settings
.WepAuthAlgorithm()
546 security
= (cip
, key
, wep_auth_algorithm
)
547 elif cip
== NM_AUTH_TYPE_WPA_PSK_AUTO
or cip
== NM_AUTH_TYPE_TKIP
or \
548 cip
== NM_AUTH_TYPE_CCMP
:
549 wpa_psk_key_mgt
= self
.settings
.PskKeyMgt()
550 wpa_psk_wpa_version
= self
.settings
.PskWpaVersion()
551 security
= (cip
, key
, wpa_psk_key_mgt
, wpa_psk_wpa_version
)
552 elif cip
== NM_AUTH_TYPE_WPA_EAP
:
553 security
= tuple([cip
]) # TODO more...
554 elif cip
== NM_AUTH_TYPE_LEAP
:
555 security
= tuple([cip
]) # TODO more...
560 class Monitor(MonitorBase
):
561 def __init__(self
, bus
):
562 MonitorBase
.__init
__(self
, bus
)
566 dbus_interface
="org.freedesktop.NetworkManager.Device.Wireless",
567 signal_name
="PropertiesChanged")
570 dbus_interface
="org.freedesktop.NetworkManager.AccessPoint",
571 signal_name
="PropertiesChanged")
573 self
.ignore("org.freedesktop.Hal.Device", "PropertyModified")
574 self
.ignore("fi.epitest.hostap.WPASupplicant.Interface", "ScanResultsAvailable")
575 self
.ignore("com.redhat.PrinterSpooler", "QueueChanged")
576 self
.ignore("org.freedesktop.NetworkManager", "StateChange") # deprecated
577 self
.watch(self
.nm_sc_h
, "org.freedesktop.NetworkManager", "StateChanged")
578 self
.watch(self
.wpas_isc_h
, "fi.epitest.hostap.WPASupplicant.Interface", "StateChange")
579 self
.watch(self
.nmd_sc_h
, "org.freedesktop.NetworkManager.Device", "StateChanged")
580 self
.watch(self
.bus_noc_h
, "org.freedesktop.DBus", "NameOwnerChanged")
582 def bus_noc_h(self
, *args
, **kwargs
):
583 (name
, old
, new
) = args
588 print "\tBUS NOC\t%s %s" % (name
, new
)
590 def wpas_isc_h(self
, *args
, **kwargs
):
591 opath
= kwargs
["path"]
593 print "\tWPAS %s\t(%s, was %s)" % (new
, opath
, old
.lower())
595 def nmd_sc_h(self
, *args
, **kwargs
):
596 opath
= kwargs
["path"]
597 (new
, old
, reason
) = args
598 news
= cDevice_07
.NM_DEVICE_STATE
[new
]
599 olds
= cDevice_07
.NM_DEVICE_STATE
[old
]
602 reasons
= "reason %d" % reason
603 print "\tDevice State %s\t(%s, was %s%s)" % (news
, opath
, olds
.lower(), reasons
)
605 def nm_sc_h(self
, *args
, **kwargs
):
608 print "\tNM State:", ss
610 def propc_h(self
, *args
, **kwargs
):
611 opath
= kwargs
["path"]
613 for k
, v
in props
.iteritems():
616 line
= "\tPROP\t%s\t%s\t(%s)" % (k
, v
, opath
)
623 op
= OptionParser(version
="%prog " + VERSION
)
624 op
.add_option("-d", "--dev",
625 action
="store_true", default
=False,
627 op
.add_option("-c", "--actcon",
628 action
="store_true", default
=False,
629 help="list active connections")
630 op
.add_option("-u", "--usrcon",
631 action
="store_true", default
=False,
632 help="list user connection settings (can CRASH nm-applet)")
633 op
.add_option("-s", "--syscon",
634 action
="store_true", default
=False,
635 help="list system connection settings")
636 op
.add_option("-a", "--ap",
637 action
="store_true", default
=False,
638 help="list found access points")
639 op
.add_option("-n", "--nets",
640 action
="store_true", default
=False,
641 help="list found wireless networks")
642 # TODO http://docs.python.org/lib/optparse-adding-new-types.html
643 op
.add_option("-w", "--wifi",
644 choices
=["0","1","off","on","no","yes","false","true"],
646 help="enable or disable wireless")
647 op
.add_option("-o", "--online",
648 choices
=["0","1","off","on","no","yes","false","true"],
650 help="enable or disable network at all")
652 op
.add_option("--activate-connection",
653 help="raw API: activate the KIND(user/system) connection CON on device DEV using AP",
654 metavar
="[KIND],CON,DEV,[AP]")
655 op
.add_option("-C", "--connect",
656 help="connect to a wireless network NET (using knetworkmanagerrc or the key options below)",
658 op
.add_option("--unprotected",
659 action
="store_true", default
=False,
660 help="network does not require a key")
661 op
.add_option("--wep-hex",
663 help="use this WEP key of 26 hex digits")
664 op
.add_option("--wep-pass",
666 help="use this WEP passphrase")
667 op
.add_option("--wpa-psk-hex",
669 help="use this WPA key of 64 hex digits")
670 op
.add_option("--wpa-pass",
672 help="use this WPA passphrase")
673 op
.add_option("-m", "--monitor",
674 action
="store_true", default
=False,
675 help="loop to show dbus signals")
678 (options
, args
) = op
.parse_args()
686 nmp
= '/org/freedesktop/NetworkManager'
689 except dbus
.exceptions
.DBusException
, e
:
690 print "NetworkManager is not running or running as an other user"
692 if options
.dev
or options
.actcon
:
695 true_choices
= ["1", "on", "yes", "true"]
696 if options
.wifi
!= None:
697 nm
.SetWifiEnabled(options
.wifi
in true_choices
)
698 if options
.online
!= None:
699 nm
.SetOnline(options
.online
in true_choices
)
705 print "SYSTEM Connections"
707 print "Cannot do that with NM 0.6"
710 ss
= cApplet(SSC
, '/org/freedesktop/NetworkManagerSettings')
714 print "USER Connections"
717 us
= cApplet_06(NMIC
, "/org/freedesktop/NetworkManagerInfo")
719 us
= cApplet(USC
, '/org/freedesktop/NetworkManagerSettings')
721 except dbus
.exceptions
.DBusException
, e
:
723 #if e.get_dbus_name() == "org.freedesktop.DBus.Error.ServiceUnknown":
724 print "Applet is not running"
727 nmo
= bus
.get_object(NMC
, nmp
)
728 nmi
= dbus
.Interface(nmo
, NMI
)
730 def service_pid(name
):
731 DBS
= 'org.freedesktop.DBus'
733 dbo
= bus
.get_object(DBS
, '/')
734 dbi
= dbus
.Interface(dbo
, DBI
)
735 owner
= dbi
.GetNameOwner(name
)
736 pid
= dbi
.GetConnectionUnixProcessID(owner
)
739 # TODO UserSettings_06
740 if options
.connect
!= None:
745 brn
= bus
.request_name(name
, _dbus_bindings
.NAME_FLAG_DO_NOT_QUEUE
)
746 if brn
== _dbus_bindings
.REQUEST_NAME_REPLY_EXISTS
:
747 print "Could not provide settings service, another applet is running (pid %s)" % service_pid(name
)
749 cfg
= ConfigParserKNM()
751 us
= UserSettings_06("/org/freedesktop/NetworkManagerInfo",
754 us
= UserSettings("/org/freedesktop/NetworkManagerSettings",
757 def Connect(wanted_net
): # any. or take arg. net is config name or ssid name
758 # ... in general, look for string in all config data. ssid for wifi, whatever for dialup
759 # TODO also respect autoconnect
761 # ActivateConn wants setting device ap; can find device from ap? ap is "specific" for wifi devices
762 #print "Connection wanted to", wanted_net
763 found_con
= found_ap
= found_dev
= None
764 for dev
in nm
.Devices():
766 if wanted_net
== ap
.Ssid():
769 break # FIXME both loops
770 found_con
= us
.GetByNet(wanted_net
)
772 print "No AP found with SSID", wanted_net
774 if found_con
== None:
775 print "No settings for net %s, assuming no key is needed" % wanted_net
776 c
= mkconmap_wifi(wanted_net
)
777 found_con
= us
.addCon(c
)
778 nm
.ActivateConnection(found_con
, found_dev
, found_ap
) # TODO async
779 # TODO run loop, exit it when we have serviced the required calls
782 if options
.connect
!= None:
783 if options
.unprotected
:
784 c
= mkconmap_wifi(options
.connect
)
786 if options
.wep_hex
!= None:
787 c
= mkconmap_wep(options
.connect
, options
.wep_hex
)
789 if options
.wep_pass
!= None:
790 c
= mkconmap_wep_pass(options
.connect
, options
.wep_pass
)
792 if options
.wpa_psk_hex
!= None:
793 c
= mkconmap_psk(options
.connect
, options
.wpa_psk_hex
)
795 if options
.wpa_pass
!= None:
796 c
= mkconmap_psk(options
.connect
, options
.wpa_pass
)
799 if Connect(options
.connect
):
804 if options
.activate_connection
!= None:
805 (svc
, conpath
, devpath
, appath
) = options
.activate_connection
.split(',')
806 if svc
== "" or svc
== "user":
808 elif svc
== "system":
816 nm
.nmi
.ActivateConnection(svc
, conpath
, devpath
, appath
,
817 reply_handler
=nm
.silent_handler
,
818 error_handler
=nm
.err_handler
,
826 loop
= gobject
.MainLoop()