PCI: adds device-specific data pointer
[akaros.git] / user / bsd / gethostbyname.c
1 /* 
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9 /* posix */
10 #include <sys/types.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <fcntl.h>
15 #include <string.h>
16 #include <errno.h>
17
18 /* bsd extensions */
19 #include <sys/uio.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <netdb.h>
23 #include <arpa/inet.h>
24
25 #include "priv.h"
26
27 int h_errno;
28
29 enum
30 {
31         Nname= 6,
32 };
33
34 /*
35  *  for inet addresses only
36  */
37 struct hostent*
38 gethostbyname(const char *name)
39 {
40         int i, t, fd, m;
41         char *p, *bp;
42         int nn, na;
43         unsigned long x;
44         static struct hostent h;
45         static char buf[1024];
46         static char *nptr[Nname+1];
47         static char *aptr[Nname+1];
48         static char addr[Nname][4];
49
50         h.h_name = 0;
51         t = _sock_ipattr(name);
52
53         /* connect to server */
54         fd = open("/net/cs", O_RDWR);
55         if(fd < 0){
56                 h_errno = NO_RECOVERY;
57                 return 0;
58         }
59
60         /* construct the query, always expect an ip# back */
61         switch(t){
62         case Tsys:
63                 snprintf(buf, sizeof buf, "!sys=%s ip=*", name);
64                 break;
65         case Tdom:
66                 snprintf(buf, sizeof buf, "!dom=%s ip=*", name);
67                 break;
68         case Tip:
69                 snprintf(buf, sizeof buf, "!ip=%s", name);
70                 break;
71         }
72
73         /* query the server */
74         if(write(fd, buf, strlen(buf)) < 0){
75                 h_errno = TRY_AGAIN;
76                 return 0;
77         }
78         lseek(fd, 0, 0);
79         for(i = 0; i < sizeof(buf)-1; i += m){
80                 m = read(fd, buf+i, sizeof(buf) - 1 - i);
81                 if(m <= 0)
82                         break;
83                 buf[i+m++] = ' ';
84         }
85         close(fd);
86         buf[i] = 0;
87
88         /* parse the reply */
89         nn = na = 0;
90         for(bp = buf;;){
91                 p = strchr(bp, '=');
92                 if(p == 0)
93                         break;
94                 *p++ = 0;
95                 if(strcmp(bp, "dom") == 0){
96                         if(h.h_name == 0)
97                                 h.h_name = p;
98                         if(nn < Nname)
99                                 nptr[nn++] = p;
100                 } else if(strcmp(bp, "sys") == 0){
101                         if(nn < Nname)
102                                 nptr[nn++] = p;
103                 } else if(strcmp(bp, "ip") == 0){
104                         x = inet_addr(p);
105                         x = ntohl(x);
106                         if(na < Nname){
107                                 addr[na][0] = x>>24;
108                                 addr[na][1] = x>>16;
109                                 addr[na][2] = x>>8;
110                                 addr[na][3] = x;
111                                 aptr[na] = addr[na];
112                                 na++;
113                         }
114                 }
115                 while(*p && *p != ' ')
116                         p++;
117                 if(*p)
118                         *p++ = 0;
119                 bp = p;
120         }
121         if(nn+na == 0){
122                 h_errno = HOST_NOT_FOUND;
123                 return 0;
124         }
125
126         nptr[nn] = 0;
127         aptr[na] = 0;
128         h.h_aliases = nptr;
129         h.h_addr_list = aptr;
130         h.h_length = 4;
131         h.h_addrtype = AF_INET;
132         if(h.h_name == 0)
133                 h.h_name = nptr[0];
134         if(h.h_name == 0)
135                 h.h_name = aptr[0];
136
137         return &h;
138 }