aboutsummaryrefslogtreecommitdiffstats
path: root/e-util/e-host-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'e-util/e-host-utils.c')
-rw-r--r--e-util/e-host-utils.c217
1 files changed, 140 insertions, 77 deletions
diff --git a/e-util/e-host-utils.c b/e-util/e-host-utils.c
index ab1b1cc0d6..1649d14ece 100644
--- a/e-util/e-host-utils.c
+++ b/e-util/e-host-utils.c
@@ -28,10 +28,85 @@
#include <stdio.h>
#include <errno.h>
-#ifndef HAVE_GETHOSTBYNAME_R
+#if !defined (HAVE_GETHOSTBYNAME_R) || !defined (HAVE_GETHOSTBYADDR_R)
G_LOCK_DEFINE_STATIC (gethost_mutex);
#endif
+
+#define GETHOST_PROCESS(h, host, buf, buflen, herr) G_STMT_START { \
+ int num_aliases = 0, num_addrs = 0; \
+ int req_length; \
+ char *p; \
+ int i; \
+ \
+ /* check to make sure we have enough room in our buffer */ \
+ req_length = 0; \
+ if (h->h_aliases) { \
+ for (i = 0; h->h_aliases[i]; i++) \
+ req_length += strlen (h->h_aliases[i]) + 1; \
+ num_aliases = i; \
+ } \
+ \
+ if (h->h_addr_list) { \
+ for (i = 0; h->h_addr_list[i]; i++) \
+ req_length += h->h_length; \
+ num_addrs = i; \
+ } \
+ \
+ req_length += sizeof (char *) * (num_aliases + 1); \
+ req_length += sizeof (char *) * (num_addrs + 1); \
+ req_length += strlen (h->h_name) + 1; \
+ \
+ if (buflen < req_length) { \
+ *herr = ERANGE; \
+ G_UNLOCK (gethost_mutex); \
+ return ERANGE; \
+ } \
+ \
+ /* we store the alias/addr pointers in the buffer */ \
+ /* their addresses here. */ \
+ p = buf; \
+ if (num_aliases) { \
+ host->h_aliases = (char **) p; \
+ p += sizeof (char *) * (num_aliases + 1); \
+ } else \
+ host->h_aliases = NULL; \
+ \
+ if (num_addrs) { \
+ host->h_addr_list = (char **) p; \
+ p += sizeof (char *) * (num_addrs + 1); \
+ } else \
+ host->h_addr_list = NULL; \
+ \
+ /* copy the host name into the buffer */ \
+ host->h_name = p; \
+ strcpy (p, h->h_name); \
+ p += strlen (h->h_name) + 1; \
+ host->h_addrtype = h->h_addrtype; \
+ host->h_length = h->h_length; \
+ \
+ /* copy the aliases/addresses into the buffer */ \
+ /* and assign pointers into the hostent */ \
+ *p = 0; \
+ if (num_aliases) { \
+ for (i = 0; i < num_aliases; i++) { \
+ strcpy (p, h->h_aliases[i]); \
+ host->h_aliases[i] = p; \
+ p += strlen (h->h_aliases[i]); \
+ } \
+ host->h_aliases[num_aliases] = NULL; \
+ } \
+ \
+ if (num_addrs) { \
+ for (i = 0; i < num_addrs; i++) { \
+ memcpy (p, h->h_addr_list[i], h->h_length); \
+ host->h_addr_list[i] = p; \
+ p += h->h_length; \
+ } \
+ host->h_addr_list[num_addrs] = NULL; \
+ } \
+} G_STMT_END
+
/**
* e_gethostbyname_r:
* @name: the host to resolve
@@ -48,109 +123,97 @@ G_LOCK_DEFINE_STATIC (gethost_mutex);
**/
int
e_gethostbyname_r (const char *name, struct hostent *host,
- char *buf, int buflen, int *herr)
+ char *buf, size_t buflen, int *herr)
{
#ifdef HAVE_GETHOSTBYNAME_R
#ifdef GETHOSTBYNAME_R_FIVE_ARGS
- if (gethostbyname_r(name, host, buf, buflen, herr))
+ if (gethostbyname_r (name, host, buf, buflen, herr))
return 0;
else
return errno;
#else
struct hostent *hp;
int retval;
-
- retval = gethostbyname_r(name, host, buf, buflen, &hp, herr);
+
+ retval = gethostbyname_r (name, host, buf, buflen, &hp, herr);
if (hp != NULL)
*herr = 0;
return retval;
#endif
#else
- int i;
- char *p;
struct hostent *h;
- int req_length;
- int num_aliases = 0, num_addrs = 0;
-
+
G_LOCK (gethost_mutex);
-
+
h = gethostbyname (name);
-
+
if (!h) {
*herr = h_errno;
G_UNLOCK (gethost_mutex);
return -1;
}
+
+ GETHOST_PROCESS (h, host,buf, buflen, herr);
+
+ G_UNLOCK (gethost_mutex);
+
+ return 0;
+#endif
+}
- /* check to make sure we have enough room in our buffer */
- req_length = 0;
- if (h->h_aliases) {
- for (i = 0; h->h_aliases[i]; i ++)
- req_length += strlen (h->h_aliases[i]) + 1;
- num_aliases = i;
- }
- if (h->h_addr_list) {
- for (i = 0; h->h_addr_list[i]; i ++)
- req_length += h->h_length;
- num_addrs = i;
- }
-
- req_length += sizeof (char*) * (num_aliases + 1);
- req_length += sizeof (char*) * (num_addrs + 1);
- req_length += strlen (h->h_name) + 1;
- if (buflen < req_length) {
- *herr = ERANGE;
- G_UNLOCK (gethost_mutex);
- return ERANGE;
- }
-
- /* we store the alias/addr pointers in the buffer - figure out
- their addresses here. */
- p = buf;
- if (num_aliases) {
- host->h_aliases = (char**)p;
- p += sizeof (char*) * (num_aliases + 1);
- }
- else
- host->h_aliases = NULL;
- if (num_addrs) {
- host->h_addr_list = (char**)p;
- p += sizeof(char*) * (num_addrs + 1);
- }
+/**
+ * e_gethostbyaddr_r:
+ * @addr: the addr to resolve
+ * @len: address length
+ * @type: AF type
+ * @host: a buffer pointing to a struct hostent to use for storage
+ * @buf: a buffer to use for hostname storage
+ * @buflen: the size of @buf
+ * @herr: a pointer to a variable to store an error code in
+ *
+ * Resolves the address @addr, in a hopefully-reentrant fashion.
+ *
+ * Return value: 0 on success, ERANGE if @buflen is too small,
+ * "something else" otherwise (in which case *@herr will be set to
+ * one of the gethostbyaddr() error codes).
+ **/
+int
+e_gethostbyaddr_r (const char *addr, int len, int type, struct hostent *host,
+ char *buf, size_t buflen, int *herr)
+{
+#ifdef HAVE_GETHOSTBYADDR_R
+#ifdef GETHOSTBYADDR_R_SEVEN_ARGS
+ if (gethostbyaddr_r (addr, len, type, host, buf, buflen, herr))
+ return 0;
else
- host->h_addr_list = NULL;
-
- /* copy the host name into the buffer */
- host->h_name = p;
- strcpy (p, h->h_name);
- p += strlen (h->h_name) + 1;
- host->h_addrtype = h->h_addrtype;
- host->h_length = h->h_length;
-
- /* copy the aliases/addresses into the buffer, and assign the
- pointers into the hostent */
- *p = 0;
- if (num_aliases) {
- for (i = 0; i < num_aliases; i ++) {
- strcpy (p, h->h_aliases[i]);
- host->h_aliases[i] = p;
- p += strlen (h->h_aliases[i]);
- }
- host->h_aliases[num_aliases] = NULL;
- }
-
- if (num_addrs) {
- for (i = 0; i < num_addrs; i ++) {
- memcpy (p, h->h_addr_list[i], h->h_length);
- host->h_addr_list[i] = p;
- p += h->h_length;
- }
- host->h_addr_list[num_addrs] = NULL;
+ return errno;
+#else
+ struct hostent *hp;
+ int retval;
+
+ retval = gethostbyaddr_r (addr, len, type, host, buf, buflen, &hp, herr);
+ if (hp != NULL)
+ *herr = 0;
+ return retval;
+#endif
+#else
+ struct hostent *h;
+
+ G_LOCK (gethost_mutex);
+
+ h = gethostbyaddr (addr, len, type);
+
+ if (!h) {
+ *herr = h_errno;
+ G_UNLOCK (gethost_mutex);
+ return -1;
}
-
+
+ GETHOST_PROCESS (h, host, buf, buflen, herr);
+
G_UNLOCK (gethost_mutex);
-
+
return 0;
#endif
}