-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,
/* 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
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;
}
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;
}
}
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 */
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);
}
* 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 */
*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;
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;
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);
}
* 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;
}
}
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...
*/
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);
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());
}
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);
* 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...
device_uri[1024], /* Device URI string */
make_model[1024]; /* Make and model */
+
/*
* Try to open each USB device...
*/
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);
}
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);
}
* 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.
*
}
+/*
+ * '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$".
*/
*/
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_ */
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 ****/
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 */
device_class = NULL;
device_id = NULL;
device_info = NULL;
+ device_location = "";
device_make_and_model = NULL;
device_uri = NULL;
attr = NULL;
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;
}
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;
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...
_cupsBackChannelRead
_cupsBackChannelWrite
_cupsBackendDeviceURI
+_cupsBackendReport
_cupsCancelJob
_cupsCancelJob2
_cupsCharsetToUTF8
<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".
.\"
.\" 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
.\" 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
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
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
http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007 by Apple Inc.
+Copyright 2007-2008 by Apple Inc.
.\"
.\" End of "$Id$".
.\"
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;
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? */
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);
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;
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;
}
/*
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 */
*/
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...
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);
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)))
/*
* 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);
}
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);
}
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);
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? */
" 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);