#endif
#if !defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
-extern int gettimeofday(struct timeval * tv, struct timezone * tz)
+int gettimeofday(struct timeval * tv, struct timezone * tz)
{
if (!tv)
{
}
#endif
-#ifndef HAVE_GETLOCALTIME_R
-extern struct tm *localtime_r(const time_t *timep, struct tm *result)
+#if !defined(HAVE_GETLOCALTIME_R) && defined(HAVE_LOCALTIME)
+struct tm *localtime_r(const time_t *timep, struct tm *result)
{
memcpy(result, localtime(timep), sizeof(*result));
return result;
#endif
#ifndef HAVE_MEMCPY
-extern void * memcpy(void * dest, void const * src, unsigned long n)
+void * memcpy(void * dest, void const * src, unsigned long n)
{
/* very slow, your fault for not having memcpy()*/
unsigned char * td=dest;
#ifndef HAVE_MEMSET
/* very slow, deal with it */
-extern void * memset(void * dest, int c, unsigned long n)
+void * memset(void * dest, int c, unsigned long n)
{
unsigned char * temp=dest;
unsigned long i;
#endif
#ifndef HAVE_STRDUP
-extern char * strdup(char const * str)
+char * strdup(char const * str)
{
char * out;
#endif
#ifndef HAVE_STRERROR
-extern char const * strerror(int errornum)
+char const * strerror(int errornum)
{
if (errornum==0)
return "No error";
struct sockaddr_in sin;
if (hints && hints->ai_family != AF_INET)
- return 1;
+ return EAI_FAMILY;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
if (hints && hints->ai_flags & AI_NUMERICHOST) {
#if HAVE_INET_ATON
if (!inet_aton(node, &sin.sin_addr))
- return 2;
+ return EAI_NONAME;
#else
sin.sin_addr.s_addr = inet_addr(node);
if (sin.sin_addr.s_addr == INADDR_NONE)
- return 2;
+ return EAI_NONAME;
#endif
} else {
struct hostent *he;
he = gethostbyname(node);
if (!he)
- return 3;
+ return EAI_NONAME;
memcpy(&sin.sin_addr, he->h_addr, he->h_length);
}
} else if (hints && hints->ai_flags & AI_PASSIVE) {
if (!service)
sin.sin_port = ntohs(0);
else if (!(sin.sin_port = ntohs(atoi(service))))
- return 4;
+ return EAI_NONAME;
*res = calloc(1, sizeof(**res) + sizeof(sin));
(*res)->ai_family = sin.sin_family;
return 0;
}
-/* TODO: implement fallback getnameinfo() */
-
void freeaddrinfo(struct addrinfo *res)
{
struct addrinfo *next;
free(res);
}
}
-
#endif
#ifndef HAVE_GAI_STRERROR
return "Unknown GAI_* error";
}
#endif
+
+#ifndef HAVE_GETNAMEINFO
+int getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen, int flags)
+{
+ if (sa->sa_family == AF_INET) {
+ const struct sockaddr_in *sin;
+ int tmp;
+
+ /* This comparison is a bit screwy looking, but socklen_t is
+ * signed on some platforms and unsigned on others, so gcc
+ * will complain if we use "salen < 0".
+ */
+ if (salen < 1 || (size_t)salen < sizeof(*sin))
+ return EAI_FAMILY;
+ sin = (const struct sockaddr_in *)sa;
+ tmp = snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
+ if (tmp < 1 || (size_t)tmp >= servlen)
+ return EAI_OVERFLOW;
+ if (0 == (flags & NI_NUMERICHOST)) {
+ struct hostent *he;
+
+ /* Try to get host entry by address.
+ * The first argument should be void *, but Cygwin is
+ * apparently wandering around the pre-C89 era.
+ */
+ he = gethostbyaddr((const char*)&sin->sin_addr, sa->sa_family, SOCK_STREAM);
+ if (he != NULL) {
+ if (servlen <= strlen(he->h_name))
+ return EAI_OVERFLOW;
+ safestrncpy(serv, he->h_name, servlen);
+ return 0;
+ }
+
+ /* If we couldn't, why did we fail, and what should we do? */
+ switch (h_errno) {
+ case NO_RECOVERY:
+ return EAI_FAIL;
+ case TRY_AGAIN:
+ return EAI_AGAIN;
+ default:
+ /* Fall through and out to inet_ntop() path. */
+ break;
+ }
+ }
+
+ /* Try to get numeric representation of address. */
+ if (inet_ntop(sa->sa_family, &sin->sin_addr, host, hostlen) != NULL)
+ return 0;
+ else if (errno == ENOSPC)
+ return EAI_OVERFLOW;
+ else
+ return EAI_FAIL;
+ }
+ else
+ return EAI_FAMILY;
+}
+#endif