rpms/hal-cups-utils/devel hal-cups-utils-git.patch, NONE, 1.1 hal-cups-utils.spec, 1.72, 1.73 hal-cups-utils-traceback.patch, 1.1, NONE

Tim Waugh twaugh at fedoraproject.org
Wed Oct 22 14:11:11 UTC 2008


Author: twaugh

Update of /cvs/pkgs/rpms/hal-cups-utils/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv28048

Modified Files:
	hal-cups-utils.spec 
Added Files:
	hal-cups-utils-git.patch 
Removed Files:
	hal-cups-utils-traceback.patch 
Log Message:
* Wed Oct 22 2008 Tim Waugh <twaugh at redhat.com> 0.6.17-3
- Added patch from git to prevent traceback (bug #468010).


hal-cups-utils-git.patch:

--- NEW FILE hal-cups-utils-git.patch ---
diff --git a/ChangeLog b/ChangeLog
index 8bdee6c..e6b0b38 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,44 @@
+2008-10-16  Tim Waugh  <twaugh at redhat.com>
+
+	* systemv/hal_lpadmin (main): Don't log a traceback if sys.exit()
+	is called (bug #466485).
+
+2008-08-03  Tim Waugh  <twaugh at redhat.com>
+
+	* systemv/hal_lpadmin (HalPrinter.read): Remember IEEE 1284 Device
+	ID we read directly from device, or else reconstruct one from the
+	HAL fields we were given.
+	(HalPrinter.store_device_id_in_ppd): New method.  Overwrite
+	1284DeviceID attribute in PPD file with actual ID from device.
+	(HalPrinter.add): Use it, ignoring exceptions (trac #2).
+
+2008-07-28  Till Kamppeter  <till.kamppeter at gmail.com>
+
+	* systemv/hal_lpadmin: If hal_lpadmin is triggered by the
+	low-level interface and therefore the device ID is polled from the
+	printer, write the device ID into the HAL database entry which
+	called hal_lpadmin. This way the ID is also available when the
+	printer is turned off and the queues to be disabled can get found
+	reliably.
+
+2008-07-26  Till Kamppeter  <till.kamppeter at gmail.com>
+
+	* systemv/hal_lpadmin, systemv/10-hal_lpadmin.fdi: Let the
+	automatic print queue setup (Plug'n'Print) and the automatic
+	disabling and re- enabling print queues when turning off and on
+	the printer work also if the usblp kernel module is absent (or
+	blacklisted) or if a libusb- based backend (like the HPLIP "hp"
+	CUPS backend) uncouples the printer from the usblp module. Now a
+	printer can be detected by either the HAL messages of the usblp
+	kernel module or by the HAL messages of the low-level USB
+	interface of the printer. Duplicate action when the kernel module
+	is present is prevented (trac #1).
+
+	This change is once done in preparation for CUPS 1.4, where the
+	USB backend will be libusb-based and second, so that queues of
+	HPLIP-driven HP printers get enabled and disabled correctly
+	depending on whether the printer is turned on or off.
+
 2008-07-07  Tim Waugh  <twaugh at redhat.com>
 
 	* configure.in: Version 0.6.17.
diff --git a/systemv/10-hal_lpadmin.fdi b/systemv/10-hal_lpadmin.fdi
index 8744278..bd265b4 100644
--- a/systemv/10-hal_lpadmin.fdi
+++ b/systemv/10-hal_lpadmin.fdi
@@ -11,5 +11,18 @@
       <append key="org.freedesktop.Hal.Device.Printer.method_execpaths" type="strlist">hal_lpadmin --configure</append>
       <append key="org.freedesktop.Hal.Device.Printer.method_argnames" type="strlist">make model</append>
     </match>
+    <match key="usb.interface.class" int="7">
+      <match key="usb.interface.subclass" int="1">
+	<append key="info.addons" type="strlist">hal_lpadmin --add</append>
+	<append key="info.callouts.remove" type="strlist">hal_lpadmin --remove</append>
+	<append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Printer</append>
+	<append key="org.freedesktop.Hal.Device.Printer.method_names" type="strlist">Configure</append>
+	<append key="org.freedesktop.Hal.Device.Printer.method_signatures" type="strlist">ss</append>
+	<append key="org.freedesktop.Hal.Device.Printer.method_execpaths" type="strlist">hal_lpadmin --configure</append>
+	<append key="org.freedesktop.Hal.Device.Printer.method_argnames" type="strlist">make model</append>
+	<merge key="usb.vendor" type="copy_property">@info.parent:usb_device.vendor</merge>
+	<merge key="usb.product" type="copy_property">@info.parent:usb_device.product</merge>
+      </match>
+    </match>
   </device>
 </deviceinfo>
diff --git a/systemv/hal_lpadmin b/systemv/hal_lpadmin
index 6b4bebe..586ed19 100755
--- a/systemv/hal_lpadmin
+++ b/systemv/hal_lpadmin
@@ -1,5 +1,5 @@
 #!/bin/env python
-import dbus, sys, os, time, signal, re
+import dbus, sys, os, time, signal, re, usb
 import traceback
 import cups, cupshelpers
 from syslog import *
@@ -57,18 +57,161 @@ class HalPrinter:
                 name = key[9:].lower().replace("_", '.')
                 self.properties[name] = value
         self.uid = os.getenv("UDI", "")
+        if re.search ("_if\d+$", self.uid):
+            syslog (LOG_DEBUG, "hal_lpadmin triggered by low-level USB device")
+        else:
+            syslog (LOG_DEBUG, "hal_lpadmin triggered by usblp kernel module")
         self.read()
 
     def read(self):
         p = self.properties
-        self.make = (p.get("printer.vendor", "") or
+        if p.get ("printer.vendor") == None:
+            # Printer 1284 device URI not supplied by HAL, so we poll
+            # it from the printer and add it to the HAL database
+            # entry. This happens usually if the printer is detected
+            # via low-level USB.
+            syslog (LOG_DEBUG, "Polling device ID from the printer")
+            if p.get ("usb.bus.number") == None or \
+               p.get ("usb.linux.device.number") == None:
+                return
+            try:
+                devidstr = ''
+                busses = usb.busses()
+                for bus in busses:
+                    if int (bus.dirname) == int (p.get ("usb.bus.number")):
+                        for dev in bus.devices:
+                            if int (dev.filename) == \
+                               int (p.get ("usb.linux.device.number")):
+                                for config in dev.configurations:
+                                    if p.get ("usb.configuration.value") == \
+                                            None or\
+                                       int (config.value) == \
+                                       int (p.get ("usb.configuration.value")):
+                                        for intf in config.interfaces:
+                                            if p.get ("usb.interface.number") \
+                                                    == None or \
+                                               int (intf[0].interfaceNumber) ==\
+                                               int (p.get \
+                                                    ("usb.interface.number")):
+                                                syslog (LOG_DEBUG, \
+                                                    "Device %s:%s: %s" % \
+                                                    (bus.dirname, \
+                                                     dev.filename, \
+                                                     p.get ("info.udi")))
+                                                handle = dev.open ()
+                                                #handle.setConfiguration (config)
+                                                handle.claimInterface (intf[0])
+                                                handle.setAltInterface (intf[0])
+                                                intfno = intf[0].interfaceNumber
+                                                alt = intf[0].alternateSetting
+                                                devidarr = handle.controlMsg \
+                                                 (requestType = 0xa1, 
+                                                  request = 0, \
+                                                  value = config.value - 1, \
+                                                  index = alt + (intfno << 8), \
+                                                  buffer = 4096, \
+                                                  timeout = 100)
+                                                siz = len(devidarr)
+                                                len0 = devidarr[0]
+                                                len1 = devidarr[1]
+                                                devidlen  = \
+                                                   ((len0 & 255) << 8) + \
+                                                   (len1 & 255)
+                                                devidlen2 = \
+                                                   ((len1 & 255) << 8) + \
+                                                   (len0 & 255)
+                                                if devidlen > siz:
+                                                    if devidlen2 > siz:
+                                                        devidlen = siz
+                                                    else:
+                                                        devidlen = devidlen2
+                                                for i in range (2, devidlen):
+                                                    devidstr = \
+                                                        devidstr + \
+                                                        chr(devidarr[i])
+                                                syslog (LOG_DEBUG, \
+                                                   "Device ID for %s:%s: %s" %\
+                                                   (bus.dirname, \
+                                                    dev.filename, \
+                                                    devidstr))
+                                                break
+                                        break
+                                break
+                        break
+            except:
+                # We cannot read out the device ID from the printer, probably
+                # because the low-level device access is clamed by the usblp
+                # kernel module. So stop this instance of hal_lpadmin so that
+                # the instance triggered by the kernel module does its job for
+                # us.
+                syslog (LOG_DEBUG, 
+                   "Stopping hal_lpadmin triggered by low-level USB device")
+                # The program is not actively stopped here, but by not
+                # filling in self.make we tell the methods of the HalLpAdmin
+                # class not to do their core action
+                self.make = None
+                return
+            self.device_id = devidstr
+            id_dict = cupshelpers.parseDeviceID (devidstr)
+            self.make = (id_dict["MFG"] or p.get("usb.vendor", "Unknown"))
+            p["printer.vendor"] = self.make
+            self.model = (id_dict["MDL"] or p.get("usb.product", "Unknown"))
+            p["printer.product"] = self.model
+            self.description = id_dict["DES"]
+            p["printer.description"] = self.description
+            self.name = self.get_name()
+            self.faxname = self.name + "_fax"
+            self.commandsets = id_dict["CMD"]
+            p["printer.commandset"] = '\t'.join (self.commandsets)
+            self.serial = (id_dict["SN"] or p.get("usb.serial", None))
+            if self.serial != None:
+                p["printer.serial"] = self.serial
+            for key in ("printer.vendor", "printer.product", \
+                        "printer.description", "printer.serial"):
+                if p.get (key) == None:
+                    continue
+                cmd = "hal-set-property --udi='%s' --key='%s' --string='%s' 2>&1" % \
+                    (self.uid, key, p[key])
+                try:
+                    output = os.popen (cmd, 'r').readlines ()
+                except:
+                    pass
+            for cs in self.commandsets:
+                cmd = "hal-set-property --udi=%s --key=\"printer.commandset\" --strlist-post=%s > /dev/null 2>&1" % \
+                    (self.uid, cs)
+                try:
+                    output = os.popen (cmd, 'r').readlines ()
+                except:
+                    pass
+            syslog (LOG_DEBUG, "Written device ID into HAL database entry")
+        else:
+            # Printer device ID is already available in the HAL database.
+            # Either HAL has already put it there (triggered by the usblp
+            # kernel module) or hal_lpadmin has read it from the printer
+            # when it was turned on.
+            syslog (LOG_DEBUG, "Using device ID from HAL database entry")
+            self.make = (p.get("printer.vendor", "") or
                      p.get("usb.vendor", "Unknown"))
-        self.model = (p.get("printer.product", "") or
+            self.model = (p.get("printer.product", "") or
                       p.get("usb.product", "Unknown"))
-        self.description = p.get("printer.description", "")
-        self.name = self.get_name()
-        self.faxname = self.name + "_fax"
-        self.commandsets = p.get('printer.commandset', '').split('\t')
+            self.description = p.get("printer.description", "")
+            self.name = self.get_name()
+            self.faxname = self.name + "_fax"
+            self.commandsets = p.get('printer.commandset', '').split('\t')
+            self.serial = p.get("printer.serial", "")
+
+            # Reconstruct Device ID ready to put it into the PPD file.
+            devidstr = ''
+            for (field, value) in [("MFG:", self.make),
+                                   ("MDL:", self.model),
+                                   ("DES:", self.description),
+                                   ("CMD:", reduce (lambda x, y: x + ',' + y,
+                                                    self.commandsets)),
+                                   ("SN:", self.serial)]:
+                if len (value) > 0:
+                    devidstr += field + value + ";"
+
+            self.device_id = devidstr
 
     def get_name(self):
         # XXX check for unallowed chars
@@ -199,6 +342,35 @@ class HalPrinter:
         else:
             return None
 
+    def store_device_id_in_ppd(self):
+        fname = self.cups_connection.getPPD(self.name)
+        lines = file (fname).readlines ()
+        attr = "*1284DeviceID:"
+        has_1284_attr = reduce (lambda x, y: x or y,
+                                map (lambda x: x.startswith (attr)))
+        outf = file (fname, 'w')
+        written = False
+        attrline = attr + ' ' + self.device_id + '\n'
+        for line in lines:
+            if not written:
+                if has_1284_attr:
+                    if line.startswith (attr):
+                        # Replace existing attribute.
+                        line = attrline
+                        written = True
+                else:
+                    if line == '\n':
+                        # Write attribute before first blank line.
+                        line = attrline + line
+                        written = True
+
+            outf.write (line)
+        if not written:
+            outf.write (attrline)
+        outf.close ()
+        self.cups_connection.addPrinter(self.name, filename=fname)
+        os.unlink (fname)
+
     def add(self):
         syslog (LOG_DEBUG, "add")
         printers = cupshelpers.getPrinters(self.cups_connection)
@@ -314,6 +486,11 @@ class HalPrinter:
                                                 device=self.get_cups_uri(),
                                                 ppdname=ppdname, info=info,
                                                 location=os.uname ()[1])
+                try:
+                    self.store_device_id_in_ppd ()
+                except:
+                    pass
+
                 self.cups_connection.enablePrinter(self.name)
                 self.cups_connection.acceptJobs(self.name)
                 syslog (LOG_INFO, "Added printer %s" % self.name)
@@ -367,9 +544,8 @@ class HalPrinter:
         # which we will disable.
         printers = cupshelpers.getPrinters(self.cups_connection)
         printers_extra_info = None
-        make = self.properties["printer.vendor"]
-        makel = make.lower ()
-        model = self.properties["printer.product"]
+        make = self.properties.get ("printer.vendor", None)
+        model = self.properties.get ("printer.product", None)
         serial = self.properties.get ("printer.serial", None)
         if not serial:
             serial = self.properties.get ("info.udi", None)
@@ -382,27 +558,36 @@ class HalPrinter:
                     serial = resg[0]
         bus = self.properties.get ("linux.subsystem", None)
         udi = self.properties.get ("info.udi", None)
-        if makel == "hewlett-packard":
-            make = "HP"
-        elif makel == "lexmark international":
-            make = "Lexmark"
-        if model.startswith (make):
-            model = model[len (make):]
-            model = model.lstrip ()
+        if make:
+            makel = make.lower ()
+            if makel == "hewlett-packard":
+                make = "HP"
+            elif makel == "lexmark international":
+                make = "Lexmark"
+        if model:
+            if model.startswith (make):
+                model = model[len (make):]
+                model = model.lstrip ()
         for name, printer in printers.iteritems():
             if printer.is_class: continue
-            if (((printer.device_uri.find (model.replace (" ", "%20")) != -1 or
-                  printer.device_uri.find (model.replace (" ", "_")) != -1) and
+            if (((model and 
+                  (printer.device_uri.find (model.replace (" ", "%20")) \
+                       != -1 or
+                   printer.device_uri.find (model.replace (" ", "_")) \
+                       != -1)) and
                  (not serial or printer.device_uri.find ("serial=") == -1 or
                   (serial and
                    printer.device_uri.find ("serial=" + serial) != -1)) and
                  (not bus or
                   printer.device_uri.find (bus) != -1)) or
-                (udi and printer.device_uri.find (udi) != -1)):
+                (udi and printer.device_uri.find (udi) != -1) or
+                (serial and
+                 printer.device_uri.find ("serial=" + serial) != -1)):
                 syslog (LOG_DEBUG,
                          "Found configured printer: %s" % name)
                 if printer.enabled:
-                    if ((not printer.device_uri.startswith ("hp:") and
+                    if (udi and re.search ("_if\d+$", udi)) or \
+                       ((not printer.device_uri.startswith ("hp:") and
                          not printer.device_uri.startswith ("hpfax:")) or
                         (bus == "usb" and
                          printer.device_uri.find ("/usb/") != -1 and
@@ -459,21 +644,27 @@ class HalLpAdmin:
 
     def addPrinter(self):
         printer = HalPrinter()
-        printer.add()
+        if printer.make:
+            printer.add()
         
     def removePrinter(self):
         printer = HalPrinter()
-        printer.remove()
+        if printer.make:
+            printer.remove()
 
     def configurePrinter(self):
         printer = HalPrinter()
-        printer.configure()
+        if printer.make:
+            printer.configure()
 
 def main():
     openlog ("hal_lpadmin", 0, LOG_DAEMON)
+    syslog (LOG_DEBUG, "Running hal_lpadmin")
     time.sleep (1) # Give HPLIP a chance to reconnect
     try:
         h = HalLpAdmin()
+    except SystemExit, e:
+        sys.exit (e)
     except:
         (type, value, tb) = sys.exc_info ()
         tblast = traceback.extract_tb (tb, limit=None)


Index: hal-cups-utils.spec
===================================================================
RCS file: /cvs/pkgs/rpms/hal-cups-utils/devel/hal-cups-utils.spec,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -r1.72 -r1.73
--- hal-cups-utils.spec	16 Oct 2008 13:41:48 -0000	1.72
+++ hal-cups-utils.spec	22 Oct 2008 14:10:41 -0000	1.73
@@ -1,14 +1,14 @@
 Summary: Halified CUPS utilities 
 Name: hal-cups-utils
 Version: 0.6.17
-Release: 2%{?dist}
+Release: 3%{?dist}
 License: GPLv2
 Group: Applications/System
 URL: https://fedorahosted.org/hal-cups-utils
 # Add "?format=raw" to the following URL to download file:
 Source: https://fedorahosted.org/hal-cups-utils/attachment/wiki/ProjectReleases/%{name}-%{version}.tar.gz
 Source1: cups-config-daemon
-Patch1: hal-cups-utils-traceback.patch
+Patch1: hal-cups-utils-git.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: glib2-devel
 BuildRequires: dbus-devel >= 0.60
@@ -30,7 +30,7 @@
 rm -rf $RPM_BUILD_ROOT
 
 %setup -q
-%patch1 -p1 -b .traceback
+%patch1 -p1 -b .git
 
 %build
 
@@ -62,6 +62,9 @@
 %{_initrddir}/cups-config-daemon
 
 %changelog
+* Wed Oct 22 2008 Tim Waugh <twaugh at redhat.com> 0.6.17-3
+- Added patch from git to prevent traceback (bug #468010).
+
 * Thu Oct 16 2008 Tim Waugh <twaugh at redhat.com> 0.6.17-2
 - Don't log a traceback if sys.exit() is called (bug #466485).
 


--- hal-cups-utils-traceback.patch DELETED ---




More information about the scm-commits mailing list