Back to index

system-config-printer  1.3.9+20120706
CheckUSBPermissions.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 
00003 ## Printing troubleshooter
00004 
00005 ## Copyright (C) 2008, 2009, 2010 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 glob
00024 import os
00025 import subprocess
00026 from timedops import TimedSubprocess
00027 import urllib
00028 from base import *
00029 class CheckUSBPermissions(Question):
00030     def __init__ (self, troubleshooter):
00031         Question.__init__ (self, troubleshooter, "Check USB permissions")
00032         troubleshooter.new_page (gtk.Label (), self)
00033 
00034     def display (self):
00035         self.answers = {}
00036         answers = self.troubleshooter.answers
00037         if answers['cups_queue_listed']:
00038             if answers['is_cups_class']:
00039                 return False
00040 
00041             cups_printer_dict = answers['cups_printer_dict']
00042             device_uri = cups_printer_dict['device-uri']
00043         elif answers.get ('cups_device_listed', False):
00044             device_uri = answers['cups_device_uri']
00045         else:
00046             return False
00047 
00048         (scheme, rest) = urllib.splittype (device_uri)
00049         if scheme not in ['hp', 'hpfax', 'usb', 'hal']:
00050             return False
00051 
00052         LSUSB = "/sbin/lsusb"
00053         if not os.access (LSUSB, os.X_OK):
00054             return False
00055 
00056         GETFACL = "/usr/bin/getfacl"
00057         if not os.access (GETFACL, os.X_OK):
00058             return False
00059 
00060         new_environ = os.environ.copy()
00061         new_environ['LC_ALL'] = "C"
00062 
00063         # Run lsusb
00064         parent = self.troubleshooter.get_window ()
00065         try:
00066             self.op = TimedSubprocess (parent=parent,
00067                                        args=[LSUSB, "-v"],
00068                                        close_fds=True,
00069                                        env=new_environ,
00070                                        stdin=file("/dev/null"),
00071                                        stdout=subprocess.PIPE,
00072                                        stderr=subprocess.PIPE)
00073             (lsusb_stdout, lsusb_stderr, result) = self.op.run ()
00074         except:
00075             # Problem executing command.
00076             return False
00077 
00078         # Now parse it.
00079         dev_by_id = {}
00080         this_dev = None
00081         for line in lsusb_stdout:
00082             if (this_dev != None and
00083                 ((line.find ("bInterfaceClass") != -1 and
00084                   line.find ("7 Printer") != -1) or
00085                  (line.find ("bInterfaceSubClass") != -1 and
00086                   line.find ("1 Printer") != -1))):
00087                 mfr = dev_by_id.get (this_mfr_id, {})
00088                 mdl = mfr.get (this_mdl_id, [])
00089                 mdl.append (this_dev)
00090                 mfr[this_mdl_id] = mdl
00091                 dev_by_id[this_mfr_id] = mfr
00092                 this_dev = None
00093                 continue
00094 
00095             separators = [ ('Bus ', 3),
00096                            (' Device ', 3),
00097                            (': ID ', 4),
00098                            (':', 4),
00099                            (' ', -1)]
00100             fields = []
00101             i = 0
00102             p = line
00103             while i < len (separators):
00104                 (sep, length) = separators[i]
00105                 if not p.startswith (sep):
00106                     break
00107                 start = len (sep)
00108                 if length == -1:
00109                     end = len (p)
00110                     fields.append (p[start:])
00111                 else:
00112                     end = start + length
00113                     fields.append (p[start:end])
00114 
00115                 p = p[end:]
00116                 i += 1
00117 
00118             if i < len (separators):
00119                 continue
00120 
00121             if not scheme.startswith ('hp') and fields[2] != '03f0':
00122                 # Skip non-HP printers if we know we're using HPLIP.
00123                 continue
00124 
00125             this_dev = { 'bus': fields[0],
00126                          'dev': fields[1],
00127                          'name': fields[4],
00128                          'full': line }
00129             this_mfr_id = fields[2]
00130             this_mdl_id = fields[3]
00131 
00132         infos = {}
00133         paths = []
00134         if not scheme.startswith ('hp'):
00135             paths.extend (glob.glob ("/dev/usb/lp?"))
00136         for mfr_id, mdls in dev_by_id.iteritems ():
00137             for mdl_id, devs in mdls.iteritems ():
00138                 for dev in devs:
00139                     path = "/dev/bus/usb/%s/%s" % (dev['bus'], dev['dev'])
00140                     paths.append (path)
00141                     infos[path] = dev['full']
00142 
00143         perms = []
00144         for path in paths:
00145             try:
00146                 self.op = TimedSubprocess (parent=parent,
00147                                            args=[GETFACL, path],
00148                                            close_fds=True,
00149                                            env=new_environ,
00150                                            stdin=file("/dev/null"),
00151                                            stdout=subprocess.PIPE,
00152                                            stderr=subprocess.PIPE)
00153                 (getfacl_stdout, getfacl_stderr, result) = self.op.run ()
00154                 output = filter (lambda x: len (x) > 0, getfacl_stdout)
00155             except:
00156                 # Problem executing command.
00157                 output = []
00158 
00159             info = infos.get (path, path)
00160             perms.append ((info, output))
00161 
00162         self.answers['getfacl_output'] = perms
00163 
00164         # Don't actually display anything, just collect information.
00165         return False
00166 
00167     def collect_answer (self):
00168         return self.answers
00169 
00170     def cancel_operation (self):
00171         self.op.cancel ()