summaryrefslogtreecommitdiffstats
path: root/src/util/pty/sane_hostname.c
blob: 3f9ed6b64eb527b43b1de4f35f66b91797da2438 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * pty_make_sane_hostname: Make a sane hostname from an IP address.
 * This returns allocated memory!
 * 
 * Copyright 1999 by the Massachusetts Institute of Technology.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby
 * granted, provided that the above copyright notice appear in all
 * copies and that both that copyright notice and this permission
 * notice appear in supporting documentation, and that the name of
 * M.I.T. not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior
 * permission.  M.I.T. makes no representations about the suitability
 * of this software for any purpose.  It is provided "as is" without
 * express or implied warranty.
 * 
 */
#include <com_err.h>
#include "pty-int.h"
#include "libpty.h"
#include <arpa/inet.h>

static long
do_ntoa(struct sockaddr_in *addr,
		     size_t hostlen,
		     char **out)
{
    strncpy(*out, inet_ntoa(addr->sin_addr), hostlen);
    (*out)[hostlen - 1] = '\0';
    return 0;
}

long
pty_make_sane_hostname(struct sockaddr_in *addr,
		       int maxlen,
		       int strip_ldomain,
		       int always_ipaddr,
		       char **out)
{
    struct hostent *hp;
#ifndef NO_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)
	/* assume they meant 16, otherwise IP addr won't fit */
	maxlen = 16;
#ifndef NO_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) {
	return do_ntoa(addr, ut_host_len, out);
    }
    hp = gethostbyaddr((char *)&addr->sin_addr, sizeof (struct in_addr),
		       addr->sin_family);
    if (hp == NULL) {
	return do_ntoa(addr, ut_host_len, out);
    }
    strncpy(*out, hp->h_name, ut_host_len);
    (*out)[ut_host_len - 1] = '\0';
    for (cp = *out; *cp != '\0'; cp++)
	*cp = tolower(*cp);

    if (strip_ldomain) {
	(void) gethostname(lhost, sizeof (lhost));
	hp = gethostbyname(lhost);
	if (hp != NULL) {
	    strncpy(lhost, hp->h_name, sizeof (lhost));
	    domain = strchr(lhost, '.');
	    if (domain != NULL) {
		for (cp = domain; *cp != '\0'; cp++)
		    *cp = tolower(*cp);
		cp = strstr(*out, domain);
		if (cp != NULL)
		    *cp = '\0';
	    }
	}
    }

    if (strlen(*out) >= maxlen) {
	return do_ntoa(addr, ut_host_len, out);
    }
    return 0;
}