/*
* Copyright 1988 by Rayan S. Zachariassen, all rights reserved.
* This will be free software, but only when it is finished.
*/
/*
* Perhaps a single interface to discovering the real system name.
*/
#include "hostenv.h"
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if defined(HAVE_RESOLVER)
#include <netdb.h>
#if !defined(EAI_AGAIN) || !defined(AI_NUMERICHOST)
# include "netdb6.h"
#endif
#include <netinet/in.h>
#endif
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>
#endif
#include "libc.h"
static int
_getmyhostname(namebuf, len)
char *namebuf;
int len;
{
#ifdef HAVE_GETADDRINFO
/* VARIANT WITH getaddrinfo() IN ITS LIBC REQUIREMENTS */
struct addrinfo req, *ai;
int i, rc;
#ifdef HAVE_SYS_UTSNAME_H
struct utsname id;
extern int uname();
if (uname(&id) < 0)
return -1;
strncpy(namebuf, id.nodename, len);
namebuf[len - 1] = 0;
#else /* !HAVE_SYS_UTSNAME_H */
extern int gethostname();
if (gethostname(namebuf, len) < 0)
return -1;
#endif /* USE_UNAME */
ai = NULL;
memset(&req, 0, sizeof(req));
req.ai_socktype = SOCK_STREAM;
req.ai_protocol = IPPROTO_TCP;
req.ai_flags = AI_CANONNAME;
req.ai_family = 0;
for (i = 0; i < 5; ++i) {
rc = getaddrinfo(namebuf, "0", &req, &ai);
if (rc != EAI_AGAIN)
break; /* We try it again if we fail here with EAI_AGAIN */
}
if (ai != NULL) {
if (ai->ai_canonname)
strncpy(namebuf, ai->ai_canonname, len);
namebuf[len-1] = 0;
freeaddrinfo(ai);
}
#if 0
/* enable this code if for some reason your PTR name is primary */
{ /* XXX:XXX:XXX: FIX TO USE GETNAMEINFO() CALL! */
struct in_addr hpaddr;
if (hp != NULL)
memcpy(&hpaddr,hp->h_addr,hp->h_length);
if (hp != NULL
&& (hp = gethostbyaddr((void*)&hpaddr, hp->h_length,
hp->h_addrtype)) != NULL) {
strcpy(namebuf,hp->h_name);
} else
return 0; /* Hmm.. Didn't quite knack it ? */
}
#endif
return 0;
#else /* NOT HAVE_GETADDRINFO */
/* VARIANT WITHOUT getaddrinfo() IN ITS LIBC REQUIREMENTS */
struct hostent *hp;
int i, rc;
#ifdef HAVE_SYS_UTSNAME_H
struct utsname id;
extern int uname();
if (uname(&id) < 0)
return -1;
strncpy(namebuf, id.nodename, len);
namebuf[len - 1] = 0;
#else /* !HAVE_SYS_UTSNAME_H */
extern int gethostname();
if (gethostname(namebuf, len) < 0)
return -1;
#endif /* USE_UNAME */
for (i = 0; i < 5; ++i) {
hp = gethostbyname(namebuf);
if (hp)
break; /* We try it again if we fail here with EAI_AGAIN */
}
if (hp) {
if (hp->h_name)
strncpy(namebuf, hp->h_name, len);
namebuf[len-1] = 0;
}
#if 0
/* enable this code if for some reason your PTR name is primary */
{ /* XXX:XXX:XXX: FIX TO USE GETNAMEINFO() CALL! */
struct in_addr hpaddr;
if (hp != NULL)
memcpy(&hpaddr,hp->h_addr,hp->h_length);
if (hp != NULL
&& (hp = gethostbyaddr((void*)&hpaddr, hp->h_length,
hp->h_addrtype)) != NULL) {
strcpy(namebuf,hp->h_name);
} else
return 0; /* Hmm.. Didn't quite knack it ? */
}
#endif
return 0;
#endif
}
int
getmyhostname(namebuf, len)
char *namebuf;
int len;
{
int rc;
static char *savedname=NULL;
if (savedname) {
strncpy(namebuf, savedname, len);
namebuf[len - 1] = 0;
return 0;
}
rc = _getmyhostname(namebuf, len);
if (rc == 0) {
savedname=(char*)malloc(strlen(namebuf)+1);
strcpy(savedname, namebuf);
}
return rc;
}
syntax highlighted by Code2HTML, v. 0.9.1