fix nftw FTW_MOUNT flag
[musl] / src / network / getnameinfo.c
1 #include <netdb.h>
2 #include <limits.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <sys/socket.h>
6 #include <netinet/in.h>
7 #include <arpa/inet.h>
8 #include "__dns.h"
9
10 int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
11         char *restrict node, socklen_t nodelen,
12         char *restrict serv, socklen_t servlen,
13         int flags)
14 {
15         char buf[256];
16         unsigned char reply[512];
17         int af = sa->sa_family;
18         unsigned char *a;
19
20         switch (af) {
21         case AF_INET:
22                 a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
23                 if (sl != sizeof(struct sockaddr_in)) return EAI_FAMILY;
24                 break;
25         case AF_INET6:
26                 a = (void *)&((struct sockaddr_in6 *)sa)->sin6_addr;
27                 if (sl != sizeof(struct sockaddr_in6)) return EAI_FAMILY;
28                 break;
29         default:
30                 return EAI_FAMILY;
31         }
32
33         if (node && nodelen) {
34                 if ((flags & NI_NUMERICHOST)
35                         || __dns_query(reply, a, af, 1) <= 0
36                         || __dns_get_rr(buf, 0, 256, 1, reply, RR_PTR, 1) <= 0)
37                 {
38                         if (flags & NI_NAMEREQD) return EAI_NONAME;
39                         inet_ntop(af, a, buf, sizeof buf);
40                 }
41                 if (strlen(buf) >= nodelen) return EAI_OVERFLOW;
42                 strcpy(node, buf);
43         }
44
45         if (serv && servlen) {
46                 if (snprintf(buf, sizeof buf, "%d",
47                         ntohs(((struct sockaddr_in *)sa)->sin_port))>=servlen)
48                         return EAI_OVERFLOW;
49                 strcpy(serv, buf);
50         }
51
52         return 0;
53 }