Back to index

system-config-printer  1.3.9+20120706
CheckNetworkServerSanity.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 
00003 ## Printing troubleshooter
00004 
00005 ## Copyright (C) 2008, 2009, 2010, 2011 Red Hat, Inc.
00006 ## Authors:
00007 ##  Tim Waugh <twaugh@redhat.com>
00008 
00009 ## This program is free software; you can redistribute it and/or modify
00010 ## it under the terms of the GNU General Public License as published by
00011 ## the Free Software Foundation; either version 2 of the License, or
00012 ## (at your option) any later version.
00013 
00014 ## This program is distributed in the hope that it will be useful,
00015 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 ## GNU General Public License for more details.
00018 
00019 ## You should have received a copy of the GNU General Public License
00020 ## along with this program; if not, write to the Free Software
00021 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00022 
00023 import cups
00024 import os
00025 import smburi
00026 import socket
00027 import subprocess
00028 from timedops import TimedSubprocess, TimedOperation
00029 from base import *
00030 
00031 try:
00032     import smbc
00033 except:
00034     pass
00035 
00036 class CheckNetworkServerSanity(Question):
00037     def __init__ (self, troubleshooter):
00038         Question.__init__ (self, troubleshooter, "Check network server sanity")
00039         troubleshooter.new_page (gtk.Label (), self)
00040 
00041     def display (self):
00042         # Collect useful information.
00043 
00044         self.answers = {}
00045         answers = self.troubleshooter.answers
00046         if (not answers.has_key ('remote_server_name') and
00047             not answers.has_key ('remote_server_ip_address')):
00048             return False
00049 
00050         parent = self.troubleshooter.get_window ()
00051 
00052         server_name = answers['remote_server_name']
00053         server_port = answers.get('remote_server_port', 631)
00054         try_connect = False
00055         if server_name:
00056             # Try resolving the hostname.
00057             try:
00058                 ai = socket.getaddrinfo (server_name, server_port)
00059                 resolves = map (lambda (family, socktype,
00060                                         proto, canonname, sockaddr):
00061                                     sockaddr[0], ai)
00062                 try_connect = True
00063             except socket.gaierror:
00064                 resolves = False
00065 
00066             self.answers['remote_server_name_resolves'] = resolves
00067 
00068             ipaddr = answers.get ('remote_server_ip_address', '')
00069             if resolves:
00070                 if ipaddr:
00071                     try:
00072                         resolves.index (ipaddr)
00073                     except ValueError:
00074                         # The IP address given doesn't match the server name.
00075                         # Use the IP address instead of the name.
00076                         server_name = ipaddr
00077                         try_connect = True
00078             elif ipaddr:
00079                 server_name = ipaddr
00080                 try_connect = True
00081         else:
00082             server_name = answers['remote_server_ip_address']
00083             # Validate it.
00084             try:
00085                 ai = socket.getaddrinfo (server_name, server_port)
00086                 resolves = map (lambda (family, socktype,
00087                                         proto, canonname, sockaddr):
00088                                     sockaddr[0], ai)
00089             except socket.gaierror:
00090                 resolves = False
00091 
00092             self.answers['remote_server_name_resolves'] = resolves
00093             try_connect = True
00094 
00095         self.answers['remote_server_try_connect'] = server_name
00096 
00097         if (try_connect and
00098             answers.get ('cups_device_uri_scheme', 'ipp') in ['ipp',
00099                                                               'http',
00100                                                               'https']):
00101             if answers.get ('cups_device_uri_scheme') == 'https':
00102                 encryption = cups.HTTP_ENCRYPT_REQUIRED
00103             else:
00104                 encryption = cups.HTTP_ENCRYPT_IF_REQUESTED
00105 
00106             try:
00107                 self.op = TimedOperation (cups.Connection,
00108                                           kwargs={"host": server_name,
00109                                                   "port": server_port,
00110                                                   "encryption": encryption},
00111                                           parent=parent)
00112                 c = self.op.run ()
00113                 ipp_connect = True
00114             except RuntimeError:
00115                 ipp_connect = False
00116 
00117             self.answers['remote_server_connect_ipp'] = ipp_connect
00118 
00119             if ipp_connect:
00120                 try:
00121                     self.op = TimedOperation (c.getPrinters, parent=parent)
00122                     self.op.run ()
00123                     cups_server = True
00124                 except:
00125                     cups_server = False
00126 
00127                 self.answers['remote_server_cups'] = cups_server
00128 
00129                 if cups_server:
00130                     cups_printer_dict = answers.get ('cups_printer_dict', {})
00131                     uri = cups_printer_dict.get ('device-uri', None)
00132                     if uri:
00133                         try:
00134                             self.op = TimedOperation (c.getPrinterAttributes,
00135                                                       kwargs={"uri": uri},
00136                                                       parent=parent)
00137                             attr = self.op.run ()
00138                             self.answers['remote_cups_queue_attributes'] = attr
00139                         except:
00140                             pass
00141 
00142         if try_connect:
00143             # Try to see if we can connect using smbc.
00144             context = None
00145             try:
00146                 context = smbc.Context ()
00147                 name = self.answers['remote_server_try_connect']
00148                 self.op = TimedOperation (context.opendir,
00149                                           args=("smb://%s/" % name,),
00150                                           parent=parent)
00151                 dir = self.op.run ()
00152                 self.op = TimedOperation (dir.getdents, parent=parent)
00153                 shares = self.op.run ()
00154                 self.answers['remote_server_smb'] = True
00155                 self.answers['remote_server_smb_shares'] = shares
00156             except NameError:
00157                 # No smbc support
00158                 pass
00159             except RuntimeError, (e, s):
00160                 self.answers['remote_server_smb_shares'] = (e, s)
00161 
00162             if context != None and answers.has_key ('cups_printer_dict'):
00163                 uri = answers['cups_printer_dict'].get ('device-uri', '')
00164                 u = smburi.SMBURI (uri)
00165                 (group, host, share, user, password) = u.separate ()
00166                 accessible = False
00167                 try:
00168                     self.op = TimedOperation (context.open,
00169                                               args=("smb://%s/%s" % (host,
00170                                                                      share),
00171                                                     os.O_RDWR,
00172                                                     0777),
00173                                               parent=parent)
00174                     f  = self.op.run ()
00175                     accessible = True
00176                 except RuntimeError, (e, s):
00177                     accessible = (e, s)
00178 
00179                 self.answers['remote_server_smb_share_anon_access'] = accessible
00180 
00181         # Try traceroute if we haven't already.
00182         if (try_connect and
00183             not answers.has_key ('remote_server_traceroute')):
00184             try:
00185                 self.op = TimedSubprocess (parent=parent, close_fds=True,
00186                                            args=['traceroute', '-w', '1',
00187                                                  server_name],
00188                                            stdin=file("/dev/null"),
00189                                            stdout=subprocess.PIPE,
00190                                            stderr=subprocess.PIPE)
00191                 self.answers['remote_server_traceroute'] = self.op.run ()
00192             except:
00193                 # Problem executing command.
00194                 pass
00195 
00196         return False
00197 
00198     def collect_answer (self):
00199         return self.answers
00200 
00201     def cancel_operation (self):
00202         self.op.cancel ()