Re-add the bsd library
[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                 _syserrno();
57                 h_errno = NO_RECOVERY;
58                 return 0;
59         }
60
61         /* construct the query, always expect an ip# back */
62         switch(t){
63         case Tsys:
64                 snprintf(buf, sizeof buf, "!sys=%s ip=*", name);
65                 break;
66         case Tdom:
67                 snprintf(buf, sizeof buf, "!dom=%s ip=*", name);
68                 break;
69         case Tip:
70                 snprintf(buf, sizeof buf, "!ip=%s", name);
71                 break;
72         }
73
74         /* query the server */
75         if(write(fd, buf, strlen(buf)) < 0){
76                 _syserrno();
77                 h_errno = TRY_AGAIN;
78                 return 0;
79         }
80         lseek(fd, 0, 0);
81         for(i = 0; i < sizeof(buf)-1; i += m){
82                 m = read(fd, buf+i, sizeof(buf) - 1 - i);
83                 if(m <= 0)
84                         break;
85                 buf[i+m++] = ' ';
86         }
87         close(fd);
88         buf[i] = 0;
89
90         /* parse the reply */
91         nn = na = 0;
92         for(bp = buf;;){
93                 p = strchr(bp, '=');
94                 if(p == 0)
95                         break;
96                 *p++ = 0;
97                 if(strcmp(bp, "dom") == 0){
98                         if(h.h_name == 0)
99                                 h.h_name = p;
100                         if(nn < Nname)
101                                 nptr[nn++] = p;
102                 } else if(strcmp(bp, "sys") == 0){
103                         if(nn < Nname)
104                                 nptr[nn++] = p;
105                 } else if(strcmp(bp, "ip") == 0){
106                         x = inet_addr(p);
107                         x = ntohl(x);
108                         if(na < Nname){
109                                 addr[na][0] = x>>24;
110                                 addr[na][1] = x>>16;
111                                 addr[na][2] = x>>8;
112                                 addr[na][3] = x;
113                                 aptr[na] = addr[na];
114                                 na++;
115                         }
116                 }
117                 while(*p && *p != ' ')
118                         p++;
119                 if(*p)
120                         *p++ = 0;
121                 bp = p;
122         }
123         if(nn+na == 0){
124                 h_errno = HOST_NOT_FOUND;
125                 return 0;
126         }
127
128         nptr[nn] = 0;
129         aptr[na] = 0;
130         h.h_aliases = nptr;
131         h.h_addr_list = aptr;
132         h.h_length = 4;
133         h.h_addrtype = AF_INET;
134         if(h.h_name == 0)
135                 h.h_name = nptr[0];
136         if(h.h_name == 0)
137                 h.h_name = aptr[0];
138
139         return &h;
140 }