10 static size_t first_component_len(const char *s
)
12 const char *first
= s
;
14 /* find the first dot or end of string */
15 while (*s
&& *s
!= '.')
22 static int getnameinfo_get_host(const struct sockaddr_in
*sockaddr
,
23 char *node
, socklen_t nodelen
, int flags
)
25 struct hostent
*hostent
;
29 if ((flags
& NI_NUMERICHOST
) != NI_NUMERICHOST
)
31 hostent
= gethostbyaddr(
32 (char *) &sockaddr
->sin_addr
,
33 sizeof(sockaddr
->sin_addr
),
36 if (hostent
&& hostent
->h_name
)
38 /* return the hostname that was found */
39 if (nodelen
<= strlen(hostent
->h_name
))
42 strcpy(node
, hostent
->h_name
);
47 if ((flags
& NI_NAMEREQD
) == NI_NAMEREQD
)
50 /* basic implementation to provide numeric values */
51 ipaddr
= inet_ntoa(sockaddr
->sin_addr
);
52 if (nodelen
<= strlen(ipaddr
))
59 static int getnameinfo_get_serv(const struct sockaddr_in
*sockaddr
,
60 char *service
, socklen_t servicelen
, int flags
)
62 struct servent
*servent
;
66 if ((flags
& NI_NUMERICSERV
) != NI_NUMERICSERV
)
68 servent
= getservbyport(sockaddr
->sin_port
,
69 ((flags
& NI_DGRAM
) == NI_DGRAM
) ? "udp" : "tcp");
70 if (servent
&& servent
->s_name
)
72 /* return the service name that was found */
73 if (strlen(servent
->s_name
) >= servicelen
)
76 strcpy(service
, servent
->s_name
);
81 /* return port number */
82 port
= ntohs(sockaddr
->sin_port
);
83 if (snprintf(service
, servicelen
, "%u", port
) >= servicelen
)
90 * getnameinfo is based on
91 * http://www.opengroup.org/onlinepubs/009695399/functions/getnameinfo.html
93 int getnameinfo(const struct sockaddr
*sa
, socklen_t salen
,
94 char *node
, socklen_t nodelen
, char *service
,
95 socklen_t servicelen
, int flags
)
98 const struct sockaddr_in
*sockaddr
;
101 * The following flags are really supported:
107 * The following flag is not supported:
110 * The following flags could have been supported but is not implemented:
114 /* check for invalid parameters; only support IPv4 */
121 if (sa
->sa_family
!= AF_INET
|| salen
!= sizeof(struct sockaddr_in
))
124 if (flags
& ~(NI_NUMERICHOST
| NI_NAMEREQD
| NI_NUMERICSERV
| NI_DGRAM
))
127 if ((!node
|| !nodelen
) && (!service
|| !servicelen
))
131 sockaddr
= (const struct sockaddr_in
*) sa
;
132 if (node
&& nodelen
> 0)
134 r
= getnameinfo_get_host(sockaddr
, node
, nodelen
, flags
);
139 /* look up service */
140 if (service
&& servicelen
> 0)
142 r
= getnameinfo_get_serv(sockaddr
, service
, servicelen
, flags
);