summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/backend-private.h1
-rw-r--r--backend/ieee1284.c441
-rw-r--r--backend/ipp.c2
-rw-r--r--backend/lpd.c2
-rw-r--r--backend/mdns.c46
-rw-r--r--backend/network.c181
-rw-r--r--backend/socket.c2
-rw-r--r--config-scripts/cups-dnssd.m42
-rw-r--r--cups/attr.c281
-rw-r--r--cups/backend.c18
-rw-r--r--cups/globals.h4
-rw-r--r--cups/http-private.h8
-rw-r--r--cups/http-support.c193
-rw-r--r--cups/libcups.exp3
-rw-r--r--cups/libcups_s.exp4
-rw-r--r--cups/ppd-private.h8
-rw-r--r--cups/snmp-private.h146
-rw-r--r--doc/images/left.xcf.gzbin0 -> 3009 bytes
-rw-r--r--scheduler/cups-driverd.c59
19 files changed, 691 insertions, 710 deletions
diff --git a/backend/backend-private.h b/backend/backend-private.h
index 1a295b9a5..1b2204aad 100644
--- a/backend/backend-private.h
+++ b/backend/backend-private.h
@@ -254,7 +254,6 @@ extern int backendGetMakeModel(const char *device_id,
extern void backendNetworkSideCB(int print_fd, int device_fd,
int snmp_fd, http_addr_t *addr,
int use_bc);
-extern const char *backendResolveURI(char **argv);
extern ssize_t backendRunLoop(int print_fd, int device_fd, int snmp_fd,
http_addr_t *addr, int use_bc,
void (*side_cb)(int print_fd,
diff --git a/backend/ieee1284.c b/backend/ieee1284.c
index 463471df5..8b8579d80 100644
--- a/backend/ieee1284.c
+++ b/backend/ieee1284.c
@@ -68,12 +68,6 @@ backendGetDeviceID(
return (-1);
#else /* Get the device ID from the specified file descriptor... */
- char *attr, /* 1284 attribute */
- *delim, /* 1284 delimiter */
- *uriptr, /* Pointer into URI */
- manufacturer[256], /* Manufacturer string */
- serial_number[1024]; /* Serial number string */
- int manulen; /* Length of manufacturer string */
# ifdef __linux
int length; /* Length of device ID info */
int got_id = 0;
@@ -111,82 +105,82 @@ backendGetDeviceID(
*device_id = '\0';
# ifdef __linux
- if (ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id))
- {
- /*
- * Linux has to implement things differently for every device it seems.
- * Since the standard parallel port driver does not provide a simple
- * ioctl() to get the 1284 device ID, we have to open the "raw" parallel
- * device corresponding to this port and do some negotiation trickery
- * to get the current device ID.
- */
-
- if (uri && !strncmp(uri, "parallel:/dev/", 14))
+ if (ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id))
{
- char devparport[16]; /* /dev/parportN */
- int devparportfd, /* File descriptor for raw device */
- mode; /* Port mode */
-
-
/*
- * Since the Linux parallel backend only supports 4 parallel port
- * devices, just grab the trailing digit and use it to construct a
- * /dev/parportN filename...
+ * Linux has to implement things differently for every device it seems.
+ * Since the standard parallel port driver does not provide a simple
+ * ioctl() to get the 1284 device ID, we have to open the "raw" parallel
+ * device corresponding to this port and do some negotiation trickery
+ * to get the current device ID.
*/
- snprintf(devparport, sizeof(devparport), "/dev/parport%s",
- uri + strlen(uri) - 1);
-
- if ((devparportfd = open(devparport, O_RDWR | O_NOCTTY)) != -1)
+ if (uri && !strncmp(uri, "parallel:/dev/", 14))
{
+ char devparport[16]; /* /dev/parportN */
+ int devparportfd, /* File descriptor for raw device */
+ mode; /* Port mode */
+
+
/*
- * Claim the device...
- */
+ * Since the Linux parallel backend only supports 4 parallel port
+ * devices, just grab the trailing digit and use it to construct a
+ * /dev/parportN filename...
+ */
- if (!ioctl(devparportfd, PPCLAIM))
- {
- fcntl(devparportfd, F_SETFL, fcntl(devparportfd, F_GETFL) | O_NONBLOCK);
+ snprintf(devparport, sizeof(devparport), "/dev/parport%s",
+ uri + strlen(uri) - 1);
- mode = IEEE1284_MODE_COMPAT;
+ if ((devparportfd = open(devparport, O_RDWR | O_NOCTTY)) != -1)
+ {
+ /*
+ * Claim the device...
+ */
- if (!ioctl(devparportfd, PPNEGOT, &mode))
+ if (!ioctl(devparportfd, PPCLAIM))
{
- /*
- * Put the device into Device ID mode...
- */
+ fcntl(devparportfd, F_SETFL, fcntl(devparportfd, F_GETFL) | O_NONBLOCK);
- mode = IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID;
+ mode = IEEE1284_MODE_COMPAT;
if (!ioctl(devparportfd, PPNEGOT, &mode))
{
/*
- * Read the 1284 device ID...
+ * Put the device into Device ID mode...
*/
- if ((length = read(devparportfd, device_id,
- device_id_size - 1)) >= 2)
- {
- device_id[length] = '\0';
- got_id = 1;
+ mode = IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID;
+
+ if (!ioctl(devparportfd, PPNEGOT, &mode))
+ {
+ /*
+ * Read the 1284 device ID...
+ */
+
+ if ((length = read(devparportfd, device_id,
+ device_id_size - 1)) >= 2)
+ {
+ device_id[length] = '\0';
+ got_id = 1;
+ }
}
}
- }
- /*
- * Release the device...
- */
+ /*
+ * Release the device...
+ */
- ioctl(devparportfd, PPRELEASE);
- }
+ ioctl(devparportfd, PPRELEASE);
+ }
- close(devparportfd);
+ close(devparportfd);
+ }
}
}
- }
- else
- got_id = 1;
+ else
+ got_id = 1;
- if (got_id)
+ if (got_id)
{
/*
* Extract the length of the device ID string from the first two
@@ -268,108 +262,57 @@ backendGetDeviceID(
if (scheme && uri && uri_size > 32)
{
- /*
- * Look for the serial number field...
- */
+ int num_values; /* Number of keys and values */
+ cups_option_t *values; /* Keys and values in device ID */
+ const char *mfg, /* Manufacturer */
+ *mdl, /* Model */
+ *sern; /* Serial number */
+ char temp[256], /* Temporary manufacturer string */
+ *tempptr; /* Pointer into temp string */
- if ((attr = strstr(device_id, "SERN:")) != NULL)
- attr += 5;
- else if ((attr = strstr(device_id, "SERIALNUMBER:")) != NULL)
- attr += 13;
- else if ((attr = strstr(device_id, ";SN:")) != NULL)
- attr += 4;
-
- if (attr)
- {
- strlcpy(serial_number, attr, sizeof(serial_number));
-
- if ((delim = strchr(serial_number, ';')) != NULL)
- *delim = '\0';
- }
- else
- serial_number[0] = '\0';
/*
- * Generate the device URI from the manufacturer, make_model, and
- * serial number strings.
+ * Get the make, model, and serial numbers...
*/
- snprintf(uri, uri_size, "%s://", scheme);
+ num_values = _ppdGet1284Values(device_id, &values);
- if ((attr = strstr(device_id, "MANUFACTURER:")) != NULL)
- attr += 13;
- else if ((attr = strstr(device_id, "Manufacturer:")) != NULL)
- attr += 13;
- else if ((attr = strstr(device_id, "MFG:")) != NULL)
- attr += 4;
+ if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL)
+ if ((sern = cupsGetOption("SERN", num_values, values)) == NULL)
+ sern = cupsGetOption("SN", num_values, values);
- if (attr)
- {
- strlcpy(manufacturer, attr, sizeof(manufacturer));
+ if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
+ mfg = cupsGetOption("MFG", num_values, values);
- if ((delim = strchr(manufacturer, ';')) != NULL)
- *delim = '\0';
+ if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
+ mdl = cupsGetOption("MDL", num_values, values);
- if (!strcasecmp(manufacturer, "Hewlett-Packard"))
- strcpy(manufacturer, "HP");
- else if (!strcasecmp(manufacturer, "Lexmark International"))
- strcpy(manufacturer, "Lexmark");
+ if (mfg)
+ {
+ if (!strcasecmp(mfg, "Hewlett-Packard"))
+ mfg = "HP";
+ else if (!strcasecmp(mfg, "Lexmark International"))
+ mfg = "Lexmark";
}
else
{
- strlcpy(manufacturer, make_model, sizeof(manufacturer));
-
- if ((delim = strchr(manufacturer, ' ')) != NULL)
- *delim = '\0';
- }
-
- manulen = strlen(manufacturer);
-
- for (uriptr = uri + strlen(uri), delim = manufacturer;
- *delim && uriptr < (uri + uri_size - 3);
- delim ++)
- if (*delim == ' ')
- {
- *uriptr++ = '%';
- *uriptr++ = '2';
- *uriptr++ = '0';
- }
- else
- *uriptr++ = *delim;
-
- *uriptr++ = '/';
+ strlcpy(temp, make_model, sizeof(temp));
- if (!strncasecmp(make_model, manufacturer, manulen))
- {
- delim = make_model + manulen;
+ if ((tempptr = strchr(temp, ' ')) != NULL)
+ *tempptr = '\0';
- while (isspace(*delim & 255))
- delim ++;
+ mfg = temp;
}
- else
- delim = make_model;
- for (; *delim && uriptr < (uri + uri_size - 3); delim ++)
- if (*delim == ' ')
- {
- *uriptr++ = '%';
- *uriptr++ = '2';
- *uriptr++ = '0';
- }
- else
- *uriptr++ = *delim;
+ /*
+ * Generate the device URI from the manufacturer, make_model, and
+ * serial number strings.
+ */
- if (serial_number[0])
- {
- /*
- * Add the serial number to the URI...
- */
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, uri_size, scheme, NULL, mfg, 0,
+ "/%s%s%s", mdl, sern ? "?serial=" : "", sern ? sern : "");
- strlcpy(uriptr, "?serial=", uri_size - (uriptr - uri));
- strlcat(uriptr, serial_number, uri_size - (uriptr - uri));
- }
- else
- *uriptr = '\0';
+ cupsFreeOptions(num_values, values);
}
return (0);
@@ -387,10 +330,11 @@ backendGetMakeModel(
char *make_model, /* O - Make/model */
int make_model_size) /* I - Size of buffer */
{
- char *attr, /* 1284 attribute */
- *delim, /* 1284 delimiter */
- *mfg, /* Manufacturer string */
- *mdl; /* Model string */
+ int num_values; /* Number of keys and values */
+ cups_option_t *values; /* Keys and values */
+ const char *mfg, /* Manufacturer string */
+ *mdl, /* Model string */
+ *des; /* Description string */
DEBUG_printf(("backendGetMakeModel(device_id=\"%s\", "
@@ -413,63 +357,10 @@ backendGetMakeModel(
* Look for the description field...
*/
- if ((attr = strstr(device_id, "DES:")) != NULL)
- attr += 4;
- else if ((attr = strstr(device_id, "DESCRIPTION:")) != NULL)
- attr += 12;
+ num_values = _ppdGet1284Values(device_id, &values);
- if (attr)
- {
- /*
- * Make sure the description contains something useful, since some
- * printer manufacturers (HP) apparently don't follow the standards
- * they helped to define...
- *
- * Here we require the description to be 8 or more characters in length,
- * containing at least one space and one letter.
- */
-
- if ((delim = strchr(attr, ';')) == NULL)
- delim = attr + strlen(attr);
-
- if ((delim - attr) < 8)
- attr = NULL;
- else
- {
- char *ptr; /* Pointer into description */
- int letters, /* Number of letters seen */
- spaces; /* Number of spaces seen */
-
-
- for (ptr = attr, letters = 0, spaces = 0; ptr < delim; ptr ++)
- {
- if (isspace(*ptr & 255))
- spaces ++;
- else if (isalpha(*ptr & 255))
- letters ++;
-
- if (spaces && letters)
- break;
- }
-
- if (!spaces || !letters)
- attr = NULL;
- }
- }
-
- if ((mfg = strstr(device_id, "MANUFACTURER:")) != NULL)
- mfg += 13;
- else if ((mfg = strstr(device_id, "Manufacturer:")) != NULL)
- mfg += 13;
- else if ((mfg = strstr(device_id, "MFG:")) != NULL)
- mfg += 4;
-
- if ((mdl = strstr(device_id, "MODEL:")) != NULL)
- mdl += 6;
- else if ((mdl = strstr(device_id, "Model:")) != NULL)
- mdl += 6;
- else if ((mdl = strstr(device_id, "MDL:")) != NULL)
- mdl += 4;
+ if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
+ mdl = cupsGetOption("MDL", num_values, values);
if (mdl)
{
@@ -477,106 +368,65 @@ backendGetMakeModel(
* Build a make-model string from the manufacturer and model attributes...
*/
- if (mfg)
- {
- /*
- * Skip leading whitespace...
- */
-
- while (isspace(*mfg & 255))
- mfg ++;
+ if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
+ mfg = cupsGetOption("MFG", num_values, values);
+ if (!mfg || !strncasecmp(mdl, mfg, strlen(mfg)))
+ {
/*
- * Map common bad names to the ones we use for driver selection...
+ * Just copy the model string, since it has the manufacturer...
*/
- if (!strncasecmp(mfg, "Hewlett-Packard", 15))
- strlcpy(make_model, "HP", make_model_size);
- else if (!strncasecmp(mfg, "Lexmark International", 21))
- strlcpy(make_model, "Lexmark", make_model_size);
- else
- {
- /*
- * Use the manufacturer that is supplied...
- */
-
- strlcpy(make_model, mfg, make_model_size);
-
- if ((delim = strchr(make_model, ';')) != NULL)
- *delim = '\0';
-
- /*
- * But strip trailing whitespace...
- */
-
- for (delim = make_model + strlen(make_model) - 1;
- delim > make_model && *delim == ' ';
- delim --)
- *delim = '\0';
- }
-
- if (!strncasecmp(make_model, mdl, strlen(make_model)))
- {
- /*
- * Just copy model string, since it has the manufacturer...
- */
-
- strlcpy(make_model, mdl, make_model_size);
- }
- else
- {
- /*
- * Concatenate the make and model...
- */
-
- while (isspace(*mdl & 255))
- mdl ++;
-
- strlcat(make_model, " ", make_model_size);
- strlcat(make_model, mdl, make_model_size);
- }
+ _ppdNormalizeMakeAndModel(mdl, make_model, make_model_size);
}
else
{
/*
- * Just copy model string, since it has the manufacturer...
+ * Concatenate the make and model...
*/
- while (isspace(*mdl & 255))
- mdl ++;
+ char temp[1024]; /* Temporary make and model */
- strlcpy(make_model, mdl, make_model_size);
+ snprintf(temp, sizeof(temp), "%s %s", mfg, mdl);
+ _ppdNormalizeMakeAndModel(temp, make_model, make_model_size);
}
}
- else if (attr)
+ else if ((des = cupsGetOption("DESCRIPTION", num_values, values)) != NULL ||
+ (des = cupsGetOption("DES", num_values, values)) != NULL)
{
/*
- * Use description...
+ * Make sure the description contains something useful, since some
+ * printer manufacturers (HP) apparently don't follow the standards
+ * they helped to define...
+ *
+ * Here we require the description to be 8 or more characters in length,
+ * containing at least one space and one letter.
*/
- while (isspace(*attr & 255))
- attr ++;
-
- if (!strncasecmp(attr, "Hewlett-Packard hp ", 19))
+ if (strlen(des) >= 8)
{
- /*
- * Check for a common HP bug...
- */
+ const char *ptr; /* Pointer into description */
+ int letters, /* Number of letters seen */
+ spaces; /* Number of spaces seen */
- strlcpy(make_model, "HP ", make_model_size);
- strlcpy(make_model + 3, attr + 19, make_model_size - 3);
- }
- else if (!strncasecmp(attr, "Hewlett-Packard ", 16))
- {
- strlcpy(make_model, "HP ", make_model_size);
- strlcpy(make_model + 3, attr + 16, make_model_size - 3);
- }
- else
- {
- strlcpy(make_model, attr, make_model_size);
+
+ for (ptr = des, letters = 0, spaces = 0; *ptr; ptr ++)
+ {
+ if (isspace(*ptr & 255))
+ spaces ++;
+ else if (isalpha(*ptr & 255))
+ letters ++;
+
+ if (spaces && letters)
+ break;
+ }
+
+ if (spaces && letters)
+ _ppdNormalizeMakeAndModel(des, make_model, make_model_size);
}
}
- else
+
+ if (!make_model[0])
{
/*
* Use "Unknown" as the printer make and model...
@@ -585,36 +435,9 @@ backendGetMakeModel(
strlcpy(make_model, "Unknown", make_model_size);
}
- /*
- * Strip trailing data...
- */
-
- if ((delim = strchr(make_model, ';')) != NULL)
- *delim = '\0';
+ cupsFreeOptions(num_values, values);
- for (delim = make_model + strlen(make_model) - 1;
- delim > make_model && *delim == ' ';
- delim --)
- *delim = '\0';
-
- /*
- * Strip trailing whitespace...
- */
-
- for (delim = make_model + strlen(make_model) - 1; delim >= make_model; delim --)
- if (isspace(*delim & 255))
- *delim = '\0';
- else
- break;
-
- /*
- * Return...
- */
-
- if (make_model[0])
- return (0);
- else
- return (-1);
+ return (0);
}
diff --git a/backend/ipp.c b/backend/ipp.c
index 4704741de..83c0dc669 100644
--- a/backend/ipp.c
+++ b/backend/ipp.c
@@ -220,7 +220,7 @@ main(int argc, /* I - Number of command-line args */
* Extract the hostname and printer name from the URI...
*/
- if (httpSeparateURI(HTTP_URI_CODING_ALL, backendResolveURI(argv),
+ if (httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv),
method, sizeof(method), username, sizeof(username),
hostname, sizeof(hostname), &port,
resource, sizeof(resource)) < HTTP_URI_OK)
diff --git a/backend/lpd.c b/backend/lpd.c
index 8f173d27b..e8233ab28 100644
--- a/backend/lpd.c
+++ b/backend/lpd.c
@@ -188,7 +188,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
* Extract the hostname and printer name from the URI...
*/
- httpSeparateURI(HTTP_URI_CODING_ALL, backendResolveURI(argv),
+ httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv),
method, sizeof(method), username, sizeof(username),
hostname, sizeof(hostname), &port,
resource, sizeof(resource));
diff --git a/backend/mdns.c b/backend/mdns.c
index 36782679e..dba97231c 100644
--- a/backend/mdns.c
+++ b/backend/mdns.c
@@ -228,12 +228,13 @@ main(int argc, /* I - Number of command-line args */
*/
char device_uri[1024]; /* Device URI */
+ int count; /* Number of queries */
static const char * const schemes[] =
{ "lpd", "ipp", "ipp", "socket", "riousbprint" };
/* URI schemes for devices */
- for (device = (cups_device_t *)cupsArrayFirst(devices);
+ for (device = (cups_device_t *)cupsArrayFirst(devices), count = 0;
device;
device = (cups_device_t *)cupsArrayNext(devices))
if (!device->ref && !device->sent)
@@ -242,16 +243,21 @@ main(int argc, /* I - Number of command-line args */
* Found the device, now get the TXT record(s) for it...
*/
- device->ref = main_ref;
-
- fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName);
-
- if (DNSServiceQueryRecord(&(device->ref),
- kDNSServiceFlagsShareConnection,
- 0, device->fullName, kDNSServiceType_TXT,
- kDNSServiceClass_IN, query_callback,
- devices) != kDNSServiceErr_NoError)
- fputs("ERROR: Unable to query for TXT records!\n", stderr);
+ if (count < 10)
+ {
+ device->ref = main_ref;
+
+ fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName);
+
+ if (DNSServiceQueryRecord(&(device->ref),
+ kDNSServiceFlagsShareConnection,
+ 0, device->fullName, kDNSServiceType_TXT,
+ kDNSServiceClass_IN, query_callback,
+ devices) != kDNSServiceErr_NoError)
+ fputs("ERROR: Unable to query for TXT records!\n", stderr);
+ else
+ count ++;
+ }
}
else if (!device->sent)
{
@@ -404,7 +410,7 @@ exec_backend(char **argv) /* I - Command-line arguments */
* Resolve the device URI...
*/
- resolved_uri = backendResolveURI(argv);
+ resolved_uri = cupsBackendDeviceURI(argv);
/*
* Extract the scheme from the URI...
@@ -615,8 +621,20 @@ query_callback(
else if ((value = TXTRecordGetValuePtr(rdlen, rdata, "product",
&valueLen)) != NULL && valueLen > 2)
{
- memcpy(model, value + 1, valueLen - 2);
- model[valueLen - 2] = '\0';
+ if (((char *)value)[0] == '(')
+ {
+ /*
+ * Strip parenthesis...
+ */
+
+ memcpy(model, value + 1, valueLen - 2);
+ model[valueLen - 2] = '\0';
+ }
+ else
+ {
+ memcpy(model, value, valueLen);
+ model[valueLen] = '\0';
+ }
if (!strcasecmp(model, "GPL Ghostscript") ||
!strcasecmp(model, "GNU Ghostscript") ||
diff --git a/backend/network.c b/backend/network.c
index d83ea9ccf..46832a3d1 100644
--- a/backend/network.c
+++ b/backend/network.c
@@ -18,8 +18,6 @@
*
* backendCheckSideChannel() - Check the side-channel for pending requests.
* backendNetworkSideCB() - Handle common network side-channel commands.
- * backendResolveURI() - Get the device URI, resolving as needed.
- * resolve_callback() - Build a device URI for the given service name.
*/
/*
@@ -33,23 +31,12 @@
#else
# include <sys/select.h>
#endif /* __hpux */
-#ifdef HAVE_DNSSD
-# include <dns_sd.h>
-#endif /* HAVE_DNSSD */
/*
* Local functions...
*/
-#ifdef HAVE_DNSSD
-static void resolve_callback(DNSServiceRef sdRef, DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *fullName, const char *hostTarget,
- uint16_t port, uint16_t txtLen,
- const unsigned char *txtRecord, void *context);
-#endif /* HAVE_DNSSD */
/*
@@ -164,173 +151,5 @@ backendNetworkSideCB(
/*
- * 'backendResolveURI()' - Get the device URI, resolving as needed.
- */
-
-const char * /* O - Device URI */
-backendResolveURI(char **argv) /* I - Command-line arguments */
-{
- const char *uri; /* Device URI */
- char scheme[32], /* URI components... */
- userpass[256],
- hostname[1024],
- resource[1024];
- int port;
- http_uri_status_t status; /* URI decode status */
-
- /*
- * Get the device URI...
- */
-
- uri = cupsBackendDeviceURI(argv);
-
- if ((status = httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme,
- sizeof(scheme), userpass, sizeof(userpass),
- hostname, sizeof(hostname), &port,
- resource, sizeof(resource))) < HTTP_URI_OK)
- {
- fprintf(stderr, "ERROR: Bad device URI \"%s\" (%d)!\n", uri, status);
- exit (CUPS_BACKEND_STOP);
- }
-
- /*
- * Resolve it as needed...
- */
-
- if (strstr(hostname, "._tcp"))
- {
-#ifdef HAVE_DNSSD
- DNSServiceRef ref; /* DNS-SD service reference */
- char *regtype, /* Pointer to type in hostname */
- *domain; /* Pointer to domain in hostname */
- static char resolved_uri[HTTP_MAX_URI];
- /* Resolved device URI */
-
- /*
- * Separate the hostname into service name, registration type, and domain...
- */
-
- regtype = strchr(hostname, '.');
- *regtype++ = '\0';
-
- domain = regtype + strlen(regtype) - 1;
- if (domain > regtype && *domain == '.')
- *domain = '\0';
-
- for (domain = strchr(regtype, '.');
- domain;
- domain = strchr(domain + 1, '.'))
- if (domain[1] != '_')
- break;
-
- if (domain)
- *domain++ = '\0';
-
- fprintf(stderr,
- "DEBUG: Resolving service \"%s\", regtype \"%s\", domain \"%s\"\n",
- hostname, regtype, domain ? domain : "(null)");
-
- if (DNSServiceResolve(&ref, 0, 0, hostname, regtype, domain,
- resolve_callback,
- resolved_uri) == kDNSServiceErr_NoError)
- {
- if (DNSServiceProcessResult(ref) != kDNSServiceErr_NoError)
- uri = NULL;
- else
- uri = resolved_uri;
-
- DNSServiceRefDeallocate(ref);
- }
- else
-#endif /* HAVE_DNSSD */
-
- uri = NULL;
-
- if (!uri)
- {
- fprintf(stderr, "ERROR: Unable to resolve DNS-SD service \"%s\"!\n", uri);
- exit(CUPS_BACKEND_STOP);
- }
- }
-
- return (uri);
-}
-
-
-#ifdef HAVE_DNSSD
-/*
- * 'resolve_callback()' - Build a device URI for the given service name.
- */
-
-static void
-resolve_callback(
- DNSServiceRef sdRef, /* I - Service reference */
- DNSServiceFlags flags, /* I - Results flags */
- uint32_t interfaceIndex, /* I - Interface number */
- DNSServiceErrorType errorCode, /* I - Error, if any */
- const char *fullName, /* I - Full service name */
- const char *hostTarget, /* I - Hostname */
- uint16_t port, /* I - Port number */
- uint16_t txtLen, /* I - Length of TXT record */
- const unsigned char *txtRecord, /* I - TXT record data */
- void *context) /* I - Pointer to URI buffer */
-{
- const char *scheme; /* URI scheme */
- char rp[257]; /* Remote printer */
- const void *value; /* Value from TXT record */
- uint8_t valueLen; /* Length of value */
-
-
- fprintf(stderr,
- "DEBUG2: resolve_callback(sdRef=%p, flags=%x, interfaceIndex=%u, "
- "errorCode=%d, fullName=\"%s\", hostTarget=\"%s\", port=%u, "
- "txtLen=%u, txtRecord=%p, context=%p)\n", sdRef, flags,
- interfaceIndex, errorCode, fullName, hostTarget, port, txtLen,
- txtRecord, context);
-
- /*
- * Figure out the scheme from the full name...
- */
-
- if (strstr(fullName, "._ipp"))
- scheme = "ipp";
- else if (strstr(fullName, "._printer."))
- scheme = "lpd";
- else if (strstr(fullName, "._pdl-datastream."))
- scheme = "socket";
- else
- scheme = "riousbprint";
-
- /*
- * Extract the "remote printer" key from the TXT record...
- */
-
- if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "rp",
- &valueLen)) != NULL)
- {
- /*
- * Convert to resource by concatenating with a leading "/"...
- */
-
- rp[0] = '/';
- memcpy(rp + 1, value, valueLen);
- rp[valueLen + 1] = '\0';
- }
- else
- rp[0] = '\0';
-
- /*
- * Assemble the final device URI...
- */
-
- httpAssembleURI(HTTP_URI_CODING_ALL, (char *)context, HTTP_MAX_URI, scheme,
- NULL, hostTarget, ntohs(port), rp);
-
- fprintf(stderr, "DEBUG: Resolved URI is \"%s\"...\n", (char *)context);
-}
-#endif /* HAVE_DNSSD */
-
-
-/*
* End of "$Id$".
*/
diff --git a/backend/socket.c b/backend/socket.c
index 77a580274..6f2c80ddf 100644
--- a/backend/socket.c
+++ b/backend/socket.c
@@ -160,7 +160,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
* Extract the hostname and port number from the URI...
*/
- httpSeparateURI(HTTP_URI_CODING_ALL, backendResolveURI(argv),
+ httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv),
method, sizeof(method), username, sizeof(username),
hostname, sizeof(hostname), &port,
resource, sizeof(resource));
diff --git a/config-scripts/cups-dnssd.m4 b/config-scripts/cups-dnssd.m4
index 28deb7583..6ef18a702 100644
--- a/config-scripts/cups-dnssd.m4
+++ b/config-scripts/cups-dnssd.m4
@@ -40,7 +40,7 @@ if test x$enable_dnssd != xno; then
;;
*)
# All others...
- AC_CHECK_LIB(dns_sd,DNSServiceCreateConnection,
+ AC_CHECK_LIB(dns_sd,TXTRecordGetValuePtr,
AC_DEFINE(HAVE_DNSSD)
DNSSDLIBS="-ldns_sd")
;;
diff --git a/cups/attr.c b/cups/attr.c
index 83e6ba887..aabd0ee75 100644
--- a/cups/attr.c
+++ b/cups/attr.c
@@ -1,5 +1,5 @@
/*
- * "$Id: attr.c 6649 2007-07-11 21:46:42Z mike $"
+ * "$Id: attr.c 7584 2008-05-16 22:55:53Z mike $"
*
* PPD model-specific attribute routines for the Common UNIX Printing System
* (CUPS).
@@ -23,7 +23,7 @@
* Include necessary headers...
*/
-#include "ppd.h"
+#include "ppd-private.h"
#include "debug.h"
#include "string.h"
#include <stdlib.h>
@@ -154,5 +154,280 @@ ppdFindNextAttr(ppd_file_t *ppd, /* I - PPD file data */
/*
- * End of "$Id: attr.c 6649 2007-07-11 21:46:42Z mike $".
+ * '_ppdGet1284Values()' - Get 1284 device ID keys and values.
+ *
+ * The returned dictionary is a CUPS option array that can be queried with
+ * cupsGetOption and freed with cupsFreeOptions.
+ */
+
+int /* O - Number of key/value pairs */
+_ppdGet1284Values(
+ const char *device_id, /* I - IEEE-1284 device ID string */
+ cups_option_t **values) /* O - Array of key/value pairs */
+{
+ int num_values; /* Number of values */
+ char key[256], /* Key string */
+ value[256], /* Value string */
+ *ptr; /* Pointer into key/value */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (values)
+ *values = NULL;
+
+ if (!device_id || !values)
+ return (0);
+
+ /*
+ * Parse the 1284 device ID value into keys and values. The format is
+ * repeating sequences of:
+ *
+ * [whitespace]key:value[whitespace];
+ */
+
+ num_values = 0;
+ while (*device_id)
+ {
+ while (isspace(*device_id & 255))
+ device_id ++;
+
+ if (!*device_id)
+ break;
+
+ for (ptr = key; *device_id && *device_id != ':'; device_id ++)
+ if (ptr < (key + sizeof(key) - 1))
+ *ptr++ = *device_id;
+
+ if (!*device_id)
+ break;
+
+ while (ptr > key && isspace(ptr[-1] & 255))
+ ptr --;
+
+ *ptr = '\0';
+ device_id ++;
+
+ while (isspace(*device_id & 255))
+ device_id ++;
+
+ if (!*device_id)
+ break;
+
+ for (ptr = value; *device_id && *device_id != ';'; device_id ++)
+ if (ptr < (value + sizeof(value) - 1))
+ *ptr++ = *device_id;
+
+ if (!*device_id)
+ break;
+
+ while (ptr > value && isspace(ptr[-1] & 255))
+ ptr --;
+
+ *ptr = '\0';
+ device_id ++;
+
+ num_values = cupsAddOption(key, value, num_values, values);
+ }
+
+ return (num_values);
+}
+
+
+/*
+ * '_ppdNormalizeMakeAndModel()' - Normalize a product/make-and-model string.
+ *
+ * This function tries to undo the mistakes made by many printer manufacturers
+ * to produce a clean make-and-model string we can use.
+ */
+
+char * /* O - Normalized make-and-model string or NULL on error */
+_ppdNormalizeMakeAndModel(
+ const char *make_and_model, /* I - Original make-and-model string */
+ char *buffer, /* I - String buffer */
+ size_t bufsize) /* I - Size of string buffer */
+{
+ char *bufptr; /* Pointer into buffer */
+
+
+ if (!make_and_model || !buffer || bufsize < 1)
+ {
+ if (buffer)
+ *buffer = '\0';
+
+ return (NULL);
+ }
+
+ /*
+ * Skip leading whitespace...
+ */
+
+ while (isspace(*make_and_model & 255))
+ make_and_model ++;
+
+ /*
+ * Remove parenthesis and add manufacturers as needed...
+ */
+
+ if (make_and_model[0] == '(')
+ {
+ strlcpy(buffer, make_and_model + 1, bufsize);
+
+ if ((bufptr = strrchr(buffer, ')')) != NULL)
+ *bufptr = '\0';
+ }
+ else if (!strncasecmp(make_and_model, "XPrint", 6))
+ {
+ /*
+ * Xerox XPrint...
+ */
+
+ snprintf(buffer, bufsize, "Xerox %s", make_and_model);
+ }
+ else if (!strncasecmp(make_and_model, "Eastman", 7))
+ {
+ /*
+ * Kodak...
+ */
+
+ snprintf(buffer, bufsize, "Kodak %s", make_and_model + 7);
+ }
+ else if (!strncasecmp(make_and_model, "laserwriter", 11))
+ {
+ /*
+ * Apple LaserWriter...
+ */
+
+ snprintf(buffer, bufsize, "Apple LaserWriter%s", make_and_model + 11);
+ }
+ else if (!strncasecmp(make_and_model, "colorpoint", 10))
+ {
+ /*
+ * Seiko...
+ */
+
+ snprintf(buffer, bufsize, "Seiko %s", make_and_model);
+ }
+ else if (!strncasecmp(make_and_model, "fiery", 5))
+ {
+ /*
+ * EFI...
+ */
+
+ snprintf(buffer, bufsize, "EFI %s", make_and_model);
+ }
+ else if (!strncasecmp(make_and_model, "ps ", 3) ||
+ !strncasecmp(make_and_model, "colorpass", 9))
+ {
+ /*
+ * Canon...
+ */
+
+ snprintf(buffer, bufsize, "Canon %s", make_and_model);
+ }
+ else if (!strncasecmp(make_and_model, "primera", 7))
+ {
+ /*
+ * Fargo...
+ */
+
+ snprintf(buffer, bufsize, "Fargo %s", make_and_model);
+ }
+ else if (!strncasecmp(make_and_model, "designjet", 9) ||
+ !strncasecmp(make_and_model, "deskjet", 7))
+ {
+ /*
+ * HP...
+ */
+
+ snprintf(buffer, bufsize, "HP %s", make_and_model);
+ }
+ else
+ strlcpy(buffer, make_and_model, bufsize);
+
+ /*
+ * Clean up the make...
+ */
+
+ if (!strncasecmp(buffer, "agfa", 4))
+ {
+ /*
+ * Replace with AGFA (all uppercase)...
+ */
+
+ buffer[0] = 'A';
+ buffer[1] = 'G';
+ buffer[2] = 'F';
+ buffer[3] = 'A';
+ }
+ else if (!strncasecmp(buffer, "Hewlett-Packard hp ", 19))
+ {
+ /*
+ * Just put "HP" on the front...
+ */
+
+ buffer[0] = 'H';
+ buffer[1] = 'P';
+ _cups_strcpy(buffer + 2, buffer + 18);
+ }
+ else if (!strncasecmp(buffer, "Hewlett-Packard ", 16))
+ {
+ /*
+ * Just put "HP" on the front...
+ */
+
+ buffer[0] = 'H';
+ buffer[1] = 'P';
+ _cups_strcpy(buffer + 2, buffer + 15);
+ }
+ else if (!strncasecmp(buffer, "Lexmark International", 21))
+ {
+ /*
+ * Strip "International"...
+ */
+
+ _cups_strcpy(buffer + 8, buffer + 21);
+ }
+ else if (!strncasecmp(buffer, "herk", 4))
+ {
+ /*
+ * Replace with LHAG...
+ */
+
+ buffer[0] = 'L';
+ buffer[1] = 'H';
+ buffer[2] = 'A';
+ buffer[3] = 'G';
+ }
+ else if (!strncasecmp(buffer, "linotype", 8))
+ {
+ /*
+ * Replace with LHAG...
+ */
+
+ buffer[0] = 'L';
+ buffer[1] = 'H';
+ buffer[2] = 'A';
+ buffer[3] = 'G';
+ _cups_strcpy(buffer + 4, buffer + 8);
+ }
+
+ /*
+ * Remove trailing whitespace and return...
+ */
+
+ for (bufptr = buffer + strlen(buffer) - 1;
+ bufptr >= buffer && isspace(*bufptr & 255);
+ bufptr --);
+
+ bufptr[1] = '\0';
+
+ return (buffer[0] ? buffer : NULL);
+}
+
+
+/*
+ * End of "$Id: attr.c 7584 2008-05-16 22:55:53Z mike $".
*/
diff --git a/cups/backend.c b/cups/backend.c
index e30aa9bbf..db17bda70 100644
--- a/cups/backend.c
+++ b/cups/backend.c
@@ -25,7 +25,7 @@
#include <stdlib.h>
#include "backend.h"
-#include "string.h"
+#include "globals.h"
/*
@@ -41,15 +41,19 @@ const char * /* O - Device URI or @code NULL@ */
cupsBackendDeviceURI(char **argv) /* I - Command-line arguments */
{
const char *device_uri; /* Device URI */
+ _cups_globals_t *cg = _cupsGlobals(); /* Global info */
- if ((device_uri = getenv("DEVICE_URI")) != NULL)
- return (device_uri);
+ if ((device_uri = getenv("DEVICE_URI")) == NULL)
+ {
+ if (!argv || !argv[0] || !strchr(argv[0], ':'))
+ return (NULL);
- if (!argv || !argv[0] || !strchr(argv[0], ':'))
- return (NULL);
- else
- return (argv[0]);
+ device_uri = argv[0];
+ }
+
+ return (_httpResolveURI(device_uri, cg->resolved_uri,
+ sizeof(cg->resolved_uri)));
}
diff --git a/cups/globals.h b/cups/globals.h
index a735f01ab..2110dbcd2 100644
--- a/cups/globals.h
+++ b/cups/globals.h
@@ -64,6 +64,10 @@ typedef struct _cups_globals_s /**** CUPS global state data ****/
/* Number of server settings */
cups_option_t *cupsd_settings;/* Server settings */
+ /* backend.c */
+ char resolved_uri[1024];
+ /* Buffer for cupsBackendDeviceURI */
+
#ifdef DEBUG
/* debug.c */
int debug_init, /* Did we initialize debugging? */
diff --git a/cups/http-private.h b/cups/http-private.h
index ba416f666..c933f45cf 100644
--- a/cups/http-private.h
+++ b/cups/http-private.h
@@ -258,11 +258,13 @@ extern void _cups_freeifaddrs(struct ifaddrs *addrs);
# endif /* !WIN32 */
/*
- * Common URI encoding function...
+ * Common URI functions...
*/
-extern char *_httpEncodeURI(char *dst, const char *src, size_t dstsize);
-
+extern char *_httpEncodeURI(char *dst, const char *src,
+ size_t dstsize);
+extern const char *_httpResolveURI(const char *uri, char *resolved_uri,
+ size_t resolved_size);
#endif /* !_CUPS_HTTP_PRIVATE_H_ */
/*
diff --git a/cups/http-support.c b/cups/http-support.c
index 145f19994..419383899 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -1,5 +1,5 @@
/*
- * "$Id: http-support.c 6649 2007-07-11 21:46:42Z mike $"
+ * "$Id: http-support.c 7583 2008-05-16 17:47:16Z mike $"
*
* HTTP support routines for the Common UNIX Printing System (CUPS) scheduler.
*
@@ -37,8 +37,10 @@
* _cups_hstrerror() - hstrerror() emulation function for Solaris and
* others...
* _httpEncodeURI() - Percent-encode a HTTP request URI.
+ * _httpResolveURI() - Resolve a DNS-SD URI.
* http_copy_decode() - Copy and decode a URI.
* http_copy_encode() - Copy and encode a URI.
+ * resolve_callback() - Build a device URI for the given service name.
*/
/*
@@ -48,6 +50,20 @@
#include "debug.h"
#include "globals.h"
#include <stdlib.h>
+#ifdef HAVE_DNSSD
+# include <dns_sd.h>
+#endif /* HAVE_DNSSD */
+
+
+/*
+ * Local types...
+ */
+
+typedef struct _http_uribuf_s /* URI buffer */
+{
+ char *buffer; /* Pointer to buffer */
+ size_t bufsize; /* Size of buffer */
+} _http_uribuf_t;
/*
@@ -91,6 +107,17 @@ static const char *http_copy_decode(char *dst, const char *src,
static char *http_copy_encode(char *dst, const char *src,
char *dstend, const char *reserved,
const char *term, int encode);
+#ifdef HAVE_DNSSD
+static void resolve_callback(DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode,
+ const char *fullName,
+ const char *hostTarget,
+ uint16_t port, uint16_t txtLen,
+ const unsigned char *txtRecord,
+ void *context);
+#endif /* HAVE_DNSSD */
/*
@@ -1221,6 +1248,91 @@ _httpEncodeURI(char *dst, /* I - Destination buffer */
/*
+ * '_httpResolveURI()' - Resolve a DNS-SD URI.
+ */
+
+const char * /* O - Resolved URI */
+_httpResolveURI(
+ const char *uri, /* I - DNS-SD URI */
+ char *resolved_uri, /* I - Buffer for resolved URI */
+ size_t resolved_size) /* I - Size of URI buffer */
+{
+ char scheme[32], /* URI components... */
+ userpass[256],
+ hostname[1024],
+ resource[1024];
+ int port;
+
+
+ /*
+ * Get the device URI...
+ */
+
+ if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
+ userpass, sizeof(userpass), hostname, sizeof(hostname),
+ &port, resource, sizeof(resource)) < HTTP_URI_OK)
+ return (NULL);
+
+ /*
+ * Resolve it as needed...
+ */
+
+ if (strstr(hostname, "._tcp"))
+ {
+#ifdef HAVE_DNSSD
+ DNSServiceRef ref; /* DNS-SD service reference */
+ char *regtype, /* Pointer to type in hostname */
+ *domain; /* Pointer to domain in hostname */
+ _http_uribuf_t uribuf; /* URI buffer */
+
+ /*
+ * Separate the hostname into service name, registration type, and domain...
+ */
+
+ regtype = strchr(hostname, '.');
+ *regtype++ = '\0';
+
+ domain = regtype + strlen(regtype) - 1;
+ if (domain > regtype && *domain == '.')
+ *domain = '\0';
+
+ for (domain = strchr(regtype, '.');
+ domain;
+ domain = strchr(domain + 1, '.'))
+ if (domain[1] != '_')
+ break;
+
+ if (domain)
+ *domain++ = '\0';
+
+ uribuf.buffer = resolved_uri;
+ uribuf.bufsize = resolved_size;
+
+ resolved_uri[0] = '\0';
+
+ if (DNSServiceResolve(&ref, 0, 0, hostname, regtype, domain,
+ resolve_callback,
+ &uribuf) == kDNSServiceErr_NoError)
+ {
+ if (DNSServiceProcessResult(ref) != kDNSServiceErr_NoError &&
+ resolved_uri[0])
+ uri = NULL;
+ else
+ uri = resolved_uri;
+
+ DNSServiceRefDeallocate(ref);
+ }
+ else
+#endif /* HAVE_DNSSD */
+
+ uri = NULL;
+ }
+
+ return (uri);
+}
+
+
+/*
* 'http_copy_decode()' - Copy and decode a URI.
*/
@@ -1337,6 +1449,83 @@ http_copy_encode(char *dst, /* O - Destination buffer */
}
+#ifdef HAVE_DNSSD
+/*
+ * 'resolve_callback()' - Build a device URI for the given service name.
+ */
+
+static void
+resolve_callback(
+ DNSServiceRef sdRef, /* I - Service reference */
+ DNSServiceFlags flags, /* I - Results flags */
+ uint32_t interfaceIndex, /* I - Interface number */
+ DNSServiceErrorType errorCode, /* I - Error, if any */
+ const char *fullName, /* I - Full service name */
+ const char *hostTarget, /* I - Hostname */
+ uint16_t port, /* I - Port number */
+ uint16_t txtLen, /* I - Length of TXT record */
+ const unsigned char *txtRecord, /* I - TXT record data */
+ void *context) /* I - Pointer to URI buffer */
+{
+ const char *scheme; /* URI scheme */
+ char rp[257]; /* Remote printer */
+ const void *value; /* Value from TXT record */
+ uint8_t valueLen; /* Length of value */
+ _http_uribuf_t *uribuf; /* URI buffer */
+
+
+ DEBUG_printf(("resolve_callback(sdRef=%p, flags=%x, interfaceIndex=%u, "
+ "errorCode=%d, fullName=\"%s\", hostTarget=\"%s\", port=%u, "
+ "txtLen=%u, txtRecord=%p, context=%p)\n", sdRef, flags,
+ interfaceIndex, errorCode, fullName, hostTarget, port, txtLen,
+ txtRecord, context));
+
+ /*
+ * Figure out the scheme from the full name...
+ */
+
+ if (strstr(fullName, "._ipp"))
+ scheme = "ipp";
+ else if (strstr(fullName, "._printer."))
+ scheme = "lpd";
+ else if (strstr(fullName, "._pdl-datastream."))
+ scheme = "socket";
+ else
+ scheme = "riousbprint";
+
+ /*
+ * Extract the "remote printer" key from the TXT record...
+ */
+
+ if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "rp",
+ &valueLen)) != NULL)
+ {
+ /*
+ * Convert to resource by concatenating with a leading "/"...
+ */
+
+ rp[0] = '/';
+ memcpy(rp + 1, value, valueLen);
+ rp[valueLen + 1] = '\0';
+ }
+ else
+ rp[0] = '\0';
+
+ /*
+ * Assemble the final device URI...
+ */
+
+ uribuf = (_http_uribuf_t *)context;
+
+ httpAssembleURI(HTTP_URI_CODING_ALL, uribuf->buffer, uribuf->bufsize, scheme,
+ NULL, hostTarget, ntohs(port), rp);
+
+ DEBUG_printf(("resolve_callback: Resolved URI is \"%s\"...\n",
+ uribuf->buffer));
+}
+#endif /* HAVE_DNSSD */
+
+
/*
- * End of "$Id: http-support.c 6649 2007-07-11 21:46:42Z mike $".
+ * End of "$Id: http-support.c 7583 2008-05-16 17:47:16Z mike $".
*/
diff --git a/cups/libcups.exp b/cups/libcups.exp
index bb12c552a..ed50f7a4f 100644
--- a/cups/libcups.exp
+++ b/cups/libcups.exp
@@ -40,15 +40,18 @@ __cupsStrScand
__cupsStrStatistics
__httpEncodeURI
__httpReadCDSA
+__httpResolveURI
__httpWriteCDSA
__ippAddAttr
__ippFindOption
__ippFreeAttr
__ppdFreeLanguages
+__ppdGet1284Values
__ppdGetEncoding
__ppdGetLanguages
__ppdHashName
__ppdLocalizedAttr
+__ppdNormalizeMakeAndModel
_cupsAddDest
_cupsAddOption
_cupsAdminCreateWindowsPPD
diff --git a/cups/libcups_s.exp b/cups/libcups_s.exp
index a556cdb89..987235093 100644
--- a/cups/libcups_s.exp
+++ b/cups/libcups_s.exp
@@ -39,10 +39,14 @@ _cups_strcpy
_cups_strlcat
_cups_strlcpy
_httpBIOMethods
+_httpEncodeURI
+_httpResolveURI
_ippAddAttr
_ippFreeAttr
_ppdFreeLanguages
+_ppdGet1284Values
_ppdGetEncoding
_ppdGetLanguages
_ppdHashName
_ppdLocalizedAttr
+_ppdNormalizeMakeAndModel
diff --git a/cups/ppd-private.h b/cups/ppd-private.h
index ffbebfc59..a7db65075 100644
--- a/cups/ppd-private.h
+++ b/cups/ppd-private.h
@@ -31,7 +31,7 @@
* Include necessary headers...
*/
-# include "ppd.h"
+# include "cups.h"
/*
@@ -44,10 +44,16 @@ extern "C" {
extern void _ppdFreeLanguages(cups_array_t *languages);
+extern int _ppdGet1284Values(const char *device_id,
+ cups_option_t **values);
+extern cups_encoding_t _ppdGetEncoding(const char *name);
extern cups_array_t *_ppdGetLanguages(ppd_file_t *ppd);
extern unsigned _ppdHashName(const char *name);
extern ppd_attr_t *_ppdLocalizedAttr(ppd_file_t *ppd, const char *keyword,
const char *spec, const char *ll_CC);
+extern char *_ppdNormalizeMakeAndModel(const char *make_and_model,
+ char *buffer,
+ size_t bufsize);
/*
diff --git a/cups/snmp-private.h b/cups/snmp-private.h
index 364913eb0..ae03ca684 100644
--- a/cups/snmp-private.h
+++ b/cups/snmp-private.h
@@ -144,149 +144,3 @@ extern int _cupsSNMPWrite(int fd, http_addr_t *address, int version,
/*
* End of "$Id$".
*/
-/*
- * "$Id$"
- *
- * SNMP definitions for the Common UNIX Printing System (CUPS).
- *
- * This API is PRIVATE and subject to change. No third-party applications
- * should use the SNMP API defined in this file.
- *
- * Copyright 2007-2008 by Apple Inc.
- * Copyright 2006-2007 by Easy Software Products, all rights reserved.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * "LICENSE" which should have been included with this file. If this
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * This file is subject to the Apple OS-Developed Software exception.
- */
-
-#ifndef _CUPS_SNMP_H_
-# define _CUPS_SNMP_H_
-
-
-/*
- * Include necessary headers.
- */
-
-#include "http.h"
-
-
-/*
- * Constants...
- */
-
-#define CUPS_SNMP_PORT 161 /* SNMP well-known port */
-#define CUPS_SNMP_MAX_OID 128 /* Maximum number of OID numbers */
-#define CUPS_SNMP_MAX_PACKET 1472 /* Maximum size of SNMP packet */
-#define CUPS_SNMP_MAX_STRING 512 /* Maximum size of string */
-#define CUPS_SNMP_VERSION_1 0 /* SNMPv1 */
-
-
-/*
- * Types...
- */
-
-enum cups_asn1_e /**** ASN1 request/object types ****/
-{
- CUPS_ASN1_END_OF_CONTENTS = 0x00, /* End-of-contents */
- CUPS_ASN1_BOOLEAN = 0x01, /* BOOLEAN */
- CUPS_ASN1_INTEGER = 0x02, /* INTEGER or ENUMERATION */
- CUPS_ASN1_BIT_STRING = 0x03, /* BIT STRING */
- CUPS_ASN1_OCTET_STRING = 0x04, /* OCTET STRING */
- CUPS_ASN1_NULL_VALUE = 0x05, /* NULL VALUE */
- CUPS_ASN1_OID = 0x06, /* OBJECT IDENTIFIER */
- CUPS_ASN1_SEQUENCE = 0x30, /* SEQUENCE */
- CUPS_ASN1_HEX_STRING = 0x40, /* Binary string aka Hex-STRING */
- CUPS_ASN1_COUNTER = 0x41, /* 32-bit unsigned aka Counter32 */
- CUPS_ASN1_GAUGE = 0x42, /* 32-bit unsigned aka Gauge32 */
- CUPS_ASN1_TIMETICKS = 0x43, /* 32-bit unsigned aka Timeticks32 */
- CUPS_ASN1_GET_REQUEST = 0xa0, /* GetRequest-PDU */
- CUPS_ASN1_GET_NEXT_REQUEST = 0xa1, /* GetNextRequest-PDU */
- CUPS_ASN1_GET_RESPONSE = 0xa2 /* GetResponse-PDU */
-};
-typedef enum cups_asn1_e cups_asn1_t; /**** ASN1 request/object types ****/
-
-struct cups_snmp_hexstring_s /**** Hex-STRING value ****/
-{
- unsigned char bytes[CUPS_SNMP_MAX_STRING];
- /* Bytes in string */
- int num_bytes; /* Number of bytes */
-};
-
-union cups_snmp_value_u /**** Object value ****/
-{
- int boolean; /* Boolean value */
- int integer; /* Integer value */
- unsigned counter; /* Counter value */
- unsigned gauge; /* Gauge value */
- unsigned timeticks; /* Timeticks value */
- int oid[CUPS_SNMP_MAX_OID]; /* OID value */
- char string[CUPS_SNMP_MAX_STRING];
- /* String value */
- struct cups_snmp_hexstring_s hex_string;
- /* Hex string value */
-};
-
-typedef struct cups_snmp_s /**** SNMP data packet ****/
-{
- const char *error; /* Encode/decode error */
- http_addr_t address; /* Source address */
- int version; /* Version number */
- char community[CUPS_SNMP_MAX_STRING];
- /* Community name */
- cups_asn1_t request_type; /* Request type */
- int request_id; /* request-id value */
- int error_status; /* error-status value */
- int error_index; /* error-index value */
- int object_name[CUPS_SNMP_MAX_OID];
- /* object-name value */
- cups_asn1_t object_type; /* object-value type */
- union cups_snmp_value_u
- object_value; /* object-value value */
-} cups_snmp_t;
-
-typedef void (*cups_snmp_cb_t)(cups_snmp_t *packet, void *data);
-
-/*
- * Prototypes...
- */
-
-# ifdef __cplusplus
-extern "C" {
-# endif /* __cplusplus */
-
-extern void _cupsSNMPClose(int fd) _CUPS_API_1_4;
-extern int *_cupsSNMPCopyOID(int *dst, const int *src, int dstsize)
- _CUPS_API_1_4;
-extern const char *_cupsSNMPDefaultCommunity(void) _CUPS_API_1_4;
-extern int _cupsSNMPIsOID(cups_snmp_t *packet, const int *oid)
- _CUPS_API_1_4;
-extern int _cupsSNMPIsOIDPrefixed(cups_snmp_t *packet,
- const int *prefix) _CUPS_API_1_4;
-extern int _cupsSNMPOpen(int family) _CUPS_API_1_4;
-extern cups_snmp_t *_cupsSNMPRead(int fd, cups_snmp_t *packet,
- double timeout) _CUPS_API_1_4;
-extern void _cupsSNMPSetDebug(int level) _CUPS_API_1_4;
-extern int _cupsSNMPWalk(int fd, http_addr_t *address, int version,
- const char *community, const int *prefix,
- double timeout, cups_snmp_cb_t cb,
- void *data) _CUPS_API_1_4;
-extern int _cupsSNMPWrite(int fd, http_addr_t *address, int version,
- const char *community,
- cups_asn1_t request_type,
- const unsigned request_id,
- const int *oid) _CUPS_API_1_4;
-
-# ifdef __cplusplus
-}
-# endif /* __cplusplus */
-#endif /* !_CUPS_SNMP_H_ */
-
-
-/*
- * End of "$Id$".
- */
diff --git a/doc/images/left.xcf.gz b/doc/images/left.xcf.gz
new file mode 100644
index 000000000..d61dd9070
--- /dev/null
+++ b/doc/images/left.xcf.gz
Binary files differ
diff --git a/scheduler/cups-driverd.c b/scheduler/cups-driverd.c
index 3a8faa46c..6c256a07e 100644
--- a/scheduler/cups-driverd.c
+++ b/scheduler/cups-driverd.c
@@ -36,13 +36,7 @@
#include "util.h"
#include <cups/dir.h>
#include <cups/transcode.h>
-
-
-/*
- * Private PPD functions...
- */
-
-extern cups_encoding_t _ppdGetEncoding(const char *name);
+#include <cups/ppd-private.h>
/*
@@ -1063,7 +1057,8 @@ load_ppds(const char *d, /* I - Actual directory */
nick_name[256], /* NickName */
device_id[256], /* 1284DeviceID */
product[256], /* Product */
- psversion[256]; /* PSVersion */
+ psversion[256], /* PSVersion */
+ temp[512]; /* Temporary make and model */
int model_number, /* cupsModelNumber */
type; /* ppd-type */
cups_array_t *products, /* Product array */
@@ -1228,8 +1223,8 @@ load_ppds(const char *d, /* I - Actual directory */
sscanf(line, "%*[^\"]\"%255[^\"]", device_id);
else if (!strncmp(line, "*Product:", 9))
{
- sscanf(line, "%*[^\"]\"(%255[^)]", product);
- cupsArrayAdd(products, strdup(product));
+ if (sscanf(line, "%*[^\"]\"(%255[^)]", product) == 1)
+ cupsArrayAdd(products, strdup(product));
}
else if (!strncmp(line, "*PSVersion:", 11))
{
@@ -1340,12 +1335,23 @@ load_ppds(const char *d, /* I - Actual directory */
cupsArrayAdd(products, strdup(model_name));
/*
- * See if we got a manufacturer...
+ * Normalize the make and model string...
*/
while (isspace(manufacturer[0] & 255))
_cups_strcpy(manufacturer, manufacturer + 1);
+ if (!strncasecmp(make_model, manufacturer, strlen(manufacturer)))
+ strlcpy(temp, make_model, sizeof(temp));
+ else
+ snprintf(temp, sizeof(temp), "%s %s", manufacturer, make_model);
+
+ _ppdNormalizeMakeAndModel(temp, make_model, sizeof(make_model));
+
+ /*
+ * See if we got a manufacturer...
+ */
+
if (!manufacturer[0] || !strcmp(manufacturer, "ESP"))
{
/*
@@ -1365,39 +1371,14 @@ load_ppds(const char *d, /* I - Actual directory */
if (*ptr && ptr > manufacturer)
*ptr = '\0';
- else if (!strncasecmp(manufacturer, "agfa", 4))
- strcpy(manufacturer, "AGFA");
- else if (!strncasecmp(manufacturer, "herk", 4) ||
- !strncasecmp(manufacturer, "linotype", 8))
- strcpy(manufacturer, "LHAG");
else
strcpy(manufacturer, "Other");
-
- /*
- * Hack for various vendors...
- */
-
- if (!strcasecmp(manufacturer, "XPrint"))
- strcpy(manufacturer, "Xerox");
- else if (!strcasecmp(manufacturer, "Eastman"))
- strcpy(manufacturer, "Kodak");
- else if (!strcasecmp(manufacturer, "laserwriter"))
- strcpy(manufacturer, "Apple");
- else if (!strcasecmp(manufacturer, "colorpoint"))
- strcpy(manufacturer, "Seiko");
- else if (!strcasecmp(manufacturer, "fiery"))
- strcpy(manufacturer, "EFI");
- else if (!strcasecmp(manufacturer, "ps") ||
- !strcasecmp(manufacturer, "colorpass"))
- strcpy(manufacturer, "Canon");
- else if (!strncasecmp(manufacturer, "primera", 7))
- strcpy(manufacturer, "Fargo");
- else if (!strcasecmp(manufacturer, "designjet"))
- strcpy(manufacturer, "HP");
}
else if (!strncasecmp(manufacturer, "LHAG", 4) ||
!strncasecmp(manufacturer, "linotype", 8))
strcpy(manufacturer, "LHAG");
+ else if (!strncasecmp(manufacturer, "Hewlett", 7))
+ strcpy(manufacturer, "HP");
/*
* Fix the lang_version as needed...
@@ -1449,7 +1430,7 @@ load_ppds(const char *d, /* I - Actual directory */
}
/*
- * Add the PPD file...
+ * Record the PPD file...
*/
new_ppd = !ppd;