/*
- * "$Id: http-addr.c 177 2006-06-21 00:20:03Z jlovell $"
+ * "$Id: http-addr.c 7910 2008-09-06 00:25:17Z mike $"
*
* HTTP address routines for the Common UNIX Printing System (CUPS).
*
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
- * property of Easy Software Products and are protected by Federal
- * copyright law. Distribution and use rights are outlined in the file
- * "LICENSE.txt" which should have been included with this file. If this
- * file is missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
* Contents:
*
* httpAddrEqual() - Compare two addresses.
* httpAddrLocalhost() - Check for the local loopback address.
* httpAddrLookup() - Lookup the hostname associated with the address.
+ * _httpAddrPort() - Get the port number associated with an address.
* httpAddrString() - Convert an IP address to a dotted string.
* httpGetHostByName() - Lookup a hostname or IP address, and return
* address records for the specified name.
* Include necessary headers...
*/
+#include "http-private.h"
#include "globals.h"
#include "debug.h"
#include <stdlib.h>
#include <stddef.h>
+#ifdef HAVE_RESOLV_H
+# include <resolv.h>
+#endif /* HAVE_RESOLV_H */
/*
char *name, /* I - Host name buffer */
int namelen) /* I - Size of name buffer */
{
+ _cups_globals_t *cg = _cupsGlobals();
+ /* Global data */
+
+
DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)\n",
addr, name, namelen));
#ifdef AF_LOCAL
if (addr->addr.sa_family == AF_LOCAL)
+ {
strlcpy(name, addr->un.sun_path, namelen);
- else
+ return (name);
+ }
#endif /* AF_LOCAL */
+
+#ifdef HAVE_RES_INIT
+ /*
+ * STR #2920: Initialize resolver after failure in cups-polld
+ *
+ * If the previous lookup failed, re-initialize the resolver to prevent
+ * temporary network errors from persisting. This *should* be handled by
+ * the resolver libraries, but apparently the glibc folks do not agree.
+ *
+ * We set a flag at the end of this function if we encounter an error that
+ * requires reinitialization of the resolver functions. We then call
+ * res_init() if the flag is set on the next call here or in httpAddrLookup().
+ */
+
+ if (cg->need_res_init)
+ {
+ res_init();
+
+ cg->need_res_init = 0;
+ }
+#endif /* HAVE_RES_INIT */
+
#ifdef HAVE_GETNAMEINFO
{
- if (getnameinfo(&addr->addr, httpAddrLength(addr), name, namelen,
- NULL, 0, 0))
- {
- /*
- * If we get an error back, then the address type is not supported
- * and we should zero out the buffer...
- */
+ /*
+ * STR #2486: httpAddrLookup() fails when getnameinfo() returns EAI_AGAIN
+ *
+ * FWIW, I think this is really a bug in the implementation of
+ * getnameinfo(), but falling back on httpAddrString() is easy to
+ * do...
+ */
- name[0] = '\0';
+ int error = getnameinfo(&addr->addr, httpAddrLength(addr), name, namelen,
+ NULL, 0, 0);
- return (NULL);
+ if (error)
+ {
+ if (error == EAI_FAIL)
+ cg->need_res_init = 1;
+
+ return (httpAddrString(addr, name, namelen));
}
}
#else
* No hostname, so return the raw address...
*/
- httpAddrString(addr, name, namelen);
- return (NULL);
+ if (h_errno == NO_RECOVERY)
+ cg->need_res_init = 1;
+
+ return (httpAddrString(addr, name, namelen));
}
strlcpy(name, host->h_name, namelen);
}
+/*
+ * '_httpAddrPort()' - Get the port number associated with an address.
+ */
+
+int /* O - Port number */
+_httpAddrPort(http_addr_t *addr) /* I - Address */
+{
+ if (!addr)
+ return (ippPort());
+#ifdef AF_INET6
+ else if (addr->addr.sa_family == AF_INET6)
+ return (ntohs(addr->ipv6.sin6_port));
+#endif /* AF_INET6 */
+ else if (addr->addr.sa_family == AF_INET)
+ return (ntohs(addr->ipv4.sin_port));
+ else
+ return (ippPort());
+}
+
+
/*
* 'httpAddrString()' - Convert an address to a numeric string.
*
/*
- * End of "$Id: http-addr.c 177 2006-06-21 00:20:03Z jlovell $".
+ * End of "$Id: http-addr.c 7910 2008-09-06 00:25:17Z mike $".
*/