summaryrefslogtreecommitdiff
path: root/cups
diff options
context:
space:
mode:
Diffstat (limited to 'cups')
-rw-r--r--cups/cups.h2
-rw-r--r--cups/debug.h12
-rw-r--r--cups/dest.c263
-rw-r--r--cups/globals.h1
-rw-r--r--cups/http-private.h1
-rw-r--r--cups/http-support.c80
-rw-r--r--cups/http.c211
-rw-r--r--cups/libcups.exp2
-rw-r--r--cups/request.c22
-rw-r--r--cups/testhttp.c2
-rw-r--r--cups/util.c12
11 files changed, 347 insertions, 261 deletions
diff --git a/cups/cups.h b/cups/cups.h
index 8742cf29d..8836aab94 100644
--- a/cups/cups.h
+++ b/cups/cups.h
@@ -288,8 +288,8 @@ extern int cupsGetConflicts(ppd_file_t *ppd, const char *option,
cups_option_t **options)
_CUPS_API_1_4;
extern ipp_status_t cupsGetDevices(http_t *http, int timeout,
- const char *exclude_schemes,
const char *include_schemes,
+ const char *exclude_schemes,
cups_device_cb_t callback,
void *user_data) _CUPS_API_1_4;
extern cups_dest_t *cupsGetNamedDest(http_t *http, const char *name,
diff --git a/cups/debug.h b/cups/debug.h
index 4efd1619c..0d81b46cb 100644
--- a/cups/debug.h
+++ b/cups/debug.h
@@ -19,6 +19,15 @@
# define _CUPS_DEBUG_H_
/*
+ * C++ magic...
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+
+
+/*
* The debug macros are used if you compile with DEBUG defined.
*
* Usage:
@@ -50,6 +59,9 @@ __attribute__ ((__format__ (__printf__, 1, 2)))
;
extern void _cups_debug_puts(const char *s);
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
#endif /* !_CUPS_DEBUG_H_ */
diff --git a/cups/dest.c b/cups/dest.c
index 9417bddc1..2886a0478 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -83,7 +83,6 @@
#ifdef __APPLE__
static CFArrayRef appleCopyLocations(void);
static CFStringRef appleCopyNetwork(void);
-static char *appleGetDefault(char *name, int namesize);
static char *appleGetPaperSize(char *name, int namesize);
static CFStringRef appleGetPrinter(CFArrayRef locations, CFStringRef network,
CFIndex *locindex);
@@ -99,8 +98,8 @@ static int cups_find_dest(const char *name, const char *instance,
static char *cups_get_default(const char *filename, char *namebuf,
size_t namesize, const char **instance);
static int cups_get_dests(const char *filename, const char *match_name,
- const char *match_inst, int num_dests,
- cups_dest_t **dests);
+ const char *match_inst, int user_default_set,
+ int num_dests, cups_dest_t **dests);
static int cups_get_sdests(http_t *http, ipp_op_t op, const char *name,
int num_dests, cups_dest_t **dests);
static char *cups_make_string(ipp_attribute_t *attr, char *buffer,
@@ -302,7 +301,8 @@ cupsGetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
char filename[1024]; /* Local ~/.cups/lpoptions file */
const char *defprinter; /* Default printer */
char name[1024], /* Copy of printer name */
- *instance; /* Pointer to instance name */
+ *instance, /* Pointer to instance name */
+ *user_default; /* User default printer */
int num_reals; /* Number of real queues */
cups_dest_t *reals; /* Real queues */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
@@ -362,22 +362,20 @@ cupsGetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
* Grab the default destination...
*/
-#ifdef __APPLE__
- if ((defprinter = appleGetDefault(name, sizeof(name))) == NULL)
-#endif /* __APPLE__ */
- defprinter = cupsGetDefault2(http);
+ if ((user_default = _cupsUserDefault(name, sizeof(name))) != NULL)
+ defprinter = name;
+ else if ((defprinter = cupsGetDefault2(http)) != NULL)
+ {
+ strlcpy(name, defprinter, sizeof(name));
+ defprinter = name;
+ }
if (defprinter)
{
/*
- * Grab printer and instance name...
+ * Separate printer and instance name...
*/
-#ifdef __APPLE__
- if (name != defprinter)
-#endif /* __APPLE__ */
- strlcpy(name, defprinter, sizeof(name));
-
if ((instance = strchr(name, '/')) != NULL)
*instance++ = '\0';
@@ -389,21 +387,15 @@ cupsGetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
dest->is_default = 1;
}
else
- {
- /*
- * This initialization of "instance" is unnecessary, but avoids a
- * compiler warning...
- */
-
instance = NULL;
- }
/*
* Load the /etc/cups/lpoptions and ~/.cups/lpoptions files...
*/
snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
- num_dests = cups_get_dests(filename, NULL, NULL, num_dests, dests);
+ num_dests = cups_get_dests(filename, NULL, NULL, user_default != NULL,
+ num_dests, dests);
if ((home = getenv("HOME")) != NULL)
{
@@ -411,7 +403,8 @@ cupsGetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
if (access(filename, 0))
snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
- num_dests = cups_get_dests(filename, NULL, NULL, num_dests, dests);
+ num_dests = cups_get_dests(filename, NULL, NULL, user_default != NULL,
+ num_dests, dests);
}
/*
@@ -497,6 +490,7 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT
char filename[1024], /* Path to lpoptions */
defname[256]; /* Default printer name */
const char *home = getenv("HOME"); /* Home directory */
+ int set_as_default = 0; /* Set returned destination as default */
ipp_op_t op = IPP_GET_PRINTER_ATTRIBUTES;
/* IPP operation to get server ops */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
@@ -508,9 +502,8 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT
if (!name)
{
- if ((name = getenv("LPDEST")) == NULL)
- if ((name = getenv("PRINTER")) != NULL && !strcmp(name, "lp"))
- name = NULL;
+ set_as_default = 1;
+ name = _cupsUserDefault(defname, sizeof(defname));
if (!name && home)
{
@@ -571,12 +564,15 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT
if (instance)
dest->instance = _cupsStrAlloc(instance);
+ if (set_as_default)
+ dest->is_default = 1;
+
/*
* Then add local options...
*/
snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
- cups_get_dests(filename, name, instance, 1, &dest);
+ cups_get_dests(filename, name, instance, 1, 1, &dest);
if (home)
{
@@ -585,7 +581,7 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT
if (access(filename, 0))
snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
- cups_get_dests(filename, name, instance, 1, &dest);
+ cups_get_dests(filename, name, instance, 1, 1, &dest);
}
/*
@@ -762,7 +758,7 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
* Merge in server defaults...
*/
- num_temps = cups_get_dests(filename, NULL, NULL, num_temps, &temps);
+ num_temps = cups_get_dests(filename, NULL, NULL, 0, num_temps, &temps);
/*
* Point to user defaults...
@@ -938,6 +934,106 @@ cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_
}
+/*
+ * '_cupsUserDefault()' - Get the user default printer from environment
+ * variables and location information.
+ */
+
+char * /* O - Default printer or NULL */
+_cupsUserDefault(char *name, /* I - Name buffer */
+ size_t namesize) /* I - Size of name buffer */
+{
+ const char *env; /* LPDEST or PRINTER env variable */
+#ifdef __APPLE__
+ CFStringRef network; /* Network location */
+ CFArrayRef locations; /* Location array */
+ CFStringRef locprinter; /* Current printer */
+#endif /* __APPLE__ */
+
+
+ if ((env = getenv("LPDEST")) == NULL)
+ if ((env = getenv("PRINTER")) != NULL && !strcmp(env, "lp"))
+ env = NULL;
+
+ if (env)
+ {
+ strlcpy(name, env, namesize);
+ return (name);
+ }
+
+#ifdef __APPLE__
+ /*
+ * Use location-based defaults if "use last printer" is selected in the
+ * system preferences...
+ */
+
+ if (!appleUseLastPrinter())
+ {
+ DEBUG_puts("_cupsUserDefault: Not using last printer as default...");
+ name[0] = '\0';
+ return (NULL);
+ }
+
+ /*
+ * Get the current location...
+ */
+
+ if ((network = appleCopyNetwork()) == NULL)
+ {
+ DEBUG_puts("_cupsUserDefault: Unable to get current network...");
+ name[0] = '\0';
+ return (NULL);
+ }
+
+# ifdef DEBUG
+ CFStringGetCString(network, name, namesize, kCFStringEncodingUTF8);
+ DEBUG_printf(("_cupsUserDefault: network=\"%s\"\n", name));
+# endif /* DEBUG */
+
+ /*
+ * Lookup the network in the preferences...
+ */
+
+ if ((locations = appleCopyLocations()) == NULL)
+ {
+ /*
+ * Missing or bad location array, so no location-based default...
+ */
+
+ DEBUG_puts("_cupsUserDefault: Missing or bad location history array...");
+
+ CFRelease(network);
+
+ name[0] = '\0';
+ return (NULL);
+ }
+
+ DEBUG_printf(("_cupsUserDefault: Got location, %d entries...\n",
+ (int)CFArrayGetCount(locations)));
+
+ if ((locprinter = appleGetPrinter(locations, network, NULL)) != NULL)
+ CFStringGetCString(locprinter, name, namesize, kCFStringEncodingUTF8);
+ else
+ name[0] = '\0';
+
+ CFRelease(network);
+ CFRelease(locations);
+
+ DEBUG_printf(("_cupsUserDefault: Returning \"%s\"...\n", name));
+
+ return (*name ? name : NULL);
+
+#else
+ /*
+ * No location-based defaults on this platform...
+ */
+
+ name[0] = '\0';
+ return (NULL);
+#endif /* __APPLE__ */
+}
+
+
#ifdef __APPLE__
/*
* 'appleCopyLocations()' - Copy the location history array.
@@ -1006,79 +1102,6 @@ appleCopyNetwork(void)
/*
- * 'appleGetDefault()' - Get the default printer for this location.
- */
-
-static char * /* O - Name or NULL if no default */
-appleGetDefault(char *name, /* I - Name buffer */
- int namesize) /* I - Size of name buffer */
-{
- CFStringRef network; /* Network location */
- CFArrayRef locations; /* Location array */
- CFStringRef locprinter; /* Current printer */
-
-
- /*
- * Use location-based defaults if "use last printer" is selected in the
- * system preferences...
- */
-
- if (!appleUseLastPrinter())
- {
- DEBUG_puts("appleGetDefault: Not using last printer as default...");
- return (NULL);
- }
-
- /*
- * Get the current location...
- */
-
- if ((network = appleCopyNetwork()) == NULL)
- {
- DEBUG_puts("appleGetDefault: Unable to get current network...");
- return (NULL);
- }
-
-#ifdef DEBUG
- CFStringGetCString(network, name, namesize, kCFStringEncodingUTF8);
- DEBUG_printf(("appleGetDefault: network=\"%s\"\n", name));
-#endif /* DEBUG */
-
- /*
- * Lookup the network in the preferences...
- */
-
- if ((locations = appleCopyLocations()) == NULL)
- {
- /*
- * Missing or bad location array, so no location-based default...
- */
-
- DEBUG_puts("appleGetDefault: Missing or bad location history array...");
-
- CFRelease(network);
-
- return (NULL);
- }
-
- DEBUG_printf(("appleGetDefault: Got location, %d entries...\n",
- (int)CFArrayGetCount(locations)));
-
- if ((locprinter = appleGetPrinter(locations, network, NULL)) != NULL)
- CFStringGetCString(locprinter, name, namesize, kCFStringEncodingUTF8);
- else
- name[0] = '\0';
-
- CFRelease(network);
- CFRelease(locations);
-
- DEBUG_printf(("appleGetDefault: Returning \"%s\"...\n", name));
-
- return (*name ? name : NULL);
-}
-
-
-/*
* 'appleGetPaperSize()' - Get the default paper size.
*/
@@ -1237,6 +1260,7 @@ appleSetDefault(const char *name) /* I - Default printer/class name */
CFPreferencesSetAppValue(kLocationHistoryArrayKey, newlocations,
kPMPrintingPreferences);
CFPreferencesAppSynchronize(kPMPrintingPreferences);
+ notify_post("com.apple.printerPrefsChange");
}
if (newlocations)
@@ -1526,11 +1550,13 @@ cups_get_default(const char *filename, /* I - File to read */
*/
static int /* O - Number of destinations */
-cups_get_dests(const char *filename, /* I - File to read from */
- const char *match_name, /* I - Destination name we want */
- const char *match_inst, /* I - Instance name we want */
- int num_dests, /* I - Number of destinations */
- cups_dest_t **dests) /* IO - Destinations */
+cups_get_dests(
+ const char *filename, /* I - File to read from */
+ const char *match_name, /* I - Destination name we want */
+ const char *match_inst, /* I - Instance name we want */
+ int user_default_set, /* I - User default printer set? */
+ int num_dests, /* I - Number of destinations */
+ cups_dest_t **dests) /* IO - Destinations */
{
int i; /* Looping var */
cups_dest_t *dest; /* Current destination */
@@ -1540,13 +1566,12 @@ cups_get_dests(const char *filename, /* I - File to read from */
*name, /* Name of destination/option */
*instance; /* Instance of destination */
int linenum; /* Current line number */
- const char *printer; /* PRINTER or LPDEST */
DEBUG_printf(("cups_get_dests(filename=\"%s\", match_name=\"%s\", "
- "match_inst=\"%s\", num_dests=%d, dests=%p)\n", filename,
- match_name ? match_name : "(null)",
- match_inst ? match_inst : "(null)", num_dests, dests));
+ "match_inst=\"%s\", user_default_set=%d, num_dests=%d, "
+ "dests=%p)\n", filename, match_name, match_inst,
+ user_default_set, num_dests, dests));
/*
* Try to open the file...
@@ -1556,18 +1581,6 @@ cups_get_dests(const char *filename, /* I - File to read from */
return (num_dests);
/*
- * Check environment variables...
- */
-
- if ((printer = getenv("LPDEST")) == NULL)
- if ((printer = getenv("PRINTER")) != NULL)
- if (strcmp(printer, "lp") == 0)
- printer = NULL;
-
- DEBUG_printf(("cups_get_dests: printer=\"%s\"\n",
- printer ? printer : "(null)"));
-
- /*
* Read each printer; each line looks like:
*
* Dest name[/instance] options
@@ -1583,7 +1596,7 @@ cups_get_dests(const char *filename, /* I - File to read from */
*/
DEBUG_printf(("cups_get_dests: linenum=%d line=\"%s\" lineptr=\"%s\"\n",
- linenum, line, lineptr ? lineptr : "(null)"));
+ linenum, line, lineptr));
if ((strcasecmp(line, "dest") && strcasecmp(line, "default")) || !lineptr)
{
@@ -1682,7 +1695,7 @@ cups_get_dests(const char *filename, /* I - File to read from */
* Set this as default if needed...
*/
- if (!printer && !strcasecmp(line, "default"))
+ if (!user_default_set && !strcasecmp(line, "default"))
{
DEBUG_puts("cups_get_dests: Setting as default...");
diff --git a/cups/globals.h b/cups/globals.h
index 9a0a99842..cdf4d1fec 100644
--- a/cups/globals.h
+++ b/cups/globals.h
@@ -145,6 +145,7 @@ extern _cups_globals_t *_cupsGlobals(void);
extern void _cupsSetError(ipp_status_t status, const char *message,
int localize);
extern void _cupsSetHTTPError(http_status_t status);
+extern char *_cupsUserDefault(char *name, size_t namesize);
/*
diff --git a/cups/http-private.h b/cups/http-private.h
index 8ffe5a281..9362e36d7 100644
--- a/cups/http-private.h
+++ b/cups/http-private.h
@@ -268,6 +268,7 @@ 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, int log);
+extern int _httpWait(http_t *http, int msec, int usessl);
#endif /* !_CUPS_HTTP_PRIVATE_H_ */
/*
diff --git a/cups/http-support.c b/cups/http-support.c
index 342c383b2..c59ecfb50 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -52,6 +52,7 @@
#include <stdlib.h>
#ifdef HAVE_DNSSD
# include <dns_sd.h>
+# include <poll.h>
#endif /* HAVE_DNSSD */
@@ -1347,10 +1348,18 @@ _httpResolveURI(
if (strstr(hostname, "._tcp"))
{
#ifdef HAVE_DNSSD
- DNSServiceRef ref; /* DNS-SD service reference */
+ DNSServiceRef ref, /* DNS-SD master service reference */
+ domainref, /* DNS-SD service reference for domain */
+ localref; /* DNS-SD service reference for .local */
+ int domainsent = 0; /* Send the domain resolve? */
char *regtype, /* Pointer to type in hostname */
*domain; /* Pointer to domain in hostname */
_http_uribuf_t uribuf; /* URI buffer */
+ struct pollfd polldata; /* Polling data */
+
+
+ if (logit)
+ fprintf(stderr, "DEBUG: Resolving \"%s\"...\n", hostname);
/*
* Separate the hostname into service name, registration type, and domain...
@@ -1375,10 +1384,6 @@ _httpResolveURI(
return (NULL);
}
- domain = regtype + strlen(regtype) - 1;
- if (domain > regtype && *domain == '.')
- *domain = '\0';
-
for (domain = strchr(regtype, '.');
domain;
domain = strchr(domain + 1, '.'))
@@ -1398,28 +1403,69 @@ _httpResolveURI(
if (logit)
{
fputs("STATE: +connecting-to-device\n", stderr);
- fprintf(stderr, "DEBUG: Resolving %s, regtype=%s, domain=%s...\n",
- hostname, regtype, domain);
+ fprintf(stderr, "DEBUG: Resolving \"%s\", regtype=\"%s\", "
+ "domain=\"local.\"...\n", hostname, regtype);
_cupsLangPuts(stderr, _("INFO: Looking for printer...\n"));
}
- if (DNSServiceResolve(&ref, 0, 0, hostname, regtype, domain,
- resolve_callback,
- &uribuf) == kDNSServiceErr_NoError)
+ uri = NULL;
+
+ if (DNSServiceCreateConnection(&ref) == kDNSServiceErr_NoError)
{
- if (DNSServiceProcessResult(ref) != kDNSServiceErr_NoError &&
- resolved_uri[0])
- uri = NULL;
- else
- uri = resolved_uri;
+ localref = ref;
+ if (DNSServiceResolve(&localref, kDNSServiceFlagsShareConnection, 0,
+ hostname, regtype, "local.", resolve_callback,
+ &uribuf) == kDNSServiceErr_NoError)
+ {
+ if (strcasecmp(domain, "local."))
+ {
+ /*
+ * Wait 2 seconds for a response to the local resolve; if nothing comes
+ * in, do an additional domain resolution...
+ */
+
+ polldata.fd = DNSServiceRefSockFD(ref);
+ polldata.events = POLLIN;
+
+ if (poll(&polldata, 1, 2000) != 1)
+ {
+ /*
+ * OK, send the domain name resolve...
+ */
+
+ if (logit)
+ fprintf(stderr, "DEBUG: Resolving \"%s\", regtype=\"%s\", "
+ "domain=\"%s\"...\n", hostname, regtype, domain);
+
+ domainref = ref;
+ if (DNSServiceResolve(&domainref, kDNSServiceFlagsShareConnection, 0,
+ hostname, regtype, domain, resolve_callback,
+ &uribuf) == kDNSServiceErr_NoError)
+ domainsent = 1;
+ }
+ }
+
+ if (DNSServiceProcessResult(ref) == kDNSServiceErr_NoError)
+ uri = resolved_uri;
+
+ if (domainsent)
+ DNSServiceRefDeallocate(domainref);
+
+ DNSServiceRefDeallocate(localref);
+ }
DNSServiceRefDeallocate(ref);
}
- else
- uri = NULL;
if (logit)
+ {
+ if (uri)
+ fputs("DEBUG: Unable to resolve URI!\n", stderr);
+ else
+ fprintf(stderr, "DEBUG: Resolved as \"%s\"...\n", uri);
+
fputs("STATE: -connecting-to-device\n", stderr);
+ }
#else
/*
diff --git a/cups/http.c b/cups/http.c
index 4d4ef2a7a..eef9973b8 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -3,7 +3,7 @@
*
* HTTP routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007-2008 by Apple Inc.
+ * Copyright 2007-2009 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
@@ -21,13 +21,14 @@
*
* _httpBIOMethods() - Get the OpenSSL BIO methods for HTTP connections.
* httpBlocking() - Set blocking/non-blocking behavior on a connection.
- * httpCheck() - Check to see if there is a pending response from
- * the server.
+ * httpCheck() - Check to see if there is a pending response from the
+ * server.
* httpClearCookie() - Clear the cookie value(s).
* httpClearFields() - Clear HTTP request fields.
* httpClose() - Close an HTTP connection...
* httpConnect() - Connect to a HTTP server.
* httpConnectEncrypt() - Connect to a HTTP server using encryption.
+ * _httpCreate() - Create an unconnected HTTP connection.
* httpDelete() - Send a DELETE request to the server.
* httpEncryption() - Set the required encryption on the link.
* httpError() - Get the last error on a connection.
@@ -46,6 +47,7 @@
* content-length or transfer-encoding fields.
* httpGetStatus() - Get the status of the last HTTP request.
* httpGetSubField() - Get a sub-field value.
+ * httpGetSubField2() - Get a sub-field value.
* httpGets() - Get a line of text from a HTTP connection.
* httpHead() - Send a HEAD request to the server.
* httpInitialize() - Initialize the HTTP interface library and set the
@@ -58,14 +60,15 @@
* httpRead2() - Read data from a HTTP connection.
* _httpReadCDSA() - Read function for the CDSA library.
* _httpReadGNUTLS() - Read function for the GNU TLS library.
- * httpReconnect() - Reconnect to a HTTP server...
+ * httpReconnect() - Reconnect to a HTTP server.
* httpSetAuthString() - Set the current authorization string.
* httpSetCookie() - Set the cookie value(s)...
* httpSetExpect() - Set the Expect: header in a request.
* httpSetField() - Set the value of an HTTP header.
- * httpSetLength() - Set the content-length and transfer-encoding.
+ * httpSetLength() - Set the content-length and content-encoding.
* httpTrace() - Send an TRACE request to the server.
* httpUpdate() - Update the current HTTP state for incoming data.
+ * _httpWait() - Wait for data available on a connection (no flush).
* httpWait() - Wait for data available on a connection.
* httpWrite() - Write data to a HTTP connection.
* httpWrite2() - Write data to a HTTP connection.
@@ -82,11 +85,11 @@
* http_read_ssl() - Read from a SSL/TLS connection.
* http_send() - Send a request with all fields and the trailing
* blank line.
- * http_setup_ssl() - Set up SSL/TLS on a connection.
+ * http_setup_ssl() - Set up SSL/TLS support on a connection.
* http_shutdown_ssl() - Shut down SSL/TLS on a connection.
* http_upgrade() - Force upgrade to TLS encryption.
- * http_wait() - Wait for data available on a connection.
- * http_write() - Write data to a connection.
+ * http_write() - Write a buffer to a HTTP connection.
+ * http_write_chunk() - Write a chunked buffer.
* http_write_ssl() - Write to a SSL/TLS connection.
*/
@@ -131,7 +134,6 @@ static void http_debug_hex(const char *prefix, const char *buffer,
static http_field_t http_field(const char *name);
static int http_send(http_t *http, http_state_t request,
const char *uri);
-static int http_wait(http_t *http, int msec, int usessl);
static int http_write(http_t *http, const char *buffer,
int length);
static int http_write_chunk(http_t *http, const char *buffer,
@@ -1012,7 +1014,7 @@ httpGets(char *line, /* I - Line to read into */
* No newline; see if there is more data to be read...
*/
- if (!http->blocking && !http_wait(http, 10000, 1))
+ if (!http->blocking && !_httpWait(http, 10000, 1))
{
DEBUG_puts("httpGets: Timed out!");
#ifdef WIN32
@@ -1539,7 +1541,7 @@ _httpReadCDSA(
* Make sure we have data before we read...
*/
- if (!http_wait(http, 10000, 0))
+ if (!_httpWait(http, 10000, 0))
{
http->error = ETIMEDOUT;
return (-1);
@@ -1600,7 +1602,7 @@ _httpReadGNUTLS(
* Make sure we have data before we read...
*/
- if (!http_wait(http, 10000, 0))
+ if (!_httpWait(http, 10000, 0))
{
http->error = ETIMEDOUT;
return (-1);
@@ -2075,6 +2077,95 @@ httpUpdate(http_t *http) /* I - Connection to server */
/*
+ * '_httpWait()' - Wait for data available on a connection (no flush).
+ */
+
+int /* O - 1 if data is available, 0 otherwise */
+_httpWait(http_t *http, /* I - Connection to server */
+ int msec, /* I - Milliseconds to wait */
+ int usessl) /* I - Use SSL context? */
+{
+#ifdef HAVE_POLL
+ struct pollfd pfd; /* Polled file descriptor */
+#else
+ fd_set input_set; /* select() input set */
+ struct timeval timeout; /* Timeout */
+#endif /* HAVE_POLL */
+ int nfds; /* Result from select()/poll() */
+
+
+ DEBUG_printf(("_httpWait(http=%p, msec=%d, usessl=%d)\n", http, msec, usessl));
+
+ if (http->fd < 0)
+ return (0);
+
+ /*
+ * Check the SSL/TLS buffers for data first...
+ */
+
+#ifdef HAVE_SSL
+ if (http->tls && usessl)
+ {
+# ifdef HAVE_LIBSSL
+ if (SSL_pending((SSL *)(http->tls)))
+ return (1);
+# elif defined(HAVE_GNUTLS)
+ if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))
+ return (1);
+# elif defined(HAVE_CDSASSL)
+ size_t bytes; /* Bytes that are available */
+
+ if (!SSLGetBufferedReadSize(((http_tls_t *)(http->tls))->session, &bytes) &&
+ bytes > 0)
+ return (1);
+# endif /* HAVE_LIBSSL */
+ }
+#endif /* HAVE_SSL */
+
+ /*
+ * Then try doing a select() or poll() to poll the socket...
+ */
+
+#ifdef HAVE_POLL
+ pfd.fd = http->fd;
+ pfd.events = POLLIN;
+
+ while ((nfds = poll(&pfd, 1, msec)) < 0 && errno == EINTR);
+
+#else
+ do
+ {
+ FD_ZERO(&input_set);
+ FD_SET(http->fd, &input_set);
+
+ DEBUG_printf(("_httpWait: msec=%d, http->fd=%d\n", msec, http->fd));
+
+ if (msec >= 0)
+ {
+ timeout.tv_sec = msec / 1000;
+ timeout.tv_usec = (msec % 1000) * 1000;
+
+ nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout);
+ }
+ else
+ nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL);
+
+ DEBUG_printf(("_httpWait: select() returned %d...\n", nfds));
+ }
+# ifdef WIN32
+ while (nfds < 0 && WSAGetLastError() == WSAEINTR);
+# else
+ while (nfds < 0 && errno == EINTR);
+# endif /* WIN32 */
+#endif /* HAVE_POLL */
+
+ DEBUG_printf(("_httpWait: returning with nfds=%d...\n", nfds));
+
+ return (nfds > 0);
+}
+
+
+/*
* 'httpWait()' - Wait for data available on a connection.
*
* @since CUPS 1.1.19/Mac OS X 10.3@
@@ -2108,7 +2199,7 @@ httpWait(http_t *http, /* I - Connection to server */
* If not, check the SSL/TLS buffers and do a select() on the connection...
*/
- return (http_wait(http, msec, 1));
+ return (_httpWait(http, msec, 1));
}
@@ -2174,7 +2265,8 @@ httpWrite2(http_t *http, /* I - Connection to server */
httpFlushWrite(http);
}
- if ((length + http->wused) <= sizeof(http->wbuffer))
+ if ((length + http->wused) <= sizeof(http->wbuffer) &&
+ length < sizeof(http->wbuffer))
{
/*
* Write to buffer...
@@ -2436,7 +2528,7 @@ http_bio_read(BIO *h, /* I - BIO data */
* Make sure we have data before we read...
*/
- if (!http_wait(http, 10000, 0))
+ if (!_httpWait(http, 10000, 0))
{
#ifdef WIN32
http->error = WSAETIMEDOUT;
@@ -3038,95 +3130,6 @@ http_upgrade(http_t *http) /* I - Connection to server */
/*
- * 'http_wait()' - Wait for data available on a connection.
- */
-
-static int /* O - 1 if data is available, 0 otherwise */
-http_wait(http_t *http, /* I - Connection to server */
- int msec, /* I - Milliseconds to wait */
- int usessl) /* I - Use SSL context? */
-{
-#ifdef HAVE_POLL
- struct pollfd pfd; /* Polled file descriptor */
-#else
- fd_set input_set; /* select() input set */
- struct timeval timeout; /* Timeout */
-#endif /* HAVE_POLL */
- int nfds; /* Result from select()/poll() */
-
-
- DEBUG_printf(("http_wait(http=%p, msec=%d)\n", http, msec));
-
- if (http->fd < 0)
- return (0);
-
- /*
- * Check the SSL/TLS buffers for data first...
- */
-
-#ifdef HAVE_SSL
- if (http->tls && usessl)
- {
-# ifdef HAVE_LIBSSL
- if (SSL_pending((SSL *)(http->tls)))
- return (1);
-# elif defined(HAVE_GNUTLS)
- if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))
- return (1);
-# elif defined(HAVE_CDSASSL)
- size_t bytes; /* Bytes that are available */
-
- if (!SSLGetBufferedReadSize(((http_tls_t *)(http->tls))->session, &bytes) &&
- bytes > 0)
- return (1);
-# endif /* HAVE_LIBSSL */
- }
-#endif /* HAVE_SSL */
-
- /*
- * Then try doing a select() or poll() to poll the socket...
- */
-
-#ifdef HAVE_POLL
- pfd.fd = http->fd;
- pfd.events = POLLIN;
-
- while ((nfds = poll(&pfd, 1, msec)) < 0 && errno == EINTR);
-
-#else
- do
- {
- FD_ZERO(&input_set);
- FD_SET(http->fd, &input_set);
-
- DEBUG_printf(("http_wait: msec=%d, http->fd=%d\n", msec, http->fd));
-
- if (msec >= 0)
- {
- timeout.tv_sec = msec / 1000;
- timeout.tv_usec = (msec % 1000) * 1000;
-
- nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout);
- }
- else
- nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL);
-
- DEBUG_printf(("http_wait: select() returned %d...\n", nfds));
- }
-# ifdef WIN32
- while (nfds < 0 && WSAGetLastError() == WSAEINTR);
-# else
- while (nfds < 0 && errno == EINTR);
-# endif /* WIN32 */
-#endif /* HAVE_POLL */
-
- DEBUG_printf(("http_wait: returning with nfds=%d...\n", nfds));
-
- return (nfds > 0);
-}
-
-
-/*
* 'http_write()' - Write a buffer to a HTTP connection.
*/
diff --git a/cups/libcups.exp b/cups/libcups.exp
index 74914ae44..4bb5cd67a 100644
--- a/cups/libcups.exp
+++ b/cups/libcups.exp
@@ -306,6 +306,8 @@ _ippRead
_ippReadFile
_ippReadIO
_ippSetPort
+_ippTagString
+_ippTagValue
_ippTimeToDate
_ippWrite
_ippWriteFile
diff --git a/cups/request.c b/cups/request.c
index bf291eabf..8179e51cb 100644
--- a/cups/request.c
+++ b/cups/request.c
@@ -753,6 +753,9 @@ cupsWriteRequestData(
const char *buffer, /* I - Bytes to write */
size_t length) /* I - Number of bytes to write */
{
+ int wused; /* Previous bytes in buffer */
+
+
/*
* Get the default connection as needed...
*/
@@ -776,6 +779,8 @@ cupsWriteRequestData(
* Then write to the HTTP connection...
*/
+ wused = http->wused;
+
if (httpWrite2(http, buffer, length) < 0)
return (HTTP_ERROR);
@@ -783,10 +788,19 @@ cupsWriteRequestData(
* Finally, check if we have any pending data from the server...
*/
- if (httpCheck(http))
- return (httpUpdate(http));
- else
- return (HTTP_CONTINUE);
+ if (length > HTTP_MAX_BUFFER ||
+ http->wused < wused ||
+ (wused > 0 && http->wused == length))
+ {
+ /*
+ * We've written something to the server, so check for response data...
+ */
+
+ if (_httpWait(http, 0, 1))
+ return (httpUpdate(http));
+ }
+
+ return (HTTP_CONTINUE);
}
diff --git a/cups/testhttp.c b/cups/testhttp.c
index fda2147b2..3e10a7634 100644
--- a/cups/testhttp.c
+++ b/cups/testhttp.c
@@ -468,7 +468,7 @@ main(int argc, /* I - Number of command-line arguments */
printf("_httpResolveURI(%s): ", argv[1]);
fflush(stdout);
- if (!_httpResolveURI(argv[1], resolved, sizeof(resolved), 0))
+ if (!_httpResolveURI(argv[1], resolved, sizeof(resolved), 1))
{
puts("FAIL");
return (1);
diff --git a/cups/util.c b/cups/util.c
index 1a6dd50a3..ee1cdf372 100644
--- a/cups/util.c
+++ b/cups/util.c
@@ -458,21 +458,15 @@ cupsGetDefault2(http_t *http) /* I - Connection to server or @code CUPS_HTTP_DE
ipp_t *request, /* IPP Request */
*response; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
- const char *var; /* Environment variable */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
/*
- * First see if the LPDEST or PRINTER environment variables are
- * set... However, if PRINTER is set to "lp", ignore it to work
- * around a "feature" in most Linux distributions - the default
- * user login scripts set PRINTER to "lp"...
+ * See if we have a user default printer set...
*/
- if ((var = getenv("LPDEST")) != NULL)
- return (var);
- else if ((var = getenv("PRINTER")) != NULL && strcmp(var, "lp") != 0)
- return (var);
+ if (_cupsUserDefault(cg->def_printer, sizeof(cg->def_printer)))
+ return (cg->def_printer);
/*
* Connect to the server as needed...