Remove the various gethostbyname_r checks and just check for

* configure.in: Remove the various gethostbyname_r checks and just
	check for getnameinfo/getaddrinfo.

	* libsoup/soup-dns.c: de-nastify. Make this use threads instead of
	forking. Change the API around a bunch in the process.

	* libsoup/soup-address.c: Update for soup-dns changes

	* tests/dns.c: take multiple hostnames on the command line and
	resolve them all at once (patch from tml)
This commit is contained in:
Dan Winship
2005-04-12 19:18:46 +00:00
parent dbc7ce9e0f
commit 7ef7034cde
6 changed files with 554 additions and 817 deletions
+13
View File
@@ -1,3 +1,16 @@
2005-04-12 Dan Winship <danw@novell.com>
* configure.in: Remove the various gethostbyname_r checks and just
check for getnameinfo/getaddrinfo.
* libsoup/soup-dns.c: de-nastify. Make this use threads instead of
forking. Change the API around a bunch in the process.
* libsoup/soup-address.c: Update for soup-dns changes
* tests/dns.c: take multiple hostnames on the command line and
resolve them all at once (patch from tml)
2005-04-11 Dan Winship <danw@novell.com>
* configure.in: require glib-2.0 >= 2.4.0
+1 -82
View File
@@ -85,88 +85,7 @@ dnl *********************************
AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket))
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname))
AC_CHECK_FUNCS(inet_pton inet_aton)
### Check if we have gethostbyname_r (if so, assume gethostbyaddr_r).
AC_CHECK_FUNC(gethostbyname_r,
[
dnl First check for the glibc variant of gethostbyname_r
AC_MSG_CHECKING(for glibc gethostbyname_r)
AC_TRY_LINK([ #include <netdb.h>],[
struct hostent result_buf;
char buf[1024];
struct hostent* result;
int h_errnop;
gethostbyname_r("localhost", &result_buf, buf, sizeof(buf),
&result, &h_errnop);
], [
dnl Have glibc gethostbyname_r
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYNAME_R_GLIBC, 1,
[Define if you have a glibc-style gethostbyname_r()])
HAVE_GETHOSTBYNAME_R=yes
], [
dnl If we don't have glibc gethostbyname_r, check
dnl for Solaris/Irix gethostbyname_r
AC_MSG_RESULT(no)
AC_MSG_CHECKING(for Solaris/Irix gethostbyname_r)
AC_TRY_LINK([ #include <netdb.h>],[
struct hostent result;
char buf[1024];
int h_errnop;
gethostbyname_r("localhost", &result, buf, sizeof(buf), &h_errnop);
], [
dnl Have Solaris/Irix gethostbyname_r
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYNAME_R_SOLARIS, 1,
[Define if you have a Solaris-style gethostbyname_r()])
HAVE_GETHOSTBYNAME_R=yes
], [
dnl If don't have Solaris/Irix gethostbyname_r, check
dnl for HP-UX gethostbyname_r
AC_MSG_RESULT(no)
AC_MSG_CHECKING(for HP-UX gethostbyname_r)
AC_TRY_LINK([ #include <netdb.h>],[
struct hostent result;
char buf[1024];
gethostbyname_r("localhost", &result, buf);
], [
dnl Have HP-UX gethostbyname_r
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GETHOSTBYNAME_R_HPUX, 1,
[Define if you have an HP-UX-style gethostbyname_r()])
HAVE_GETHOSTBYNAME_R=yes
]
)]
)]
)])
# If we don't have gethostbyname_r, we'll use Glib mutexes, but give a warning
if test -z "$HAVE_GETHOSTBYNAME_R"; then
AC_DEFINE(HAVE_GETHOSTBYNAME_R_GLIB_MUTEX, 1,
[Define if you have no gethostbyname_r()])
AC_MSG_WARN([You have neither Glib threads nor the function
gethostbyname_r. This means that calls to
gethostbyname (called by the Soup address
functions) will not be thread safe so could
malfunction in programs that use threads.])
fi
AC_CHECK_FUNCS(inet_pton inet_aton getaddrinfo getnameinfo)
AC_CACHE_CHECK(IPv6 support, soup_cv_ipv6, [
AC_EGREP_HEADER(sockaddr_in6, netinet/in.h, soup_cv_ipv6=yes, soup_cv_ipv6=no)
+26 -73
View File
@@ -42,7 +42,7 @@ typedef struct {
char *name, *physical;
guint port;
SoupDNSEntry *lookup;
SoupDNSLookup *lookup;
guint timeout_id;
} SoupAddressPrivate;
#define SOUP_ADDRESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_ADDRESS, SoupAddressPrivate))
@@ -132,7 +132,7 @@ finalize (GObject *object)
g_free (priv->physical);
if (priv->lookup)
soup_dns_entry_cancel_lookup (priv->lookup);
soup_dns_lookup_free (priv->lookup);
if (priv->timeout_id)
g_source_remove (priv->timeout_id);
@@ -144,6 +144,8 @@ soup_address_class_init (SoupAddressClass *address_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (address_class);
soup_dns_init ();
g_type_class_add_private (address_class, sizeof (SoupAddressPrivate));
/* virtual method override */
@@ -187,6 +189,7 @@ soup_address_new (const char *name, guint port)
priv = SOUP_ADDRESS_GET_PRIVATE (addr);
priv->name = g_strdup (name);
priv->port = port;
priv->lookup = soup_dns_lookup_name (priv->name);
return addr;
}
@@ -215,6 +218,8 @@ soup_address_new_from_sockaddr (struct sockaddr *sa, int len)
priv = SOUP_ADDRESS_GET_PRIVATE (addr);
priv->sockaddr = g_memdup (sa, len);
priv->port = ntohs (SOUP_ADDRESS_GET_PORT (priv));
priv->lookup = soup_dns_lookup_address (priv->sockaddr);
return addr;
}
@@ -245,6 +250,7 @@ soup_address_new_any (SoupAddressFamily family, guint port)
priv->sockaddr = g_malloc0 (SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (family));
SOUP_ADDRESS_SET_FAMILY (priv, family);
SOUP_ADDRESS_SET_PORT (priv, htons (port));
priv->lookup = soup_dns_lookup_address (priv->sockaddr);
return addr;
}
@@ -309,11 +315,8 @@ soup_address_get_physical (SoupAddress *addr)
if (!priv->sockaddr)
return NULL;
if (!priv->physical) {
priv->physical =
soup_dns_ntop (SOUP_ADDRESS_GET_DATA (priv),
SOUP_ADDRESS_GET_FAMILY (priv));
}
if (!priv->physical)
priv->physical = soup_dns_ntop (priv->sockaddr);
return priv->physical;
}
@@ -335,58 +338,23 @@ soup_address_get_port (SoupAddress *addr)
}
static guint
update_address_from_entry (SoupAddress *addr, SoupDNSEntry *entry)
{
SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
struct hostent *h;
h = soup_dns_entry_get_hostent (entry);
if (!h)
return SOUP_STATUS_CANT_RESOLVE;
if (!priv->name)
priv->name = g_strdup (h->h_name);
if (!priv->sockaddr &&
SOUP_ADDRESS_FAMILY_IS_VALID (h->h_addrtype) &&
SOUP_ADDRESS_FAMILY_DATA_SIZE (h->h_addrtype) == h->h_length) {
priv->sockaddr = g_malloc0 (SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (h->h_addrtype));
SOUP_ADDRESS_SET_FAMILY (priv, h->h_addrtype);
SOUP_ADDRESS_SET_PORT (priv, htons (priv->port));
SOUP_ADDRESS_SET_DATA (priv, h->h_addr, h->h_length);
}
soup_dns_free_hostent (h);
if (priv->name && priv->sockaddr)
return SOUP_STATUS_OK;
else
return SOUP_STATUS_CANT_RESOLVE;
}
static gboolean
timeout_check_lookup (gpointer user_data)
static void
update_address (SoupDNSLookup *lookup, gboolean success, gpointer user_data)
{
SoupAddress *addr = user_data;
SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
guint status;
if (priv->name && priv->sockaddr) {
priv->timeout_id = 0;
g_signal_emit (addr, signals[DNS_RESULT], 0, SOUP_STATUS_OK);
return FALSE;
if (success) {
if (!priv->name)
priv->name = soup_dns_lookup_get_hostname (lookup);
if (!priv->sockaddr) {
priv->sockaddr = soup_dns_lookup_get_address (lookup);
SOUP_ADDRESS_SET_PORT (priv, htons (priv->port));
}
}
if (!soup_dns_entry_check_lookup (priv->lookup))
return TRUE;
status = update_address_from_entry (addr, priv->lookup);
priv->lookup = NULL;
priv->timeout_id = 0;
g_signal_emit (addr, signals[DNS_RESULT], 0, status);
return FALSE;
g_signal_emit (addr, signals[DNS_RESULT], 0, success ? SOUP_STATUS_OK : SOUP_STATUS_CANT_RESOLVE);
}
/**
@@ -416,17 +384,7 @@ soup_address_resolve_async (SoupAddress *addr,
G_CALLBACK (callback), user_data);
}
if (priv->timeout_id)
return;
if (!priv->sockaddr) {
priv->lookup = soup_dns_entry_from_name (priv->name);
} else if (!priv->name) {
priv->lookup = soup_dns_entry_from_addr (SOUP_ADDRESS_GET_DATA (priv),
SOUP_ADDRESS_GET_FAMILY (priv));
}
priv->timeout_id = g_timeout_add (100, timeout_check_lookup, addr);
soup_dns_lookup_resolve_async (priv->lookup, update_address, addr);
}
/**
@@ -441,18 +399,13 @@ soup_address_resolve_async (SoupAddress *addr,
guint
soup_address_resolve_sync (SoupAddress *addr)
{
SoupDNSEntry *entry;
SoupAddressPrivate *priv;
gboolean success;
g_return_val_if_fail (SOUP_IS_ADDRESS (addr), SOUP_STATUS_MALFORMED);
priv = SOUP_ADDRESS_GET_PRIVATE (addr);
if (priv->name)
entry = soup_dns_entry_from_name (priv->name);
else {
entry = soup_dns_entry_from_addr (SOUP_ADDRESS_GET_DATA (priv),
SOUP_ADDRESS_GET_FAMILY (priv));
}
return update_address_from_entry (addr, entry);
success = soup_dns_lookup_resolve (priv->lookup);
update_address (priv->lookup, success, addr);
return success ? SOUP_STATUS_OK : SOUP_STATUS_CANT_RESOLVE;
}
+471 -637
View File
File diff suppressed because it is too large Load Diff
+19 -10
View File
@@ -11,19 +11,28 @@
#include <sys/socket.h>
#include <netdb.h>
typedef struct SoupDNSEntry SoupDNSEntry;
void soup_dns_init (void);
SoupDNSEntry *soup_dns_entry_from_name (const char *name);
SoupDNSEntry *soup_dns_entry_from_addr (gconstpointer addr,
int family);
typedef struct SoupDNSLookup SoupDNSLookup;
gboolean soup_dns_entry_check_lookup (SoupDNSEntry *entry);
void soup_dns_entry_cancel_lookup (SoupDNSEntry *entry);
SoupDNSLookup *soup_dns_lookup_name (const char *name);
SoupDNSLookup *soup_dns_lookup_address (struct sockaddr *address);
struct hostent *soup_dns_entry_get_hostent (SoupDNSEntry *entry);
void soup_dns_free_hostent (struct hostent *h);
typedef void (*SoupDNSCallback) (SoupDNSLookup *lookup, gboolean success, gpointer user_data);
gboolean soup_dns_lookup_resolve (SoupDNSLookup *lookup);
void soup_dns_lookup_resolve_async (SoupDNSLookup *lookup,
SoupDNSCallback callback,
gpointer user_data);
void soup_dns_lookup_cancel (SoupDNSLookup *lookup);
char *soup_dns_lookup_get_hostname (SoupDNSLookup *lookup);
struct sockaddr *soup_dns_lookup_get_address (SoupDNSLookup *lookup);
void soup_dns_lookup_free (SoupDNSLookup *lookup);
char *soup_dns_ntop (struct sockaddr *address);
char *soup_dns_ntop (gconstpointer addr,
int family);
#endif /* SOUP_DNS_H */
+24 -15
View File
@@ -5,25 +5,30 @@
#include "libsoup/soup-address.h"
GMainLoop *loop;
static GMainLoop *loop;
static int nlookups = 0;
static void
resolve_callback (SoupAddress *addr, guint status, gpointer data)
{
if (status != SOUP_STATUS_OK) {
fprintf (stderr, "%s\n", soup_status_get_phrase (status));
exit (1);
if (status == SOUP_STATUS_OK) {
printf ("Name: %s\n", soup_address_get_name (addr));
printf ("Address: %s\n", soup_address_get_physical (addr));
} else {
printf ("Name: %s\n", soup_address_get_name (addr));
printf ("Error: %s\n", soup_status_get_phrase (status));
}
printf ("\n");
printf ("Name: %s\n", soup_address_get_name (addr));
printf ("Address: %s\n", soup_address_get_physical (addr));
g_main_loop_quit (loop);
nlookups--;
if (nlookups == 0)
g_main_loop_quit (loop);
}
static void
usage (void)
{
fprintf (stderr, "Usage: dns [hostname | -r IP]\n");
fprintf (stderr, "Usage: dns hostname ...\n");
exit (1);
}
@@ -31,20 +36,24 @@ int
main (int argc, char **argv)
{
SoupAddress *addr;
int i;
if (argc != 2)
if (argc < 2)
usage ();
g_type_init ();
g_thread_init (NULL);
addr = soup_address_new (argv[1], 0);
if (!addr) {
fprintf (stderr, "Could not parse address %s\n", argv[1]);
exit (1);
}
for (i = 1; i < argc; i++) {
addr = soup_address_new (argv[i], 0);
if (!addr) {
fprintf (stderr, "Could not parse address %s\n", argv[1]);
exit (1);
}
soup_address_resolve_async (addr, resolve_callback, NULL);
soup_address_resolve_async (addr, resolve_callback, NULL);
nlookups++;
}
loop = g_main_loop_new (NULL, TRUE);
g_main_run (loop);