From 7d896ab1bbd5e15be7ae9203ead47f4f500a6a81 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 4 Aug 1998 22:16:43 +0000 Subject: Added gethostbyname_ex(), which returns the same kind of data as gethostbyaddr(). (Plain gethostbyname() returns only the IP address.) This moves the code shared by gethostbyaddr() and gethostbyname_ex() to a subroutine. Original patch by Dan Stromberg; some tweaks by GvR. --- Modules/socketmodule.c | 136 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 99 insertions(+), 37 deletions(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 0eb3fd5..58b2c98 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1314,49 +1314,18 @@ static char gethostbyname_doc[] = Return the IP address (a string of the form '255.255.255.255') for a host."; -/* Python interface to gethostbyaddr(IP). */ +/* Convenience function common to gethostbyname_ex and gethostbyaddr */ -/*ARGSUSED*/ static PyObject * -BUILD_FUNC_DEF_2(PySocket_gethostbyaddr,PyObject *,self, PyObject *, args) -{ - struct sockaddr_in addr; - char *ip_num; +gethost_common(h, addr) struct hostent *h; + struct sockaddr_in *addr; +{ char **pch; PyObject *rtn_tuple = (PyObject *)NULL; PyObject *name_list = (PyObject *)NULL; PyObject *addr_list = (PyObject *)NULL; PyObject *tmp; -#ifdef HAVE_GETHOSTBYNAME_R - struct hostent hp_allocated; - char buf[16384]; - int buf_len = (sizeof buf) - 1; - int errnop; -#endif /* HAVE_GETHOSTBYNAME_R */ - - if (!PyArg_Parse(args, "s", &ip_num)) - return NULL; - if (setipaddr(ip_num, &addr) < 0) - return NULL; - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_GETHOSTBYNAME_R - h = gethostbyaddr_r((char *)&addr.sin_addr, - sizeof(addr.sin_addr), - AF_INET, - &hp_allocated, buf, buf_len, &errnop); -#else /* not HAVE_GETHOSTBYNAME_R */ -#if defined(WITH_THREAD) && !defined(MS_WINDOWS) - acquire_lock(gethostbyname_lock,1); -#endif - h = gethostbyaddr((char *)&addr.sin_addr, - sizeof(addr.sin_addr), - AF_INET); -#if defined(WITH_THREAD) && !defined(MS_WINDOWS) - release_lock(gethostbyname_lock); -#endif -#endif /* HAVE_GETHOSTBYNAME_R */ - Py_END_ALLOW_THREADS if (h == NULL) { #ifdef HAVE_HSTRERROR /* Let's get real error message to return */ @@ -1383,8 +1352,8 @@ BUILD_FUNC_DEF_2(PySocket_gethostbyaddr,PyObject *,self, PyObject *, args) } for (pch = h->h_addr_list; *pch != NULL; pch++) { int status; - memcpy((char *) &addr.sin_addr, *pch, h->h_length); - tmp = makeipaddr(&addr); + memcpy((char *) &addr->sin_addr, *pch, h->h_length); + tmp = makeipaddr(addr); if (tmp == NULL) goto err; status = PyList_Append(addr_list, tmp); @@ -1399,6 +1368,98 @@ BUILD_FUNC_DEF_2(PySocket_gethostbyaddr,PyObject *,self, PyObject *, args) return rtn_tuple; } + +/* Python interface to gethostbyname_ex(name). */ + +/*ARGSUSED*/ +static PyObject * +BUILD_FUNC_DEF_2(PySocket_gethostbyname_ex,PyObject *,self, PyObject *,args) +{ + char *name; + struct hostent *h; + struct sockaddr_in addr; + PyObject *addr_list = (PyObject *)NULL; + char **pch; + PyObject *tmp; +#ifdef HAVE_GETHOSTBYNAME_R + struct hostent hp_allocated; + char buf[16384]; + int buf_len = (sizeof buf) - 1; + int errnop; +#endif /* HAVE_GETHOSTBYNAME_R */ + if (!PyArg_Parse(args, "s", &name)) + return NULL; + if (setipaddr(name, &addr) < 0) + return NULL; + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_GETHOSTBYNAME_R + h = gethostbyname_r(name, &hp_allocated, buf, buf_len, &errnop); +#else /* not HAVE_GETHOSTBYNAME_R */ +#if defined(WITH_THREAD) && !defined(MS_WINDOWS) + acquire_lock(gethostbyname_lock,1); +#endif + h = gethostbyname(name); +#if defined(WITH_THREAD) && !defined(MS_WINDOWS) + release_lock(gethostbyname_lock); +#endif +#endif /* HAVE_GETHOSTBYNAME_R */ + Py_END_ALLOW_THREADS + return gethost_common(h,&addr); +} + +static char ghbn_ex_doc[] = +"gethostbyname_ex(host) -> (name, aliaslist, addresslist)\n\ +\n\ +Return the true host name, a list of aliases, and a list of IP addresses,\n\ +for a host. The host argument is a string giving a host name or IP number."; + + +/* Python interface to gethostbyaddr(IP). */ + +/*ARGSUSED*/ +static PyObject * +BUILD_FUNC_DEF_2(PySocket_gethostbyaddr,PyObject *,self, PyObject *, args) +{ + struct sockaddr_in addr; + char *ip_num; + struct hostent *h; + char **pch; + PyObject *rtn_tuple = (PyObject *)NULL; + PyObject *name_list = (PyObject *)NULL; + PyObject *addr_list = (PyObject *)NULL; + PyObject *tmp; +#ifdef HAVE_GETHOSTBYNAME_R + struct hostent hp_allocated; + char buf[16384]; + int buf_len = (sizeof buf) - 1; + int errnop; +#endif /* HAVE_GETHOSTBYNAME_R */ + + if (!PyArg_Parse(args, "s", &ip_num)) + return NULL; + if (setipaddr(ip_num, &addr) < 0) + return NULL; + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_GETHOSTBYNAME_R + h = gethostbyaddr_r((char *)&addr.sin_addr, + sizeof(addr.sin_addr), + AF_INET, + &hp_allocated, buf, buf_len, &errnop); +#else /* not HAVE_GETHOSTBYNAME_R */ +#if defined(WITH_THREAD) && !defined(MS_WINDOWS) + acquire_lock(gethostbyname_lock,1); +#endif + h = gethostbyaddr((char *)&addr.sin_addr, + sizeof(addr.sin_addr), + AF_INET); +#if defined(WITH_THREAD) && !defined(MS_WINDOWS) + release_lock(gethostbyname_lock); +#endif +#endif /* HAVE_GETHOSTBYNAME_R */ + Py_END_ALLOW_THREADS + return gethost_common(h,&addr); +} + static char gethostbyaddr_doc[] = "gethostbyaddr(host) -> (name, aliaslist, addresslist)\n\ \n\ @@ -1623,6 +1684,7 @@ Convert a 32-bit integer from host to network byte order."; static PyMethodDef PySocket_methods[] = { {"gethostbyname", PySocket_gethostbyname, 0, gethostbyname_doc}, + {"gethostbyname_ex", PySocket_gethostbyname_ex, 0, ghbn_ex_doc}, {"gethostbyaddr", PySocket_gethostbyaddr, 0, gethostbyaddr_doc}, {"gethostname", PySocket_gethostname, 0, gethostname_doc}, {"getservbyname", PySocket_getservbyname, 0, getservbyname_doc}, -- cgit v0.12