]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Add device-location attribute.
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Tue, 29 Jul 2008 01:11:15 +0000 (01:11 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Tue, 29 Jul 2008 01:11:15 +0000 (01:11 +0000)
Add cupsBackendReport() API.

Update cupsGetDevices() to pass device-location.

Update cups-deviced to support quoted strings and device-location.

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@7810 7a7537e8-13f0-0310-91df-b6672ffda945

17 files changed:
CHANGES.txt
backend/backend-private.h
backend/mdns.c
backend/parallel.c
backend/snmp.c
backend/usb-darwin.c
backend/usb-libusb.c
backend/usb-unix.c
cups/backend.c
cups/backend.h
cups/cups.h
cups/getdevices.c
cups/libcups.exp
doc/help/spec-ipp.html
man/backend.man
scheduler/cups-deviced.c
systemv/lpinfo.c

index 861fdcad50fcabb7ec67cb4d6b32bc7916700740..8a1984e9a28571d72650560f999f08b7ff7155e0 100644 (file)
@@ -1,8 +1,12 @@
-CHANGES.txt - 2008-07-25
+CHANGES.txt - 2008-07-28
 ------------------------
 
 CHANGES IN CUPS V1.4b1
 
+       - Added support for a device-location attribute which provides
+         the physical location of a printer device.
+       - Added a cupsBackendReport() API which handles quoting of the
+         device data by a backend.
        - Added support for custom options in the web interface
          (STR #1729)
        - Added support for Mozilla LDAP, reconnection to LDAP servers,
index 8d474ec0b178259b742e9c5ddcafb0510f77c561..cd21be3b24211a732b5a72432fa2c2c64fd99919 100644 (file)
@@ -51,6 +51,9 @@ extern "C" {
 /* Host MIB */
 #define CUPS_OID_mib2                          1,3,6,1,2,1
 
+#define CUPS_OID_system                                CUPS_OID_mib2,1
+#define CUPS_OID_sysLocation                   CUPS_OID_system,6
+
 #define CUPS_OID_host                          CUPS_OID_mib2,25
 
 #define CUPS_OID_hrSystem                      CUPS_OID_host,1
index 4ae2c8121d6cf6e1c5fb21b23f8577a0f2bc5f16..419b12dc3c72572b5e578b648287266e5123a430 100644 (file)
@@ -280,11 +280,8 @@ main(int  argc,                            /* I - Number of command-line args */
                            schemes[best->type], NULL, best->fullName, 0,
                            best->cups_shared ? "/cups" : "/");
 
-           printf("network %s \"%s\" \"%s\"\n", device_uri,
-                  best->make_and_model ? best->make_and_model : "Unknown",
-                  best->name);
-           fflush(stdout);
-
+           cupsBackendReport("network", device_uri, best->make_and_model,
+                             best->name, NULL, NULL);
            best->sent = 1;
            best       = device;
          }
@@ -305,11 +302,8 @@ main(int  argc,                            /* I - Number of command-line args */
                        schemes[best->type], NULL, best->fullName, 0,
                        best->cups_shared ? "/cups" : "/");
 
-       printf("network %s \"%s\" \"%s\"\n", device_uri,
-              best->make_and_model ? best->make_and_model : "Unknown",
-              best->name);
-       fflush(stdout);
-
+       cupsBackendReport("network", device_uri, best->make_and_model,
+                         best->name, NULL, NULL);
        best->sent = 1;
       }
     }
index 48ce24d691782d71e963862016013da28705d4b1..5a9e5e0663b0889346c049f5611f9603786eee0f 100644 (file)
@@ -328,6 +328,7 @@ list_devices(void)
        basedevice[255],        /* Base device filename for ports */
        device_id[1024],        /* Device ID string */
        make_model[1024],       /* Make and model */
+       info[1024],             /* Info string */
        uri[1024];              /* Device URI */
 
 
@@ -359,10 +360,15 @@ list_devices(void)
       if (!backendGetDeviceID(fd, device_id, sizeof(device_id),
                               make_model, sizeof(make_model),
                              NULL, uri, sizeof(uri)))
-       printf("direct %s \"%s\" \"%s LPT #%d\" \"%s\"\n", uri,
-              make_model, make_model, i + 1, device_id);
+      {
+        snprintf(info, sizeof(info), "%s LPT #%d", make_model, i + 1);
+       cupsBackendReport("direct", uri, make_model, info, device_id, NULL);
+      }
       else
-       printf("direct %s \"Unknown\" \"LPT #%d\"\n", uri, i + 1);
+      {
+        snprintf(info, sizeof(info), "LPT #%d", i + 1);
+       cupsBackendReport("direct", uri, NULL, info, NULL, NULL);
+      }
 
       close(fd);
     }
index 4c517ea73df24b404db5a8c7190e0fb6480a7a0e..0eeb44426c74028cf7e4a5aaf2e4bdcdce8b060f 100644 (file)
  * Types...
  */
 
+enum                                   /**** Request IDs for each field ****/
+{
+  DEVICE_TYPE = 1,
+  DEVICE_DESCRIPTION,
+  DEVICE_LOCATION,
+  DEVICE_ID,
+  DEVICE_URI,
+  DEVICE_PRODUCT
+};
+
 typedef struct device_uri_s            /**** DeviceURI values ****/
 {
   regex_t      re;                     /* Regular expression to match */
@@ -124,7 +134,9 @@ typedef struct snmp_cache_s         /**** SNMP scan cache ****/
                *uri,                   /* device-uri */
                *id,                    /* device-id */
                *info,                  /* device-info */
+               *location,              /* device-location */
                *make_and_model;        /* device-make-and-model */
+  int          sent;                   /* Has this device been listed? */
 } snmp_cache_t;
 
 
@@ -174,14 +186,15 @@ static cups_array_t       *Addresses = NULL;
 static cups_array_t    *Communities = NULL;
 static cups_array_t    *Devices = NULL;
 static int             DebugLevel = 0;
-static const int       DeviceDescOID[] = { CUPS_OID_hrDeviceDescr, 1, -1 };
-static unsigned                DeviceDescRequest;
+static const int       DescriptionOID[] = { CUPS_OID_hrDeviceDescr, 1, -1 };
+static const int       LocationOID[] = { CUPS_OID_sysLocation, 0, -1 };
 static const int       DeviceTypeOID[] = { CUPS_OID_hrDeviceType, 1, -1 };
-static unsigned                DeviceTypeRequest;
 static const int       DeviceIdOID[] = { CUPS_OID_ppmPrinterIEEE1284DeviceId, 1, -1 };
-static unsigned                DeviceIdRequest;
-static const int       DeviceUriOID[] = { CUPS_OID_ppmPortServiceNameOrURI, 1, 1, -1 };
-static unsigned                DeviceUriRequest;
+static const int       UriOID[] = { CUPS_OID_ppmPortServiceNameOrURI, 1, 1, -1 };
+static const int       LexmarkProductOID[] = { 1,3,6,1,4,1,641,2,1,2,1,2,1,-1 };
+static const int       LexmarkProductOID2[] = { 1,3,6,1,4,1,674,10898,100,2,1,2,1,2,1,-1 };
+static const int       LexmarkDeviceIdOID[] = { 1,3,6,1,4,1,641,2,1,2,1,3,1,-1 };
+static const int       XeroxProductOID[] = { 1,3,6,1,4,1,128,2,1,3,1,2,0,-1 };
 static cups_array_t    *DeviceURIs = NULL;
 static int             HostNameLookups = 0;
 static int             MaxRunTime = 120;
@@ -660,15 +673,8 @@ static void
 list_device(snmp_cache_t *cache)       /* I - Cached device */
 {
   if (cache->uri)
-  {
-    printf("network %s \"%s\" \"%s %s\" \"%s\"\n",
-           cache->uri,
-          cache->make_and_model ? cache->make_and_model : "Unknown",
-          cache->info ? cache->info : "Unknown",
-          cache->addrname,
-          cache->id ? cache->id : "");
-    fflush(stdout);
-  }
+    cupsBackendReport("network", cache->uri, cache->make_and_model,
+                      cache->info, cache->id, cache->location);
 }
 
 
@@ -953,156 +959,172 @@ read_snmp_response(int fd)              /* I - SNMP socket file descriptor */
   * Process the message...
   */
 
-  if (packet.request_id == DeviceTypeRequest)
+  switch (packet.request_id)
   {
-   /*
-    * Got the device type response...
-    */
-
-    if (device)
-    {
-      debug_printf("DEBUG: Discarding duplicate device type for \"%s\"...\n",
-                  addrname);
-      return;
-    }
-
-   /*
-    * Add the device and request the device description...
-    */
-
-    add_cache(&(packet.address), addrname, NULL, NULL, NULL);
+    case DEVICE_TYPE :
+       /*
+       * Got the device type response...
+       */
+
+       if (device)
+       {
+         debug_printf("DEBUG: Discarding duplicate device type for \"%s\"...\n",
+                      addrname);
+         return;
+       }
+
+       /*
+       * Add the device and request the device data...
+       */
+
+       add_cache(&(packet.address), addrname, NULL, NULL, NULL);
+
+       _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+                      packet.community, CUPS_ASN1_GET_REQUEST,
+                      DEVICE_DESCRIPTION, DescriptionOID);
+       _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+                      packet.community, CUPS_ASN1_GET_REQUEST,
+                      DEVICE_ID, DeviceIdOID);
+       _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+                      packet.community, CUPS_ASN1_GET_REQUEST,
+                      DEVICE_URI, UriOID);
+       _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+                      packet.community, CUPS_ASN1_GET_REQUEST,
+                      DEVICE_LOCATION, LocationOID);
+       _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+                      packet.community, CUPS_ASN1_GET_REQUEST,
+                      DEVICE_PRODUCT, LexmarkProductOID);
+       _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+                      packet.community, CUPS_ASN1_GET_REQUEST,
+                      DEVICE_PRODUCT, LexmarkProductOID2);
+       _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+                      packet.community, CUPS_ASN1_GET_REQUEST,
+                      DEVICE_URI, LexmarkDeviceIdOID);
+       _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+                      packet.community, CUPS_ASN1_GET_REQUEST,
+                      DEVICE_PRODUCT, XeroxProductOID);
+        break;
+
+    case DEVICE_DESCRIPTION :
+       if (device && packet.object_type == CUPS_ASN1_OCTET_STRING)
+       {
+        /*
+         * Update an existing cache entry...
+         */
+
+         char  make_model[256];        /* Make and model */
+
+
+         if (strchr(packet.object_value.string, ':') &&
+             strchr(packet.object_value.string, ';'))
+         {
+          /*
+           * Description is the IEEE-1284 device ID...
+           */
 
-    _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, packet.community,
-                  CUPS_ASN1_GET_REQUEST, DeviceDescRequest, DeviceDescOID);
-    _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, packet.community,
-                  CUPS_ASN1_GET_REQUEST, DeviceIdRequest, DeviceIdOID);
-    _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, packet.community,
-                  CUPS_ASN1_GET_REQUEST, DeviceUriRequest, DeviceUriOID);
-  }
-  else if (packet.request_id == DeviceDescRequest &&
-           packet.object_type == CUPS_ASN1_OCTET_STRING)
-  {
-   /*
-    * Update an existing cache entry...
-    */
+           if (!device->id)
+             device->id = strdup(packet.object_value.string);
 
-    char       make_model[256];        /* Make and model */
+           backendGetMakeModel(packet.object_value.string, make_model,
+                               sizeof(make_model));
 
+            if (device->info)
+             free(device->info);
 
-    if (!device)
-    {
-      debug_printf("DEBUG: Discarding device description for \"%s\"...\n",
-                  addrname);
-      return;
-    }
-
-    if (strchr(packet.object_value.string, ':') &&
-       strchr(packet.object_value.string, ';'))
-    {
-     /*
-      * Description is the IEEE-1284 device ID...
-      */
-
-      if (!device->id)
-       device->id = strdup(packet.object_value.string);
-
-      backendGetMakeModel(packet.object_value.string, make_model,
-                         sizeof(make_model));
-      device->info = strdup(make_model);
-    }
-    else
-    {
-     /*
-      * Description is plain text...
-      */
+           device->info = strdup(make_model);
+         }
+         else
+         {
+          /*
+           * Description is plain text...
+           */
 
-      fix_make_model(make_model, packet.object_value.string,
-                    sizeof(make_model));
+           fix_make_model(make_model, packet.object_value.string,
+                          sizeof(make_model));
 
-      device->info = strdup(packet.object_value.string);
-    }
+            if (device->info)
+             free(device->info);
 
-    if (!device->make_and_model)
-      device->make_and_model = strdup(make_model);
+           device->info = strdup(packet.object_value.string);
+         }
 
-   /*
-    * List the device now if we have all the info...
-    */
+         if (!device->make_and_model)
+           device->make_and_model = strdup(make_model);
+        }
+       break;
 
-    if (device->id && device->info && device->make_and_model && device->uri)
-      list_device(device);
-  }
-  else if (packet.request_id == DeviceIdRequest &&
-           packet.object_type == CUPS_ASN1_OCTET_STRING)
-  {
-   /*
-    * Update an existing cache entry...
-    */
+    case DEVICE_ID :
+       if (device && packet.object_type == CUPS_ASN1_OCTET_STRING)
+       {
+        /*
+         * Update an existing cache entry...
+         */
 
-    char       make_model[256];        /* Make and model */
+         char  make_model[256];        /* Make and model */
 
 
-    if (!device)
-    {
-      debug_printf("DEBUG: Discarding device ID for \"%s\"...\n",
-                  addrname);
-      return;
-    }
+         if (device->id)
+           free(device->id);
 
-    if (device->id)
-      free(device->id);
+         device->id = strdup(packet.object_value.string);
 
-    device->id = strdup(packet.object_value.string);
+        /*
+         * Convert the ID to a make and model string...
+         */
 
-   /*
-    * Convert the ID to a make and model string...
-    */
+         backendGetMakeModel(packet.object_value.string, make_model,
+                             sizeof(make_model));
+         if (device->make_and_model)
+           free(device->make_and_model);
 
-    backendGetMakeModel(packet.object_value.string, make_model,
-                       sizeof(make_model));
-    if (device->make_and_model)
-      free(device->make_and_model);
+         device->make_and_model = strdup(make_model);
+       }
+       break;
 
-    device->make_and_model = strdup(make_model);
+    case DEVICE_LOCATION :
+       if (device && packet.object_type == CUPS_ASN1_OCTET_STRING &&
+           !device->location)
+         device->location = strdup(packet.object_value.string);
+       break;
 
-   /*
-    * List the device now if we have all the info...
-    */
+    case DEVICE_PRODUCT :
+       if (device && packet.object_type == CUPS_ASN1_OCTET_STRING &&
+           !device->id)
+       {
+        /*
+         * Update an existing cache entry...
+         */
 
-    if (device->id && device->info && device->make_and_model && device->uri)
-      list_device(device);
-  }
-  else if (packet.request_id == DeviceUriRequest &&
-           packet.object_type == CUPS_ASN1_OCTET_STRING)
-  {
-   /*
-    * Update an existing cache entry...
-    */
+          if (!device->info)
+           device->info = strdup(packet.object_value.string);
 
-    if (!device)
-    {
-      debug_printf("DEBUG: Discarding device URI for \"%s\"...\n",
-                  addrname);
-      return;
-    }
+          if (device->make_and_model)
+           free(device->make_and_model);
 
-    if (!strncmp(packet.object_value.string, "lpr:", 4))
-    {
-     /*
-      * We want "lpd://..." for the URI...
-      */
+         device->make_and_model = strdup(packet.object_value.string);
+       }
+       break;
 
-      packet.object_value.string[2] = 'd';
-    }
+    case DEVICE_URI :
+       if (device && packet.object_type == CUPS_ASN1_OCTET_STRING &&
+           !device->uri)
+       {
+        /*
+         * Update an existing cache entry...
+         */
 
-    device->uri = strdup(packet.object_value.string);
+         if (!strncmp(packet.object_value.string, "lpr:", 4))
+         {
+          /*
+           * We want "lpd://..." for the URI...
+           */
 
-   /*
-    * List the device now if we have all the info...
-    */
+           packet.object_value.string[2] = 'd';
+         }
 
-    if (device->id && device->info && device->make_and_model && device->uri)
-      list_device(device);
+         device->uri = strdup(packet.object_value.string);
+       }
+       break;
   }
 }
 
@@ -1141,15 +1163,8 @@ scan_devices(int fd)                     /* I - SNMP socket */
   snmp_cache_t         *device;        /* Current device */
 
 
- /*
-  * Setup the request IDs...
-  */
-
   gettimeofday(&StartTime, NULL);
 
-  DeviceTypeRequest = StartTime.tv_sec;
-  DeviceDescRequest = StartTime.tv_sec + 1;
-
  /*
   * First send all of the broadcast queries...
   */
@@ -1189,7 +1204,7 @@ scan_devices(int fd)                      /* I - SNMP socket */
 
       for (addr = addrs; addr; addr = addr->next)
         _cupsSNMPWrite(fd, &(addr->addr), CUPS_SNMP_VERSION_1, community,
-                     CUPS_ASN1_GET_REQUEST, DeviceTypeRequest, DeviceTypeOID);
+                      CUPS_ASN1_GET_REQUEST, DEVICE_TYPE, DeviceTypeOID);
     }
 
     httpAddrFreeList(addrs);
@@ -1219,21 +1234,30 @@ scan_devices(int fd)                    /* I - SNMP socket */
     if (FD_ISSET(fd, &input))
       read_snmp_response(fd);
     else
-      break;
-  }
+    {
+     /*
+      * List devices with complete information...
+      */
 
- /*
-  * Finally, probe all of the printers we discovered to see how they are
-  * connected...
-  */
+      int sent_something = 0;
 
-  for (device = (snmp_cache_t *)cupsArrayFirst(Devices);
-       device;
-       device = (snmp_cache_t *)cupsArrayNext(Devices))
-    if (MaxRunTime > 0 && run_time() >= MaxRunTime)
-      break;
-    else if (!device->uri)
-      probe_device(device);
+      for (device = (snmp_cache_t *)cupsArrayFirst(Devices);
+           device;
+          device = (snmp_cache_t *)cupsArrayNext(Devices))
+        if (!device->sent && device->info && device->make_and_model)
+       {
+         if (device->uri)
+           list_device(device);
+         else
+           probe_device(device);
+
+         device->sent = sent_something = 1;
+       }
+
+      if (!sent_something)
+        break;
+    }
+  }
 
   debug_printf("DEBUG: %.3f Scan complete!\n", run_time());
 }
index bd5b59ccf57867cfbcc73258d6c2f88034a5548e..ede9ead1d9df79a822214b1570e010478f6626fa 100644 (file)
@@ -1056,8 +1056,8 @@ static Boolean list_device_cb(void *refcon,
       httpAssembleURI(HTTP_URI_CODING_ALL, uristr, sizeof(uristr), "usb", NULL, makestr, 0, modelstr);
       strncat(uristr, optionsstr, sizeof(uristr));
 
-      printf("direct %s \"%s\" \"%s USB\" \"%s\"\n", uristr, make_modelstr,
-             make_modelstr, idstr);
+      cupsBackendReport("direct", uristr, make_modelstr, make_modelstr, idstr,
+                        NULL);
 
       release_deviceinfo(&make, &model, &serial);
       CFRelease(deviceIDString);
index 4a7716ec30d02de5f049a5914ee136edba43e9d0..cad8d87ca6be0c232b0d9245f4383a802c01706b 100644 (file)
@@ -447,9 +447,8 @@ list_cb(usb_printer_t *printer,             /* I - Printer */
   * Report the printer...
   */
 
-  printf("direct %s \"%s\" \"%s USB\" \"%s\"\n", device_uri, make_model,
-         make_model, device_id);
-  fflush(stdout);
+  cupsBackendReport("direct", device_uri, make_model, make_model, device_id,
+                    NULL);
 
  /*
   * Keep going...
index 17dd6c45f5674050f0691bed8ad25f9f82be15c4..4abbf5d646391ec1491215f98682f23d6ae407d7 100644 (file)
@@ -210,6 +210,7 @@ list_devices(void)
        device_uri[1024],               /* Device URI string */
        make_model[1024];               /* Make and model */
 
+
  /*
   * Try to open each USB device...
   */
@@ -245,8 +246,8 @@ list_devices(void)
     if (!backendGetDeviceID(fd, device_id, sizeof(device_id),
                             make_model, sizeof(make_model),
                            "usb", device_uri, sizeof(device_uri)))
-      printf("direct %s \"%s\" \"%s USB #%d\" \"%s\"\n", device_uri,
-            make_model, make_model, i + 1, device_id);
+      cupsBackendReport("direct", device_uri, make_model, make_model,
+                        device_id, NULL);
 
     close(fd);
   }
@@ -273,8 +274,8 @@ list_devices(void)
       if (!backendGetDeviceID(fd, device_id, sizeof(device_id),
                               make_model, sizeof(make_model),
                              "usb", device_uri, sizeof(device_uri)))
-       printf("direct %s \"%s\" \"%s USB #%d\" \"%s\"\n", device_uri,
-              make_model, make_model, i + 1, device_id);
+       cupsBackendReport("direct", device_uri, make_model, make_model,
+                         device_id, NULL);
 
       close(fd);
     }
index 3236564d2f4832195288641caf5323fbb031bfeb..87879a95cbf7b238602a9db9c52789d19a0200bd 100644 (file)
@@ -17,6 +17,8 @@
  * Contents:
  *
  *   cupsBackendDeviceURI() - Get the device URI for a backend.
+ *   cupsBackendReport()    - Write a device line from a backend.
+ *   quote_string()         - Write a quoted string to stdout, escaping \ and ".
  */
 
 /*
 #include "globals.h"
 
 
+/*
+ * Local functions...
+ */
+
+static void    quote_string(const char *s);
+
+
 /*
  * 'cupsBackendDeviceURI()' - Get the device URI for a backend.
  *
@@ -57,6 +66,65 @@ cupsBackendDeviceURI(char **argv)    /* I - Command-line arguments */
 }
 
 
+/*
+ * 'cupsBackendReport()' - Write a device line from a backend.
+ *
+ * This function writes a single device line to stdout for a backend.
+ * It handles quoting of special characters in the device-make-and-model,
+ * device-info, device-id, and device-location strings.
+ */
+
+void
+cupsBackendReport(
+    const char *device_scheme,         /* I - device-scheme string */
+    const char *device_uri,            /* I - device-uri string */
+    const char *device_make_and_model, /* I - device-make-and-model string or @code NULL@ */
+    const char *device_info,           /* I - device-info string or @code NULL@ */
+    const char *device_id,             /* I - device-id string or @code NULL@ */
+    const char *device_location)       /* I - device-location string or @code NULL@ */
+{
+  if (!device_scheme || !device_uri)
+    return;
+
+  printf("%s %s", device_scheme, device_uri);
+  if (device_make_and_model && *device_make_and_model)
+    quote_string(device_make_and_model);
+  else
+    quote_string("unknown");
+  quote_string(device_info);
+  quote_string(device_id);
+  quote_string(device_location);
+  putchar('\n');
+  fflush(stdout);
+}
+
+
+/*
+ * 'quote_string()' - Write a quoted string to stdout, escaping \ and ".
+ */
+
+static void
+quote_string(const char *s)            /* I - String to write */
+{
+  fputs(" \"", stdout);
+
+  if (s)
+  {
+    while (*s)
+    {
+      if (*s == '\\' || *s == '\"')
+       putchar('\\');
+
+      putchar(*s);
+
+      s ++;
+    }
+  }
+
+  putchar('\"');
+}
+
+
 /*
  * End of "$Id$".
  */
index 8e8f7f0291cc0010e0629fb5b4b4b0773f5841f7..90e6a2670c80514c051f9e207a46598c6dd5b936 100644 (file)
@@ -48,7 +48,14 @@ typedef enum cups_backend_e cups_backend_t;
  */
 
 extern const char      *cupsBackendDeviceURI(char **argv) _CUPS_API_1_2;
-
+extern void            cupsBackendReport(const char *device_scheme,
+                                         const char *device_uri,
+                                         const char *device_make_and_model,
+                                         const char *device_info,
+                                         const char *device_id,
+                                         const char *device_location)
+                                         _CUPS_API_1_4;
+                                         
 
 #endif /* !_CUPS_BACKEND_H_ */
 
index f3b4d6c1717bc1f6b860b955cb6e9fa387a17d71..6117c1dd9251d048a07023da38286653f0d5ba3e 100644 (file)
@@ -124,7 +124,8 @@ typedef const char *(*cups_password_cb_t)(const char *prompt);
 typedef void (*cups_device_cb_t)(const char *device_class,
                                  const char *device_id, const char *device_info,
                                  const char *device_make_and_model,
-                                 const char *device_uri, void *user_data);
+                                 const char *device_uri,
+                                const char *device_location, void *user_data);
                                        /**** Device callback @since CUPS 1.4@ ****/
 
 typedef struct cups_option_s           /**** Printer Options ****/
index b2e474b1e2ac9c92defd64ac586912c4839c3652..c6f7ddac3e0af5c37985584cfae6018b3c59fec1 100644 (file)
@@ -51,6 +51,7 @@ cupsGetDevices(
   const char   *device_class,          /* device-class value */
                *device_id,             /* device-id value */
                *device_info,           /* device-info value */
+               *device_location,       /* device-location value */
                *device_make_and_model, /* device-make-and-model value */
                *device_uri;            /* device-uri value */
   int          blocking;               /* Current blocking-IO mode */
@@ -161,6 +162,7 @@ cupsGetDevices(
   device_class          = NULL;
   device_id             = NULL;
   device_info           = NULL;
+  device_location       = "";
   device_make_and_model = NULL;
   device_uri            = NULL;
   attr                  = NULL;
@@ -193,11 +195,13 @@ cupsGetDevices(
         if (device_class && device_id && device_info && device_make_and_model &&
            device_uri)
           (*callback)(device_class, device_id, device_info,
-                     device_make_and_model, device_uri, user_data);
+                     device_make_and_model, device_uri, device_location,
+                     user_data);
 
        device_class          = NULL;
        device_id             = NULL;
        device_info           = NULL;
+       device_location       = "";
        device_make_and_model = NULL;
        device_uri            = NULL;
       }
@@ -210,6 +214,9 @@ cupsGetDevices(
       else if (!strcmp(attr->name, "device-info") &&
                attr->value_tag == IPP_TAG_TEXT)
         device_info = attr->values[0].string.text;
+      else if (!strcmp(attr->name, "device-location") &&
+               attr->value_tag == IPP_TAG_TEXT)
+        device_location = attr->values[0].string.text;
       else if (!strcmp(attr->name, "device-make-and-model") &&
                attr->value_tag == IPP_TAG_TEXT)
         device_make_and_model = attr->values[0].string.text;
@@ -226,7 +233,7 @@ cupsGetDevices(
   if (device_class && device_id && device_info && device_make_and_model &&
       device_uri)
     (*callback)(device_class, device_id, device_info,
-               device_make_and_model, device_uri, user_data);
+               device_make_and_model, device_uri, device_location, user_data);
 
  /*
   * Set the IPP status and return...
index 8f34b3ccc157a3dfafbfbdc4a04c6640877040d2..3da3642b039362ca0b18852a68ceb3710c23a858 100644 (file)
@@ -86,6 +86,7 @@ _cupsArrayUserData
 _cupsBackChannelRead
 _cupsBackChannelWrite
 _cupsBackendDeviceURI
+_cupsBackendReport
 _cupsCancelJob
 _cupsCancelJob2
 _cupsCharsetToUTF8
index a1c85a82538e206e1a13ec59c4b9b40e40937d38..04639bef3a5688969064bc13b769b0417540a8cd 100644 (file)
@@ -2043,9 +2043,14 @@ string for the device.</p>
 <p>The device-info attribute specifies a human-readable string describing
 the device, e.g. "Parallel Port #1".
 
+<h4><a name="device-location">device-location (text(127))</a><span class="info">CUPS 1.4</span></h4>
+
+<p>The device-location attribute specifies the physical location of the
+printer.
+
 <h4><a name="device-make-and-model">device-make-and-model (text(127))</a></h4>
 
-<p>The device-makr-and-model attribute specifies a device
+<p>The device-make-and-model attribute specifies a device
 identification string provided by the printer connected to the device.
 If the device or printer does not support identification then this
 attribute contains the string "unknown".
index 064027d9cc2a5e11b361e346d7edeb73d749c8d2..2115c128a9871d2bf3aa8b932abdc64a637db28d 100644 (file)
@@ -3,7 +3,7 @@
 .\"
 .\"   Backend man page for the Common UNIX Printing System (CUPS).
 .\"
-.\"   Copyright 2007 by Apple Inc.
+.\"   Copyright 2007-2008 by Apple Inc.
 .\"   Copyright 1997-2006 by Easy Software Products.
 .\"
 .\"   These coded instructions, statements, and computer programs are the
@@ -12,7 +12,7 @@
 .\"   which should have been included with this file.  If this file is
 .\"   file is missing or damaged, see the license at "http://www.cups.org/".
 .\"
-.TH backend 7 "Common UNIX Printing System" "20 March 2006" "Apple Inc."
+.TH backend 7 "Common UNIX Printing System" "28 July 2008" "Apple Inc."
 
 .SH NAME
 backend \- cups backend transmission interfaces
@@ -59,6 +59,7 @@ forms:
     device-class scheme "Unknown" "device-info"
     device-class device-uri "device-make-and-model" "device-info"
     device-class device-uri "device-make-and-model" "device-info" "device-id"
+    device-class device-uri "device-make-and-model" "device-info" "device-id" "device-location"
 .fi
 
 .LP
@@ -111,6 +112,11 @@ The optional \fIdevice-id\fR field specifies the IEEE-1284 device
 ID string for the device, which is used to select a matching
 driver.
 
+.LP
+The optional \fIdevice-location\fR field specifies the physical location of
+the device, which is often used to pre-populate the printer-location attribute
+when adding a printer.
+
 .SH PERMISSIONS
 Backends without world execute permissions are run as the root
 user. Otherwise, the backend is run using the unprivileged user
@@ -173,7 +179,7 @@ All other exit code values are reserved.
 http://localhost:631/help
 
 .SH COPYRIGHT
-Copyright 2007 by Apple Inc.
+Copyright 2007-2008 by Apple Inc.
 .\"
 .\" End of "$Id$".
 .\"
index 8760713e12fc3ff7f1edb3c1039b24136c72c2ce..4a640e2b9226cefe22197565ada5745f3d3628ba 100644 (file)
@@ -65,10 +65,8 @@ typedef struct
 typedef struct
 {
   char device_class[128],              /* Device class */
-       device_make_and_model[128],     /* Make and model, if known */
        device_info[128],               /* Device info/description */
-       device_uri[1024],               /* Device URI */
-       device_id[1024];                /* 1284 Device ID */
+       device_uri[1024];               /* Device URI */
 } cupsd_device_t;
 
 
@@ -92,7 +90,8 @@ static int            send_class,     /* Send device-class attribute? */
                        send_make_and_model,
                                        /* Send device-make-and-model attribute? */
                        send_uri,       /* Send device-uri attribute? */
-                       send_id;        /* Send device-id attribute? */
+                       send_id,        /* Send device-id attribute? */
+                       send_location;  /* Send device-location attribute? */
 static int             dead_children = 0;
                                        /* Dead children? */
 
@@ -105,7 +104,8 @@ static int          add_device(const char *device_class,
                                   const char *device_make_and_model,
                                   const char *device_info,
                                   const char *device_uri,
-                                  const char *device_id);
+                                  const char *device_id,
+                                  const char *device_location);
 static int             compare_devices(cupsd_device_t *p0,
                                        cupsd_device_t *p1);
 static cups_array_t    *create_strings_array(const char *s);
@@ -198,7 +198,10 @@ main(int  argc,                            /* I - Number of command-line args */
                                                    num_options, options));
 
   if (!requested || cupsArrayFind(requested, "all") != NULL)
-    send_class = send_info = send_make_and_model = send_uri = send_id = 1;
+  {
+    send_class = send_info = send_make_and_model = send_uri = send_id =
+        send_location = 1;
+  }
   else
   {
     send_class          = cupsArrayFind(requested, "device-class") != NULL;
@@ -206,6 +209,7 @@ main(int  argc,                             /* I - Number of command-line args */
     send_make_and_model = cupsArrayFind(requested, "device-make-and-model") != NULL;
     send_uri            = cupsArrayFind(requested, "device-uri") != NULL;
     send_id             = cupsArrayFind(requested, "device-id") != NULL;
+    send_location       = cupsArrayFind(requested, "device-location") != NULL;
   }
 
  /*
@@ -345,7 +349,8 @@ add_device(
     const char *device_make_and_model, /* I - Device make and model */
     const char *device_info,           /* I - Device information */
     const char *device_uri,            /* I - Device URI */
-    const char *device_id)             /* I - 1284 device ID */
+    const char *device_id,             /* I - 1284 device ID */
+    const char *device_location)       /* I - Physical location */
 {
   cupsd_device_t       *device;        /* New device */
 
@@ -366,11 +371,8 @@ add_device(
   */
 
   strlcpy(device->device_class, device_class, sizeof(device->device_class));
-  strlcpy(device->device_make_and_model, device_make_and_model,
-          sizeof(device->device_make_and_model));
   strlcpy(device->device_info, device_info, sizeof(device->device_info));
   strlcpy(device->device_uri, device_uri, sizeof(device->device_uri));
-  strlcpy(device->device_id, device_id, sizeof(device->device_id));
 
  /*
   * Add the device to the array and return...
@@ -397,16 +399,20 @@ add_device(
       cupsdSendIPPGroup(IPP_TAG_PRINTER);
       if (send_class)
        cupsdSendIPPString(IPP_TAG_KEYWORD, "device-class",
-                          device->device_class);
+                          device_class);
       if (send_info)
-       cupsdSendIPPString(IPP_TAG_TEXT, "device-info", device->device_info);
+       cupsdSendIPPString(IPP_TAG_TEXT, "device-info", device_info);
       if (send_make_and_model)
        cupsdSendIPPString(IPP_TAG_TEXT, "device-make-and-model",
-                          device->device_make_and_model);
+                          device_make_and_model);
       if (send_uri)
-       cupsdSendIPPString(IPP_TAG_URI, "device-uri", device->device_uri);
+       cupsdSendIPPString(IPP_TAG_URI, "device-uri", device_uri);
       if (send_id)
-       cupsdSendIPPString(IPP_TAG_TEXT, "device-id", device->device_id);
+       cupsdSendIPPString(IPP_TAG_TEXT, "device-id",
+                          device_id ? device_id : "");
+      if (send_location)
+       cupsdSendIPPString(IPP_TAG_TEXT, "device-location",
+                          device_location ? device_location : "");
 
       fflush(stdout);
       fputs("DEBUG: Flushed attributes...\n", stderr);
@@ -508,11 +514,14 @@ static int                                /* O - 0 on success, -1 on error */
 get_device(cupsd_backend_t *backend)   /* I - Backend to read from */
 {
   char line[2048],                     /* Line from backend */
-       dclass[64],                     /* Device class */
-       uri[1024],                      /* Device URI */
-       info[128],                      /* Device info */
-       make_model[256],                /* Make and model */
-       device_id[1024];                /* 1284 device ID */
+       temp[2048],                     /* Copy of line */
+       *ptr,                           /* Pointer into line */
+       *dclass,                        /* Device class */
+       *uri,                           /* Device URI */
+       *make_model,                    /* Make and model */
+       *info,                          /* Device info */
+       *device_id,                     /* 1284 device ID */
+       *location;                      /* Physical location */
 
 
   if (cupsFileGets(backend->pipe, line, sizeof(line)))
@@ -520,35 +529,123 @@ get_device(cupsd_backend_t *backend)     /* I - Backend to read from */
    /*
     * Each line is of the form:
     *
-    *   class URI "make model" "name" ["1284 device ID"]
+    *   class URI "make model" "name" ["1284 device ID"] ["location"]
+    */
+
+    strlcpy(temp, line, sizeof(temp));
+
+   /*
+    * device-class
+    */
+
+    dclass = temp;
+
+    for (ptr = line; *ptr; ptr ++)
+      if (isspace(*ptr & 255))
+        break;
+
+    while (isspace(*ptr & 255))
+      *ptr++ = '\0';
+
+   /*
+    * device-uri
+    */
+
+    if (!*ptr)
+      goto error;
+
+    for (uri = ptr; *ptr; ptr ++)
+      if (isspace(*ptr & 255))
+        break;
+
+    while (isspace(*ptr & 255))
+      *ptr++ = '\0';
+
+   /*
+    * device-make-and-model
     */
 
-    device_id[0] = '\0';
+    if (*ptr != '\"')
+      goto error;
 
-    if (sscanf(line,
-              "%63s%1023s%*[ \t]\"%255[^\"]\"%*[ \t]\"%127[^\"]\""
-              "%*[ \t]\"%1023[^\"]",
-              dclass, uri, make_model, info, device_id) < 4)
+    for (ptr ++, make_model = ptr; *ptr && *ptr != '\"'; ptr ++)
     {
-     /*
-      * Bad format; strip trailing newline and write an error message.
-      */
+      if (*ptr == '\\' && ptr[1])
+        _cups_strcpy(ptr, ptr + 1);
+    }
+
+    if (*ptr != '\"')
+      goto error;
+
+    for (*ptr++ = '\0'; isspace(*ptr & 255); *ptr++ = '\0');
+
+   /*
+    * device-info
+    */
 
-      if (line[strlen(line) - 1] == '\n')
-       line[strlen(line) - 1] = '\0';
+    if (*ptr != '\"')
+      goto error;
 
-      fprintf(stderr, "ERROR: [cups-deviced] Bad line from \"%s\": %s\n",
-             backend->name, line);
+    for (ptr ++, info = ptr; *ptr && *ptr != '\"'; ptr ++)
+    {
+      if (*ptr == '\\' && ptr[1])
+        _cups_strcpy(ptr, ptr + 1);
     }
-    else
+
+    if (*ptr != '\"')
+      goto error;
+
+    for (*ptr++ = '\0'; isspace(*ptr & 255); *ptr++ = '\0');
+
+   /*
+    * device-id
+    */
+
+    if (*ptr == '\"')
     {
+      for (ptr ++, device_id = ptr; *ptr && *ptr != '\"'; ptr ++)
+      {
+       if (*ptr == '\\' && ptr[1])
+         _cups_strcpy(ptr, ptr + 1);
+      }
+
+      if (*ptr != '\"')
+       goto error;
+
+      for (*ptr++ = '\0'; isspace(*ptr & 255); *ptr++ = '\0');
+
      /*
-      * Add the device to the array of available devices...
+      * device-location
       */
 
-      if (!add_device(dclass, make_model, info, uri, device_id))
-        fprintf(stderr, "DEBUG: [cups-deviced] Found device \"%s\"...\n", uri);
+      if (*ptr == '\"')
+      {
+       for (ptr ++, location = ptr; *ptr && *ptr != '\"'; ptr ++)
+       {
+         if (*ptr == '\\' && ptr[1])
+           _cups_strcpy(ptr, ptr + 1);
+       }
+
+       if (*ptr != '\"')
+         goto error;
+
+       *ptr++ = '\0';
+      }
+      else
+        location = NULL;
     }
+    else
+    {
+      device_id = NULL;
+      location  = NULL;
+    }
+
+   /*
+    * Add the device to the array of available devices...
+    */
+
+    if (!add_device(dclass, make_model, info, uri, device_id, location))
+      fprintf(stderr, "DEBUG: [cups-deviced] Found device \"%s\"...\n", uri);
 
     return (0);
   }
@@ -561,6 +658,19 @@ get_device(cupsd_backend_t *backend)       /* I - Backend to read from */
   backend->pipe = NULL;
 
   return (-1);
+
+ /*
+  * Bad format; strip trailing newline and write an error message.
+  */
+
+  error:
+
+  if (line[strlen(line) - 1] == '\n')
+    line[strlen(line) - 1] = '\0';
+
+  fprintf(stderr, "ERROR: [cups-deviced] Bad line from \"%s\": %s\n",
+         backend->name, line);
+  return (0);
 }
 
 
index 47cf6f60a453e8191c2f13fa5fdb2ab08c794d7a..d0906db8df37789cad41a5acb9e6fa7e7e2fbe4e 100644 (file)
@@ -40,7 +40,8 @@
 static void    device_cb(const char *device_clas, const char *device_id,
                          const char *device_info,
                          const char *device_make_and_model,
-                         const char *device_uri, void *user_data);
+                         const char *device_uri, const char *device_location,
+                         void *user_data);
 static int     show_devices(http_t *, int);
 static int     show_models(http_t *, int);
 
@@ -173,6 +174,7 @@ device_cb(
     const char *device_info,           /* I - device-info string */
     const char *device_make_and_model, /* I - device-make-and-model string */
     const char *device_uri,            /* I - device-uri string */
+    const char *device_location,       /* I - device-location string */
     void       *user_data)             /* I - User data */
 {
   int  *long_status;                   /* Show verbose info? */
@@ -191,9 +193,10 @@ device_cb(
                      "        class = %s\n"
                      "        info = %s\n"
                      "        make-and-model = %s\n"
-                     "        device-id = %s\n"),
+                     "        device-id = %s\n"
+                     "        location = %s\n"),
                    device_uri, device_class, device_info,
-                   device_make_and_model, device_id);
+                   device_make_and_model, device_id, device_location);
   }
   else
     _cupsLangPrintf(stdout, "%s %s\n", device_class, device_uri);