mirror of
https://git.FreeBSD.org/ports.git
synced 2024-12-16 03:24:07 +00:00
1c274b738e
still some problems, at least with signal handling and locking on SMP. Submitted by: dick
166 lines
3.8 KiB
C
166 lines
3.8 KiB
C
#include "pthread.h"
|
|
#include <netdb.h>
|
|
#include <string.h>
|
|
|
|
#ifdef __sparc__
|
|
#define NEED_ALIGNED_ACCESS
|
|
#endif
|
|
|
|
static pthread_mutex_t gethostby_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
static int
|
|
convert (struct hostent *host, struct hostent *result,
|
|
char *buf, int buflen, int *h_errnop)
|
|
{
|
|
int len, i;
|
|
|
|
if (!buf || !h_errnop) return -1;
|
|
*h_errnop = h_errno;
|
|
|
|
*result = *host;
|
|
result->h_name = (char *) buf;
|
|
/* This is the size. */
|
|
len = strlen (host->h_name) + 1;
|
|
if (len > buflen) return -1;
|
|
buflen -= len;
|
|
buf += len;
|
|
strcpy ((char *) result->h_name, host->h_name);
|
|
|
|
/* How many aliases and how big the buffer should be? There
|
|
is always a NULL pointer. */
|
|
for (len = sizeof (char *), i = 0; host->h_aliases [i]; i++)
|
|
{
|
|
/* It should be size of (char *) and the length of string
|
|
plus 1. */
|
|
len += strlen (host->h_aliases [i]) + 1 + sizeof (char *);
|
|
}
|
|
if (len > buflen) return -1;
|
|
buflen -= len;
|
|
|
|
/* This is an array of char * for h_aliases. */
|
|
#ifdef NEED_ALIGNED_ACCESS
|
|
{
|
|
int extra;
|
|
extra = 4 - (((unsigned long) buf) & 3);
|
|
if (extra != 4) {
|
|
if (buflen < extra)
|
|
return -1;
|
|
buf = (char *) buf + extra;
|
|
}
|
|
}
|
|
#endif
|
|
result->h_aliases = (char **) buf;
|
|
buf += (i + 1) * sizeof (char *);
|
|
|
|
/* We copy the aliases now. */
|
|
for (i = 0; host->h_aliases [i]; i++)
|
|
{
|
|
result->h_aliases [i] = (char *) buf;
|
|
strcpy (result->h_aliases [i], host->h_aliases [i]);
|
|
buf += strlen (host->h_aliases [i]) + 1;
|
|
}
|
|
/* This is the last one */
|
|
result->h_aliases [i] = NULL;
|
|
|
|
#if BSD >= 43 || defined(h_addr)
|
|
for (len = sizeof (char *), i = 0; host->h_addr_list [i]; i++)
|
|
{
|
|
/* It should be size of (char *) and the length of string
|
|
plus 1. */
|
|
len += host->h_length + sizeof (char *);
|
|
}
|
|
if (len > buflen) return -1;
|
|
|
|
/* This is an array of char * for h_addr_list. */
|
|
#ifdef NEED_ALIGNED_ACCESS
|
|
{
|
|
int extra;
|
|
extra = 4 - (((unsigned long) buf) & 0x3);
|
|
if (extra != 4) {
|
|
if (buflen < extra)
|
|
return -1;
|
|
buf = ((char *) buf) + extra;
|
|
}
|
|
}
|
|
#endif
|
|
result->h_addr_list = (char **) buf;
|
|
buf += (i + 1) * sizeof (char *);
|
|
|
|
/* We copy the h_addr_list now. */
|
|
for (i = 0; host->h_addr_list [i]; i++)
|
|
{
|
|
result->h_addr_list [i] = (char *) buf;
|
|
memcpy (result->h_addr_list [i], host->h_addr_list [i], host->h_length);
|
|
buf += host->h_length;
|
|
}
|
|
/* This is the last one */
|
|
result->h_addr_list [i] = NULL;
|
|
#else
|
|
len = strlen (host->h_addr) + 1 + sizeof (char *);
|
|
if (len > buflen) return -1;
|
|
|
|
result->h_addr = (char *) buf;
|
|
strcpy (result->h_addr, host->h_addr);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
struct hostent *
|
|
gethostbyaddr_r (const char *addr, int length, int type,
|
|
struct hostent *result, char *buffer, int buflen,
|
|
int *h_errnop)
|
|
{
|
|
struct hostent *host;
|
|
|
|
pthread_mutex_lock (&gethostby_mutex);
|
|
|
|
host = gethostbyaddr (addr, length, type);
|
|
if (!host ||
|
|
convert (host, result, buffer, buflen, h_errnop) != 0)
|
|
{
|
|
result = NULL;
|
|
}
|
|
|
|
pthread_mutex_unlock (&gethostby_mutex);
|
|
return result;
|
|
}
|
|
|
|
struct hostent *
|
|
gethostbyname_r (const char *name,
|
|
struct hostent *result, char *buffer, int buflen,
|
|
int *h_errnop)
|
|
{
|
|
struct hostent *host;
|
|
|
|
pthread_mutex_lock (&gethostby_mutex);
|
|
|
|
host = gethostbyname (name);
|
|
if (!host ||
|
|
convert (host, result, buffer, buflen, h_errnop) != 0)
|
|
{
|
|
result = NULL;
|
|
}
|
|
|
|
pthread_mutex_unlock (&gethostby_mutex);
|
|
return result;
|
|
}
|
|
|
|
struct hostent *
|
|
gethostent_r (struct hostent *result, char *buffer, int buflen,
|
|
int *h_errnop)
|
|
{
|
|
struct hostent *host;
|
|
|
|
pthread_mutex_lock (&gethostby_mutex);
|
|
|
|
host = gethostent ();
|
|
if (!host ||
|
|
convert (host, result, buffer, buflen, h_errnop) != 0)
|
|
{
|
|
result = NULL;
|
|
}
|
|
|
|
pthread_mutex_unlock (&gethostby_mutex);
|
|
return result;
|
|
}
|