/*
* "$Id: http-support.c 7952 2008-09-17 00:56:20Z mike $"
*
- * HTTP support routines for the Common UNIX Printing System (CUPS) scheduler.
+ * HTTP support routines for CUPS.
*
- * Copyright 2007-2009 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
* httpStatus() - Return a short string describing a HTTP status code.
* _cups_hstrerror() - hstrerror() emulation function for Solaris and
* others...
+ * _httpDecodeURI() - Percent-decode a HTTP request URI.
* _httpEncodeURI() - Percent-encode a HTTP request URI.
* _httpResolveURI() - Resolve a DNS-SD URI.
* http_copy_decode() - Copy and decode a URI.
* Include necessary headers...
*/
-#include "debug.h"
-#include "globals.h"
-#include <stdlib.h>
+#include "cups-private.h"
#ifdef HAVE_DNSSD
# include <dns_sd.h>
-# include <poll.h>
+# ifdef WIN32
+# include <io.h>
+# elif defined(HAVE_POLL)
+# include <poll.h>
+# else
+# include <sys/select.h>
+# endif /* WIN32 */
#endif /* HAVE_DNSSD */
char *dstend, const char *reserved,
const char *term, int encode);
#ifdef HAVE_DNSSD
-static void resolve_callback(DNSServiceRef sdRef,
+static void DNSSD_API resolve_callback(DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
* Otherwise, just copy the host string...
*/
- ptr = http_copy_encode(ptr, host, end, ":/?#[]@\\", NULL,
+ ptr = http_copy_encode(ptr, host, end, ":/?#[]@\\\"", NULL,
encoding & HTTP_URI_CODING_HOSTNAME);
if (!ptr)
for (ptr = scheme, end = scheme + schemelen - 1;
*uri && *uri != ':' && ptr < end;)
- if (isalnum(*uri & 255) || *uri == '-' || *uri == '+' || *uri == '.')
+ if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789-+.", *uri) != NULL)
*ptr++ = *uri++;
else
break;
*port = 80;
else if (!strcmp(scheme, "https"))
*port = 443;
- else if (!strcmp(scheme, "ipp"))
+ else if (!strcmp(scheme, "ipp") || !strcmp(scheme, "ipps"))
*port = 631;
else if (!strcasecmp(scheme, "lpd"))
*port = 515;
case HTTP_SERVER_ERROR :
s = _("Internal Server Error");
break;
+ case HTTP_PKI_ERROR :
+ s = _("SSL/TLS Negotiation Error");
+ break;
+ case HTTP_WEBIF_DISABLED :
+ s = _("Web Interface is Disabled");
+ break;
default :
s = _("Unknown");
#endif /* !HAVE_HSTRERROR */
+/*
+ * '_httpDecodeURI()' - Percent-decode a HTTP request URI.
+ */
+
+char * /* O - Decoded URI or NULL on error */
+_httpDecodeURI(char *dst, /* I - Destination buffer */
+ const char *src, /* I - Source URI */
+ size_t dstsize) /* I - Size of destination buffer */
+{
+ if (http_copy_decode(dst, src, (int)dstsize, NULL, 1))
+ return (dst);
+ else
+ return (NULL);
+}
+
+
/*
* '_httpEncodeURI()' - Percent-encode a HTTP request URI.
*/
#endif /* DEBUG */
{
if (logit)
- _cupsLangPrintf(stderr, _("Bad device URI \"%s\"!\n"), uri);
+ _cupsLangPrintFilter(stderr, "ERROR", _("Bad device-uri \"%s\"."), uri);
DEBUG_printf(("6_httpResolveURI: httpSeparateURI returned %d!", status));
DEBUG_puts("5_httpResolveURI: Returning NULL");
if (strstr(hostname, "._tcp"))
{
#ifdef HAVE_DNSSD
+# ifdef WIN32
+# pragma comment(lib, "dnssd.lib")
+# endif /* WIN32 */
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? */
+ int domainsent = 0, /* Send the domain resolve? */
+ offline = 0; /* offline-report state set? */
char *regtype, /* Pointer to type in hostname */
*domain; /* Pointer to domain in hostname */
_http_uribuf_t uribuf; /* URI buffer */
+#ifdef HAVE_POLL
struct pollfd polldata; /* Polling data */
-
+#else /* select() */
+ fd_set input_set; /* Input set for select() */
+ struct timeval stimeout; /* Timeout value for select() */
+#endif /* HAVE_POLL */
if (logit)
fprintf(stderr, "DEBUG: Resolving \"%s\"...\n", hostname);
fputs("STATE: +connecting-to-device\n", stderr);
fprintf(stderr, "DEBUG: Resolving \"%s\", regtype=\"%s\", "
"domain=\"local.\"...\n", hostname, regtype);
- _cupsLangPuts(stderr, _("INFO: Looking for printer...\n"));
}
uri = NULL;
hostname, regtype, "local.", resolve_callback,
&uribuf) == kDNSServiceErr_NoError)
{
- if (strcasecmp(domain, "local."))
+ int fds; /* Number of ready descriptors */
+ time_t timeout, /* Poll timeout */
+ start_time = time(NULL);/* Start time */
+
+ for (;;)
{
+ if (logit)
+ _cupsLangPrintFilter(stderr, "INFO", _("Looking for printer."));
+
/*
- * Wait 2 seconds for a response to the local resolve; if nothing comes
- * in, do an additional domain resolution...
+ * For the first minute, wakeup every 2 seconds to emit a
+ * "looking for printer" message...
*/
+ timeout = (time(NULL) < (start_time + 60)) ? 2000 : -1;
+
+#ifdef HAVE_POLL
polldata.fd = DNSServiceRefSockFD(ref);
polldata.events = POLLIN;
- if (poll(&polldata, 1, 2000) != 1)
+ fds = poll(&polldata, 1, timeout);
+
+#else /* select() */
+ FD_ZERO(&input_set);
+ FD_SET(DNSServiceRefSockFD(ref), &input_set);
+
+ stimeout.tv_sec = ((int)timeout) / 1000;
+ stimeout.tv_usec = ((int)(timeout) * 1000) % 1000000;
+
+ fds = select(DNSServiceRefSockFD(ref)+1, &input_set, NULL, NULL,
+ timeout < 0.0 ? NULL : &stimeout);
+#endif /* HAVE_POLL */
+
+ if (fds < 0)
+ {
+ if (errno != EINTR && errno != EAGAIN)
+ {
+ DEBUG_printf(("5_httpResolveURI: poll error: %s", strerror(errno)));
+ break;
+ }
+ }
+ else if (fds == 0)
{
/*
- * OK, send the domain name resolve...
+ * Wait 2 seconds for a response to the local resolve; if nothing
+ * comes in, do an additional domain resolution...
*/
- if (logit)
- fprintf(stderr, "DEBUG: Resolving \"%s\", regtype=\"%s\", "
- "domain=\"%s\"...\n", hostname, regtype, domain);
+ if (domainsent == 0 && strcasecmp(domain, "local."))
+ {
+ 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;
+ }
- domainref = ref;
- if (DNSServiceResolve(&domainref, kDNSServiceFlagsShareConnection, 0,
- hostname, regtype, domain, resolve_callback,
- &uribuf) == kDNSServiceErr_NoError)
- domainsent = 1;
- }
- }
+ /*
+ * If it hasn't resolved within 5 seconds set the offline-report
+ * printer-state-reason...
+ */
- if (DNSServiceProcessResult(ref) == kDNSServiceErr_NoError)
- uri = resolved_uri;
+ if (logit && offline == 0 && time(NULL) > (start_time + 5))
+ {
+ fputs("STATE: +offline-report\n", stderr);
+ offline = 1;
+ }
+ }
+ else
+ {
+ if (DNSServiceProcessResult(ref) == kDNSServiceErr_NoError)
+ {
+ uri = resolved_uri;
+ break;
+ }
+ }
+ }
if (domainsent)
DNSServiceRefDeallocate(domainref);
if (uri)
fprintf(stderr, "DEBUG: Resolved as \"%s\"...\n", uri);
else
- fputs("DEBUG: Unable to resolve URI!\n", stderr);
+ fputs("DEBUG: Unable to resolve URI\n", stderr);
- fputs("STATE: -connecting-to-device\n", stderr);
+ fputs("STATE: -connecting-to-device,offline-report\n", stderr);
}
#else
#endif /* HAVE_DNSSD */
if (logit && !uri)
- _cupsLangPuts(stderr, _("Unable to find printer!\n"));
+ _cupsLangPrintFilter(stderr, "ERROR", _("Unable to find printer."));
}
DEBUG_printf(("5_httpResolveURI: Returning \"%s\"", uri));
* 'resolve_callback()' - Build a device URI for the given service name.
*/
-static void
+static void DNSSD_API
resolve_callback(
DNSServiceRef sdRef, /* I - Service reference */
DNSServiceFlags flags, /* I - Results flags */