home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- '''Convenience functions for use in package hooks.
-
- Copyright (C) 2008-2009 Canonical Ltd.
- Author: Matt Zimmerman <mdz@canonical.com>
- Contributor: Brian Murray <brian@ubuntu.com>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2 of the License, or (at your
- option) any later version. See http://www.gnu.org/copyleft/gpl.html for
- the full text of the license.
- '''
- import subprocess
- import hashlib
- import os
- import datetime
- import glob
- import re
- import string
- import xml.dom as xml
- import xml.dom.minidom as xml
- from packaging_impl import impl as packaging
- _path_key_trans = string.maketrans('#/-_+', '.....')
-
- def path_to_key(path):
- """Generate a valid report key name from a file path.
-
- This will meet apport's restrictions on the characters used in keys.
- """
- return path.translate(_path_key_trans)
-
-
- def attach_file_if_exists(report, path, key = None):
- '''Attach file contents if file exists.'''
- if not key:
- key = path_to_key(path)
-
- if os.path.exists(path):
- attach_file(report, path, key)
-
-
-
- def read_file(path):
- '''Return the contents of the specified path.
-
- Upon error, this will deliver a a text representation of the error,
- instead of failing.
- '''
-
- try:
- return open(path).read().strip()
- except Exception:
- e = None
- return 'Error: ' + str(e)
-
-
-
- def attach_file(report, path, key = None):
- '''Attach a file to the report.
-
- If key is not specified, the key name will be derived from the file
- name with path_to_key().
- '''
- if not key:
- key = path_to_key(path)
-
- report[key] = read_file(path)
-
-
- def attach_conffiles(report, package, conffiles = None):
- '''Attach information about any modified or deleted conffiles'''
- output = command_output([
- 'dpkg-query',
- '-W',
- '--showformat=${Conffiles}',
- package])
- for line in output.split('\n'):
- (path, default_md5sum) = line.strip().split()
- if conffiles and path not in conffiles:
- continue
-
- key = 'modified.conffile.' + path_to_key(path)
- if os.path.exists(path):
- contents = open(path).read()
- m = hashlib.md5()
- m.update(contents)
- calculated_md5sum = m.hexdigest()
- if calculated_md5sum != default_md5sum:
- report[key] = contents
- statinfo = os.stat(path)
- mtime = datetime.datetime.fromtimestamp(statinfo.st_mtime)
- mtime_key = 'mtime.conffile.' + path_to_key(path)
- report[mtime_key] = mtime.isoformat()
-
- calculated_md5sum != default_md5sum
- report[key] = '[deleted]'
-
-
-
- def attach_dmesg(report):
- '''Attach information from the kernel ring buffer (dmesg).'''
- report['BootDmesg'] = open('/var/log/dmesg').read()
- report['CurrentDmesg'] = command_output([
- 'sh',
- '-c',
- 'dmesg | comm -13 /var/log/dmesg -'])
-
-
- def attach_machinetype(report):
- '''Calculate and attach a specific machine type if possible.'''
- if 'HalComputerInfo' in report:
- system = ''
- vendor = re.compile("system.hardware.vendor\\s*=\\s*'(.*)'\\s*\\(string\\)")
- match = vendor.search(report['HalComputerInfo'])
- if match:
- system += match.group(1).rstrip() + ' '
-
- product = re.compile("system.hardware.product\\s*=\\s*'(.*)'\\s*\\(string\\)")
- match = product.search(report['HalComputerInfo'])
- if match:
- system += match.group(1).rstrip() + ' '
-
- if system != '':
- report['MachineType'] = system.rstrip()
-
-
-
-
- def attach_hardware(report):
- attach_dmesg(report)
- attach_file(report, '/proc/interrupts', 'ProcInterrupts')
- attach_file(report, '/proc/version_signature', 'ProcVersionSignature')
- attach_file(report, '/proc/cpuinfo', 'ProcCpuinfo')
- attach_file(report, '/proc/cmdline', 'ProcCmdLine')
- attach_file(report, '/proc/modules', 'ProcModules')
- report['Lspci'] = command_output([
- 'lspci',
- '-vvnn'])
- report['Lsusb'] = command_output([
- 'lsusb'])
- report['HalComputerInfo'] = hal_dump_udi('/org/freedesktop/Hal/devices/computer')
- if 'Uname' in report:
- del report['Uname']
-
- attach_machinetype(report)
-
-
- def attach_alsa(report):
- '''Attach ALSA subsystem information to the report.
-
- (loosely based on http://www.alsa-project.org/alsa-info.sh)
- '''
- attach_file_if_exists(report, os.path.expanduser('~/.asoundrc'), 'UserAsoundrc')
- attach_file_if_exists(report, os.path.expanduser('~/.asoundrc.asoundconf'), 'UserAsoundrcAsoundconf')
- attach_file_if_exists(report, '/etc/asound.conf')
- report['AlsaDevices'] = command_output([
- 'ls',
- '-l',
- '/dev/snd/'])
- report['AplayDevices'] = command_output([
- 'aplay',
- '-l'])
- report['ArecordDevices'] = command_output([
- 'arecord',
- '-l'])
- report['PciMultimedia'] = pci_devices(PCI_MULTIMEDIA)
- cards = []
- for line in open('/proc/asound/cards'):
- if ']:' in line:
- fields = line.lstrip().split()
- cards.append(int(fields[0]))
- continue
-
- for card in cards:
- key = 'Card%d.Amixer.info' % card
- report[key] = command_output([
- 'amixer',
- '-c',
- str(card),
- 'info'])
- key = 'Card%d.Amixer.values' % card
- report[key] = command_output([
- 'amixer',
- '-c',
- str(card)])
- for codecpath in glob.glob('/proc/asound/card%d/codec*' % card):
- if os.path.isfile(codecpath):
- codec = os.path.basename(codecpath)
- key = 'Card%d.Codecs.%s' % (card, path_to_key(codec))
- attach_file(report, codecpath, key = key)
- continue
- if os.path.isdir(codecpath):
- codec = os.path.basename(codecpath)
- for name in os.listdir(codecpath):
- path = os.path.join(codecpath, name)
- key = 'Card%d.Codecs.%s.%s' % (card, path_to_key(codec), path_to_key(name))
- attach_file(report, path, key)
-
-
-
- report['AudioDevicesInUse'] = command_output([
- 'fuser',
- '-v'] + glob.glob('/dev/dsp*') + glob.glob('/dev/snd/*') + glob.glob('/dev/seq*'))
- attach_dmesg(report)
-
-
- def command_output(command, input = None, stderr = subprocess.STDOUT):
- '''Try to execute given command (array) and return its stdout.
-
- In case of failure, a textual error gets returned.
- '''
-
- try:
- sp = subprocess.Popen(command, stdout = subprocess.PIPE, stderr = stderr, close_fds = True)
- except OSError:
- e = None
- return 'Error: ' + str(e)
-
- out = sp.communicate(input)[0]
- if sp.returncode == 0:
- return out.strip()
- return 'Error: command %s failed with exit code %i: %s' % (str(command), sp.returncode, out)
-
-
- def recent_syslog(pattern):
- '''Extract recent messages from syslog which match a regex.
-
- pattern should be a "re" object.
- '''
- lines = ''
- for line in open('/var/log/syslog'):
- if pattern.search(line):
- lines += line
- continue
-
- return lines
-
- PCI_MASS_STORAGE = 1
- PCI_NETWORK = 2
- PCI_DISPLAY = 3
- PCI_MULTIMEDIA = 4
- PCI_MEMORY = 5
- PCI_BRIDGE = 6
- PCI_SIMPLE_COMMUNICATIONS = 7
- PCI_BASE_SYSTEM_PERIPHERALS = 8
- PCI_INPUT_DEVICES = 9
- PCI_DOCKING_STATIONS = 10
- PCI_PROCESSORS = 11
- PCI_SERIAL_BUS = 12
-
- def pci_devices(*pci_classes):
- '''Return a text dump of PCI devices attached to the system.'''
- if not pci_classes:
- return command_output([
- 'lspci',
- '-vvnn'])
- slots = []
- output = command_output([
- 'lspci',
- '-vvmmnn'])
- for paragraph in output.split('\n\n'):
- pci_class = None
- pci_subclass = None
- slot = None
- for line in paragraph.split('\n'):
- (key, value) = line.split(':', 1)
- value = value.strip()
- key = key.strip()
- if key == 'Class':
- n = int(value[-5:-1], 16)
- pci_class = (n & 65280) >> 8
- pci_subclass = n & 255
- continue
- pci_classes
- if key == 'Slot':
- slot = value
- continue
-
- if pci_class and slot and pci_class in pci_classes:
- slots.append(slot)
- continue
-
- cmd = [
- 'lspci',
- '-vvnn']
- for slot in slots:
- cmd.extend([
- '-s',
- slot])
-
- return command_output(cmd)
-
-
- def usb_devices():
- '''Return a text dump of USB devices attached to the system.'''
- return command_output([
- 'lsusb',
- '-v'])
-
-
- def hal_find_by_capability(capability):
- '''Retrieve a list of UDIs for hal objects having the specified capability.'''
- output = command_output([
- 'hal-find-by-capability',
- '--capability',
- capability])
- return output.split('\n')
-
-
- def hal_dump_udi(udi):
- '''Dump the properties of a HAL object, specified by its UDI.'''
- out = command_output([
- 'lshal',
- '-u',
- udi])
- result = ''
- for l in out.splitlines():
- if '.serial =' in l:
- continue
-
- result += l + '\n'
-
- return result
-
-
- def files_in_package(package, globpat = None):
- '''Retrieve a list of files owned by package, optionally matching globpat'''
- files = packaging.get_files(package)
- return result
-
-
- def attach_gconf(report, package):
- '''Attach information about gconf keys set to non-default values.'''
- import gconf
- import glib
- client = gconf.client_get_default()
- non_defaults = { }
- for schema_file in files_in_package(package, '/usr/share/gconf/schemas/*.schemas'):
- for key, default_value in _parse_gconf_schema(schema_file).items():
-
- try:
- value = client.get(key).to_string()
- if value != default_value:
- non_defaults[key] = value
- continue
- except glib.GError:
- value = command_output([
- 'gconftool-2',
- '-g',
- key])
- if value != default_value:
- non_defaults[key] = value
-
- value != default_value
-
-
-
-
- if non_defaults:
- s = ''
- keys = non_defaults.keys()
- keys.sort()
- for key in keys:
- value = non_defaults[key]
- s += '%s=%s\n' % (key, value)
-
- report['GConfNonDefault'] = s
-
-
-
- def attach_network(report):
- '''Attach network-related information to report.'''
- report['IpRoute'] = command_output([
- 'ip',
- 'route'])
- report['IpAddr'] = command_output([
- 'ip',
- 'addr'])
- report['PciNetwork'] = pci_devices(PCI_NETWORK)
- for var in ('http_proxy', 'ftp_proxy', 'no_proxy'):
- if var in os.environ:
- report[var] = os.environ[var]
- continue
-
-
-
- def attach_printing(report):
- '''Attach printing information to the report.
-
- Based on http://wiki.ubuntu.com/PrintingBugInfoScript.
- '''
- attach_file_if_exists(report, '/etc/papersize', 'Papersize')
- attach_file_if_exists(report, '/var/log/cups/error_log', 'CupsErrorLog')
- report['Locale'] = command_output([
- 'locale'])
- report['Lpstat'] = command_output([
- 'lpstat',
- '-v'])
- ppds = glob.glob('/etc/cups/ppd/*.ppd')
- if ppds:
- nicknames = command_output([
- 'fgrep',
- '-H',
- '*NickName'] + ppds)
- report['PpdFiles'] = re.sub('/etc/cups/ppd/(.*).ppd:\\*NickName: *"(.*)"', '\\g<1>: \\g<2>', nicknames)
-
- report['PrintingPackages'] = package_versions('foo2zjs', 'foomatic-db', 'foomatic-db-engine', 'foomatic-db-gutenprint', 'foomatic-db-hpijs', 'foomatic-filters', 'foomatic-gui', 'hpijs', 'hplip', 'm2300w', 'min12xxw', 'c2050', 'hpoj', 'pxljr', 'pnm2ppa', 'splix', 'hp-ppd', 'hpijs-ppds', 'linuxprinting.org-ppds', 'openprinting-ppds', 'openprinting-ppds-extra', 'ghostscript', 'cups', 'cups-driver-gutenprint', 'foomatic-db-gutenprint', 'ijsgutenprint', 'cupsys-driver-gutenprint', 'gimp-gutenprint', 'gutenprint-doc', 'gutenprint-locales', 'system-config-printer-common', 'kdeprint')
-
-
- def attach_related_packages(report, packages):
- '''Attach version information for related packages
-
- In the future, this might also run their hooks.'''
- report['RelatedPackageVersions'] = package_versions(*packages)
-
-
- def package_versions(*packages):
- '''Return a text listing of package names and versions for the specified
- packages. Arguments may be package names or glob patterns, e.g. "foo*"'''
- versions = ''
- for package_pattern in packages:
- for package in package_glob(package_pattern):
-
- try:
- version = packaging.get_version(package)
- except ValueError:
- version = 'N/A'
-
- if version is None:
- version = 'N/A'
-
- versions += '%s %s\n' % (package, version)
-
-
- return versions
-
-
- def package_glob(name):
- '''Return a list of known packages matching name'''
- all_packages = command_output([
- 'apt-cache',
- 'pkgnames']).split('\n')
- return glob.fnmatch.filter(all_packages, name)
-
-
- def _parse_gconf_schema(schema_file):
- ret = { }
- dom = xml.dom.minidom.parse(schema_file)
- for gconfschemafile in dom.getElementsByTagName('gconfschemafile'):
- for schemalist in gconfschemafile.getElementsByTagName('schemalist'):
- for schema in schemalist.getElementsByTagName('schema'):
- key = schema.getElementsByTagName('applyto')[0].childNodes[0].data
- type = schema.getElementsByTagName('type')[0].childNodes[0].data
- default = schema.getElementsByTagName('default')[0].childNodes[0].data
- if type == 'bool':
- if default:
- ret[key] = 'true'
- else:
- ret[key] = 'false'
- default
- ret[key] = default
-
-
-
- return ret
-
-