#include "com_err.h"
#include "pty-int.h"
#include <sys/socket.h>
#include "libpty.h"
#include <arpa/inet.h>
#include "socket-utils.h"
#include "fake-addrinfo.h"
static void
downcase (char *s)
{
for (; *s != '\0'; s++)
*s = tolower ((int) *s);
}
long
pty_make_sane_hostname(const struct sockaddr *addr, int maxlen,
int strip_ldomain, int always_ipaddr, char **out)
{
struct addrinfo *ai = 0;
char addrbuf[NI_MAXHOST];
#ifdef HAVE_STRUCT_UTMP_UT_HOST
struct utmp ut;
#else
struct utmpx utx;
#endif
char *cp, *domain;
char lhost[MAXHOSTNAMELEN];
size_t ut_host_len;
*out = NULL;
if (maxlen && maxlen < 16)
maxlen = 16;
#ifdef HAVE_STRUCT_UTMP_UT_HOST
ut_host_len = sizeof (ut.ut_host);
#else
ut_host_len = sizeof (utx.ut_host);
#endif
if (maxlen == 0)
maxlen = ut_host_len;
*out = malloc(ut_host_len);
if (*out == NULL)
return ENOMEM;
if (always_ipaddr) {
use_ipaddr:
if (getnameinfo (addr, socklen (addr), addrbuf, sizeof (addrbuf),
(char *)0, 0, NI_NUMERICHOST) == 0)
strncpy(*out, addrbuf, ut_host_len);
else
strncpy(*out, "??", ut_host_len);
(*out)[ut_host_len - 1] = '\0';
return 0;
}
if (getnameinfo(addr, socklen (addr), addrbuf, sizeof (addrbuf),
(char *) NULL, 0, NI_NAMEREQD) != 0)
goto use_ipaddr;
downcase (addrbuf);
if (strip_ldomain) {
struct addrinfo hints;
(void) gethostname(lhost, sizeof (lhost));
memset (&hints, 0, sizeof (hints));
hints.ai_family = PF_UNSPEC;
hints.ai_flags = AI_CANONNAME;
if (getaddrinfo(lhost, (char *)NULL, &hints, &ai) == 0
&& ai != NULL) {
if (ai->ai_canonname != NULL) {
downcase (ai->ai_canonname);
domain = strchr (ai->ai_canonname, '.');
if (domain != NULL) {
cp = strstr (addrbuf, domain);
if (cp != NULL)
*cp = '\0';
}
}
freeaddrinfo (ai);
}
}
strncpy(*out, addrbuf, ut_host_len);
(*out)[ut_host_len - 1] = '\0';
if (strlen(*out) >= maxlen)
goto use_ipaddr;
return 0;
}