From 5eb9da713fb99d4a865bbc65169eb1acf9ff08e2 Mon Sep 17 00:00:00 2001 From: msweet Date: Fri, 16 May 2008 23:29:51 +0000 Subject: [PATCH] Import CUPS 1.4svn-r7585. git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@771 a1ca3aef-8c08-0410-bb20-df032aa958be --- backend/backend-private.h | 1 - backend/ieee1284.c | 441 +++++++++++------------------------ backend/ipp.c | 2 +- backend/lpd.c | 2 +- backend/mdns.c | 46 ++-- backend/network.c | 181 -------------- backend/socket.c | 2 +- config-scripts/cups-dnssd.m4 | 2 +- cups/attr.c | 281 +++++++++++++++++++++- cups/backend.c | 18 +- cups/globals.h | 4 + cups/http-private.h | 8 +- cups/http-support.c | 193 ++++++++++++++- cups/libcups.exp | 3 + cups/libcups_s.exp | 4 + cups/ppd-private.h | 8 +- cups/snmp-private.h | 146 ------------ doc/images/left.xcf.gz | Bin 0 -> 3009 bytes scheduler/cups-driverd.c | 59 ++--- 19 files changed, 691 insertions(+), 710 deletions(-) create mode 100644 doc/images/left.xcf.gz 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 #endif /* __hpux */ -#ifdef HAVE_DNSSD -# include -#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 */ /* @@ -163,174 +150,6 @@ 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 @@ -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 #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 +#ifdef HAVE_DNSSD +# include +#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 */ /* @@ -1220,6 +1247,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 @@ -141,152 +141,6 @@ extern int _cupsSNMPWrite(int fd, http_addr_t *address, int version, #endif /* !_CUPS_SNMP_H_ */ -/* - * 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 0000000000000000000000000000000000000000..d61dd907095ef4a4ad0233bd29d086031506cb2f GIT binary patch literal 3009 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 #include - - -/* - * Private PPD functions... - */ - -extern cups_encoding_t _ppdGetEncoding(const char *name); +#include /* @@ -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; -- 2.39.2