]> git.lizzy.rs Git - plan9front.git/blob - sys/src/ape/lib/bsd/getnameinfo.c
ape: Add mkstemp to /sys/src/ape/lib/ap/gen/mkfile
[plan9front.git] / sys / src / ape / lib / bsd / getnameinfo.c
1 /* posix */
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <fcntl.h>
7 #include <string.h>
8 #include <errno.h>
9
10 /* bsd extensions */
11 #include <sys/uio.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <netdb.h>
15
16 #include "priv.h"
17
18 static int
19 netquery(char *buf, int nbuf)
20 {
21         int fd, i, n;
22
23         if((fd = open("/net/cs", O_RDWR)) < 0)
24                 return EAI_SYSTEM;
25         n = strlen(buf);
26         if(write(fd, buf, n) != n){
27                 close(fd);
28                 return EAI_NONAME;
29         }
30         lseek(fd, 0, 0);
31         for(i = 0; i < nbuf-1; i += n){
32                 n = read(fd, buf+i, nbuf - 1 - i);
33                 if(n <= 0)
34                         break;
35                 buf[i+n++] = ' ';
36         }
37         close(fd);
38         buf[i] = 0;
39         return i;
40 }
41
42 int
43 getnameinfo(struct sockaddr *sa, int salen,
44         char *host, int hostlen,
45         char *serv, int servlen,
46         unsigned int flags)
47 {
48         char buf[8*1024], *b, *p;
49         int err;
50
51         if(sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
52                 return EAI_FAMILY;
53
54         if(host != 0 && hostlen > 0){
55                 if(inet_ntop(sa->sa_family, _sock_inip(sa), host, hostlen) == 0)
56                         return EAI_SYSTEM;
57
58                 if((flags & NI_NUMERICHOST) == 0){
59                         snprintf(buf, sizeof(buf), "!ip=%s", host);
60                         if((err = netquery(buf, sizeof(buf))) < 0){
61                                 if((flags & NI_NAMEREQD) != 0)
62                                         return err;
63                         } else {
64                                 char *sys, *dom;
65
66                                 sys = dom = 0;
67                                 for(b = buf;;){
68                                         if((p = strchr(b, '=')) == 0)
69                                                 break;
70                                         *p++ = 0;
71                                         if(strcmp(b, "sys") == 0)
72                                                 sys = p;
73                                         else if(strcmp(b, "dom") == 0)
74                                                 dom = p;
75                                         while(*p && *p != ' ')
76                                                 p++;
77                                         while(*p == ' ')
78                                                 *p++ = 0;
79                                         b = p;
80                                 }
81                                 if(sys == 0){
82                                         if(dom == 0 && (flags & NI_NAMEREQD) != 0)
83                                                 return EAI_NONAME;
84                                         if(dom != 0 && (flags & NI_NOFQDN) != 0){
85                                                 if((p = strchr(dom, '.')) != 0)
86                                                         *p = 0;
87                                         }
88                                         sys = dom;
89                                 }
90                                 snprintf(host, hostlen, "%s", sys);
91                         }
92                 }
93         }
94
95         if(serv != 0 && servlen > 0){
96                 snprintf(serv, servlen, "%d", _sock_inport(sa));
97                 if((flags & NI_NUMERICSERV) == 0){
98                         snprintf(buf, sizeof(buf), "!port=%s", serv);
99                         if(netquery(buf, sizeof(buf)) > 0){
100                                 char *tcp, *udp;
101
102                                 tcp = udp = 0;
103                                 for(b = buf;;){
104                                         if((p = strchr(b, '=')) == 0)
105                                                 break;
106                                         *p++ = 0;
107                                         if(strcmp(b, "tcp") == 0)
108                                                 tcp = p;
109                                         else if(strcmp(b, "udp") == 0)
110                                                 udp = p;
111                                         while(*p && *p != ' ')
112                                                 p++;
113                                         while(*p == ' ')
114                                                 *p++ = 0;
115                                         b = p;
116                                 }
117                                 if(udp != 0 && (flags & NI_DGRAM) != 0)
118                                         snprintf(serv, servlen, "%s", udp);
119                                 else if(tcp != 0)
120                                         snprintf(serv, servlen, "%s", tcp);
121                         }
122                 }
123         }
124
125         return 0;
126 }