diff --git a/system-config-printer-a05bd9c.patch b/system-config-printer-a05bd9c.patch new file mode 100644 index 0000000..6d7e2ca --- /dev/null +++ b/system-config-printer-a05bd9c.patch @@ -0,0 +1,322 @@ +diff --git a/udev/udev-add-printer b/udev/udev-add-printer +index 03d301e..2e4d933 100755 +--- a/udev/udev-add-printer ++++ b/udev/udev-add-printer +@@ -27,13 +27,11 @@ import sys + import traceback + from syslog import * + +-def create_queue (c, name, device_uri, ppdname, info): ++def create_queue (c, printernames, name, device_uri, ppdname, info): + # Make sure the name is unique. +- printers = cupshelpers.getPrinters (c) +- names = printers.keys () +- if name in names: ++ if name in printernames: + suffix = 2 +- while (name + "-" + str (suffix)) in names: ++ while (name + "-" + str (suffix)) in printernames: + suffix += 1 + if suffix == 100: + break +@@ -83,7 +81,10 @@ def add_queue (device_id, device_uris, is_fax=False): + name = name.replace ("/", "-") + name = name.replace ("#", "-") + +- create_queue (c, name, device_uris[0], ppdname, ++ printers = cupshelpers.getPrinters (c) ++ printernames = printers.keys () ++ ++ create_queue (c, printernames, name, device_uris[0], ppdname, + "%s %s" % (id_dict["MFG"], id_dict["MDL"])) + + if not is_fax: +@@ -93,24 +94,8 @@ def add_queue (device_id, device_uris, is_fax=False): + # find one whose scheme ends in "fax", use that as a fax + # queue. Note that the HPLIP backends do follow this + # pattern (hp and hpfax). +- not_fax_schemes=["beh", +- "bluetooth", +- "http", +- "https", +- "ipp", +- "lpd", +- "parallel", +- "serial", +- "smb", +- "snmp", +- "socket", +- "scsi", +- "usb"] +- devices = c.getDevices (exclude_schemes=not_fax_schemes) +- for uri, device_dict in devices.iteritems (): +- if uri in device_uris: +- continue +- ++ used_uris = map (lambda x: x.device_uri, printers.values ()) ++ for uri in device_uris[1:]: + if uri.find (":") == -1: + continue + +@@ -119,8 +104,20 @@ def add_queue (device_id, device_uris, is_fax=False): + # Now see if the non-scheme parts of the URI match + # any of the URIs we were given. + for each_uri in device_uris: ++ if each_uri == uri: ++ continue + (s, device_uri_rest) = each_uri.split (":", 1) + if rest == device_uri_rest: ++ # This one matches. Check there is not ++ # already a queue using this URI. ++ if uri in used_uris: ++ break ++ ++ devices = c.getDevices (include_schemes=[scheme]) ++ device_dict = devices.get (uri) ++ if device_dict == None: ++ break ++ + add_queue (device_dict.get ("device-id", ""), + [uri], is_fax=True) + else: +diff --git a/udev/udev-configure-printer.c b/udev/udev-configure-printer.c +index a3c87dc..37a8682 100644 +--- a/udev/udev-configure-printer.c ++++ b/udev/udev-configure-printer.c +@@ -708,7 +708,7 @@ cupsDoRequestOrDie (http_t *http, + + static int + find_matching_device_uris (struct device_id *id, +- const char *serial, ++ const char *usbserial, + struct device_uris *uris, + const char *devpath) + { +@@ -716,21 +716,34 @@ find_matching_device_uris (struct device_id *id, + ipp_t *request, *answer; + ipp_attribute_t *attr; + struct device_uris uris_noserial; ++ struct device_uris all_uris; ++ size_t i, n; ++ const char *exclude_schemes[] = { ++ "beh", ++ "bluetooth", ++ "http", ++ "https", ++ "ipp", ++ "lpd", ++ "ncp", ++ "parallel", ++ "scsi", ++ "smb", ++ "snmp", ++ "socket", ++ }; + +- uris->n_uris = 0; +- uris->uri = NULL; +- +- uris_noserial.n_uris = 0; +- uris_noserial.uri = NULL; ++ uris->n_uris = uris_noserial.n_uris = all_uris.n_uris = 0; ++ uris->uri = uris_noserial.uri = all_uris.uri = NULL; + + /* Leave the bus to settle. */ + sleep (1); + + cups = cups_connection (); + request = ippNewRequest (CUPS_GET_DEVICES); +- ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "include-schemes", +- sizeof (device_uri_types) / sizeof(device_uri_types[0]), +- NULL, device_uri_types); ++ ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "exclude-schemes", ++ sizeof (exclude_schemes) / sizeof(exclude_schemes[0]), ++ NULL, exclude_schemes); + + answer = cupsDoRequestOrDie (cups, request, "/"); + httpClose (cups); +@@ -757,6 +770,28 @@ find_matching_device_uris (struct device_id *id, + parse_device_id (attr->values[0].string.text, &this_id); + } + ++ /* Only use device schemes in our preference order for matching ++ * against the IEEE 1284 Device ID. */ ++ ++ for (i = 0; ++ device_uri && ++ i < sizeof (device_uri_types) / sizeof (device_uri_types[0]); ++ i++) ++ { ++ size_t len = strlen (device_uri_types[i]); ++ if (!strncmp (device_uri_types[i], device_uri, len) && ++ device_uri[len] == ':') ++ break; ++ } ++ ++ if (device_uri) ++ add_device_uri (&all_uris, device_uri); ++ ++ if (i == sizeof (device_uri_types) / sizeof (device_uri_types[0])) ++ /* Not what we want to match against. Ignore this one. */ ++ device_uri = NULL; ++ ++ /* Now check the manufacturer and model names. */ + if (device_uri && this_id.mfg && this_id.mdl && + !strcmp (this_id.mfg, id->mfg) && + !strcmp (this_id.mdl, id->mdl)) +@@ -803,11 +838,11 @@ find_matching_device_uris (struct device_id *id, + match = 1; + } + +- if (!match && strlen (serial) >= 12) ++ if (!match && usbserial[0] != '\0') + { + if (!id->sern) + { +- if (this_id.sern && !strcmp (serial, this_id.sern)) ++ if (this_id.sern && !strcmp (usbserial, this_id.sern)) + { + syslog (LOG_DEBUG, + "SERN field matches USB serial number"); +@@ -819,10 +854,11 @@ find_matching_device_uris (struct device_id *id, + { + char *saveptr, *uri = strdup (device_uri); + const char *token; +- for (token = strtok_r (uri, "?=&", &saveptr); ++ const char *sep = "?=&/"; ++ for (token = strtok_r (uri, sep, &saveptr); + token; +- token = strtok_r (NULL, "?=&", &saveptr)) +- if (!strcmp (token, serial)) ++ token = strtok_r (NULL, sep, &saveptr)) ++ if (!strcmp (token, usbserial)) + { + syslog (LOG_DEBUG, "URI contains USB serial number"); + match = 1; +@@ -886,14 +922,56 @@ find_matching_device_uris (struct device_id *id, + uris->uri = old; + else + { +- size_t i; + for (i = 0; i < uris_noserial.n_uris; i++) + uris->uri[uris->n_uris + i] = uris_noserial.uri[i]; + uris->n_uris += uris_noserial.n_uris; + } ++ ++ uris_noserial.n_uris = 0; ++ uris_noserial.uri = NULL; + } + + free_device_uris (&uris_noserial); ++ ++ /* Having decided which device URIs match based on IEEE 1284 Device ++ * ID, we now need to look for "paired" URIs for other functions of ++ * a multi-function device. This are the same except for the ++ * scheme. */ ++ ++ n = uris->n_uris; ++ for (i = 0; i < n; i++) ++ { ++ size_t j; ++ char *me = uris->uri[i]; ++ char *my_rest = strchr (me, ':'); ++ size_t my_schemelen; ++ if (!my_rest) ++ continue; ++ ++ my_schemelen = my_rest - me; ++ for (j = 0; j < all_uris.n_uris; j++) ++ { ++ char *twin = all_uris.uri[j]; ++ char *twin_rest = strchr (twin, ':'); ++ size_t twin_schemelen; ++ if (!twin_rest) ++ continue; ++ ++ twin_schemelen = twin_rest - twin; ++ if (my_schemelen == twin_schemelen && ++ !strncmp (me, twin, my_schemelen)) ++ /* This is the one we are looking for the twin of. */ ++ continue; ++ ++ if (!strcmp (my_rest, twin_rest)) ++ { ++ syslog (LOG_DEBUG, "%s twinned with %s", me, twin); ++ add_device_uri (uris, twin); ++ } ++ } ++ } ++ ++ free_device_uris (&all_uris); + if (uris->n_uris > 0) + { + struct usb_uri_map *map = read_usb_uri_map (); +@@ -1048,12 +1126,12 @@ do_add (const char *cmd, const char *devpath) + struct device_id id; + struct device_uris device_uris; + char *usb_device_devpath; +- char serial[256]; ++ char usbserial[256]; + + syslog (LOG_DEBUG, "add %s", devpath); + + usb_device_devpath = device_id_from_devpath (devpath, &id, +- serial, sizeof (serial)); ++ usbserial, sizeof (usbserial)); + if (!id.mfg || !id.mdl) + { + syslog (LOG_ERR, "invalid or missing IEEE 1284 Device ID%s%s", +@@ -1063,28 +1141,31 @@ do_add (const char *cmd, const char *devpath) + } + + syslog (LOG_DEBUG, "MFG:%s MDL:%s SERN:%s serial:%s", id.mfg, id.mdl, +- id.sern ? id.sern : "-", serial); +- +- if ((pid = fork ()) == -1) +- syslog (LOG_ERR, "Failed to fork process"); +- else if (pid != 0) +- /* Parent. */ +- exit (0); +- +- close (STDIN_FILENO); +- close (STDOUT_FILENO); +- close (STDERR_FILENO); +- f = open ("/dev/null", O_RDWR); +- if (f != STDIN_FILENO) +- dup2 (f, STDIN_FILENO); +- if (f != STDOUT_FILENO) +- dup2 (f, STDOUT_FILENO); +- if (f != STDERR_FILENO) +- dup2 (f, STDERR_FILENO); +- +- setsid (); +- +- find_matching_device_uris (&id, serial, &device_uris, usb_device_devpath); ++ id.sern ? id.sern : "-", usbserial); ++ ++ if (getenv ("DEBUG") == NULL) ++ { ++ if ((pid = fork ()) == -1) ++ syslog (LOG_ERR, "Failed to fork process"); ++ else if (pid != 0) ++ /* Parent. */ ++ exit (0); ++ ++ close (STDIN_FILENO); ++ close (STDOUT_FILENO); ++ close (STDERR_FILENO); ++ f = open ("/dev/null", O_RDWR); ++ if (f != STDIN_FILENO) ++ dup2 (f, STDIN_FILENO); ++ if (f != STDOUT_FILENO) ++ dup2 (f, STDOUT_FILENO); ++ if (f != STDERR_FILENO) ++ dup2 (f, STDERR_FILENO); ++ ++ setsid (); ++ } ++ ++ find_matching_device_uris (&id, usbserial, &device_uris, usb_device_devpath); + free (usb_device_devpath); + if (device_uris.n_uris == 0) + { diff --git a/system-config-printer.spec b/system-config-printer.spec index 4ac1d6f..9d3f183 100644 --- a/system-config-printer.spec +++ b/system-config-printer.spec @@ -7,13 +7,14 @@ Summary: A printer administration tool Name: system-config-printer Version: 1.1.10 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv2+ URL: http://cyberelk.net/tim/software/system-config-printer/ Group: System Environment/Base Source0: http://cyberelk.net/tim/data/system-config-printer/1.1/system-config-printer-%{version}.tar.bz2 Source1: http://cyberelk.net/tim/data/pycups/pycups-%{pycups_version}.tar.bz2 Source2: http://cyberelk.net/tim/data/pysmbc/pysmbc-%{pysmbc_version}.tar.bz2 +Patch1: system-config-printer-a05bd9c.patch BuildRequires: cups-devel >= 1.2 BuildRequires: python-devel >= 2.4 @@ -76,6 +77,7 @@ printers. %prep %setup -q -a 1 -a 2 +%patch1 -p1 -b .a05bd9c %build %configure --with-udev-rules @@ -183,6 +185,9 @@ rm -rf %buildroot exit 0 %changelog +* Thu Jul 23 2009 Tim Waugh 1.1.10-2 +- Applied some udev-configure-printer fixes from upstrema. + * Wed Jul 22 2009 Tim Waugh 1.1.10-1 - 1.1.10: - New udev rules for adding/enabling/disabling USB printers