1219b2ee8SDavid du Colombier /* posix */
2219b2ee8SDavid du Colombier #include <sys/types.h>
3219b2ee8SDavid du Colombier #include <unistd.h>
4219b2ee8SDavid du Colombier #include <stdlib.h>
5219b2ee8SDavid du Colombier #include <stdio.h>
6219b2ee8SDavid du Colombier #include <fcntl.h>
7219b2ee8SDavid du Colombier #include <string.h>
8219b2ee8SDavid du Colombier #include <errno.h>
9219b2ee8SDavid du Colombier
10219b2ee8SDavid du Colombier /* bsd extensions */
11219b2ee8SDavid du Colombier #include <sys/uio.h>
12219b2ee8SDavid du Colombier #include <sys/socket.h>
13219b2ee8SDavid du Colombier #include <netinet/in.h>
14219b2ee8SDavid du Colombier #include <netdb.h>
15219b2ee8SDavid du Colombier
16219b2ee8SDavid du Colombier #include "priv.h"
17219b2ee8SDavid du Colombier
18219b2ee8SDavid du Colombier int h_errno;
19219b2ee8SDavid du Colombier
20219b2ee8SDavid du Colombier enum
21219b2ee8SDavid du Colombier {
22219b2ee8SDavid du Colombier Nname= 6,
23219b2ee8SDavid du Colombier };
24219b2ee8SDavid du Colombier
25219b2ee8SDavid du Colombier /*
26219b2ee8SDavid du Colombier * for inet addresses only
27219b2ee8SDavid du Colombier */
28219b2ee8SDavid du Colombier struct hostent*
gethostbyname(const char * name)29*6ca6a3e7SDavid du Colombier gethostbyname(const char *name)
30219b2ee8SDavid du Colombier {
31219b2ee8SDavid du Colombier int i, t, fd, m;
32219b2ee8SDavid du Colombier char *p, *bp;
33219b2ee8SDavid du Colombier int nn, na;
34219b2ee8SDavid du Colombier unsigned long x;
35219b2ee8SDavid du Colombier static struct hostent h;
36219b2ee8SDavid du Colombier static char buf[1024];
37219b2ee8SDavid du Colombier static char *nptr[Nname+1];
38219b2ee8SDavid du Colombier static char *aptr[Nname+1];
39219b2ee8SDavid du Colombier static char addr[Nname][4];
40219b2ee8SDavid du Colombier
41219b2ee8SDavid du Colombier h.h_name = 0;
42219b2ee8SDavid du Colombier t = _sock_ipattr(name);
43219b2ee8SDavid du Colombier
44219b2ee8SDavid du Colombier /* connect to server */
45219b2ee8SDavid du Colombier fd = open("/net/cs", O_RDWR);
46219b2ee8SDavid du Colombier if(fd < 0){
47219b2ee8SDavid du Colombier _syserrno();
48219b2ee8SDavid du Colombier h_errno = NO_RECOVERY;
49219b2ee8SDavid du Colombier return 0;
50219b2ee8SDavid du Colombier }
51219b2ee8SDavid du Colombier
52219b2ee8SDavid du Colombier /* construct the query, always expect an ip# back */
53219b2ee8SDavid du Colombier switch(t){
54219b2ee8SDavid du Colombier case Tsys:
557e125112SDavid du Colombier snprintf(buf, sizeof buf, "!sys=%s ip=*", name);
56219b2ee8SDavid du Colombier break;
57219b2ee8SDavid du Colombier case Tdom:
587e125112SDavid du Colombier snprintf(buf, sizeof buf, "!dom=%s ip=*", name);
59219b2ee8SDavid du Colombier break;
60219b2ee8SDavid du Colombier case Tip:
617e125112SDavid du Colombier snprintf(buf, sizeof buf, "!ip=%s", name);
62219b2ee8SDavid du Colombier break;
63219b2ee8SDavid du Colombier }
64219b2ee8SDavid du Colombier
65219b2ee8SDavid du Colombier /* query the server */
66219b2ee8SDavid du Colombier if(write(fd, buf, strlen(buf)) < 0){
67219b2ee8SDavid du Colombier _syserrno();
68219b2ee8SDavid du Colombier h_errno = TRY_AGAIN;
69219b2ee8SDavid du Colombier return 0;
70219b2ee8SDavid du Colombier }
71219b2ee8SDavid du Colombier lseek(fd, 0, 0);
72219b2ee8SDavid du Colombier for(i = 0; i < sizeof(buf)-1; i += m){
73219b2ee8SDavid du Colombier m = read(fd, buf+i, sizeof(buf) - 1 - i);
74219b2ee8SDavid du Colombier if(m <= 0)
75219b2ee8SDavid du Colombier break;
76219b2ee8SDavid du Colombier buf[i+m++] = ' ';
77219b2ee8SDavid du Colombier }
78219b2ee8SDavid du Colombier close(fd);
79219b2ee8SDavid du Colombier buf[i] = 0;
80219b2ee8SDavid du Colombier
81219b2ee8SDavid du Colombier /* parse the reply */
82219b2ee8SDavid du Colombier nn = na = 0;
83219b2ee8SDavid du Colombier for(bp = buf;;){
84219b2ee8SDavid du Colombier p = strchr(bp, '=');
85219b2ee8SDavid du Colombier if(p == 0)
86219b2ee8SDavid du Colombier break;
87219b2ee8SDavid du Colombier *p++ = 0;
88219b2ee8SDavid du Colombier if(strcmp(bp, "dom") == 0){
89219b2ee8SDavid du Colombier if(h.h_name == 0)
90219b2ee8SDavid du Colombier h.h_name = p;
91219b2ee8SDavid du Colombier if(nn < Nname)
92219b2ee8SDavid du Colombier nptr[nn++] = p;
93219b2ee8SDavid du Colombier } else if(strcmp(bp, "sys") == 0){
94219b2ee8SDavid du Colombier if(nn < Nname)
95219b2ee8SDavid du Colombier nptr[nn++] = p;
96219b2ee8SDavid du Colombier } else if(strcmp(bp, "ip") == 0){
97219b2ee8SDavid du Colombier x = inet_addr(p);
987dd7cddfSDavid du Colombier x = ntohl(x);
99219b2ee8SDavid du Colombier if(na < Nname){
100219b2ee8SDavid du Colombier addr[na][0] = x>>24;
101219b2ee8SDavid du Colombier addr[na][1] = x>>16;
102219b2ee8SDavid du Colombier addr[na][2] = x>>8;
103219b2ee8SDavid du Colombier addr[na][3] = x;
104219b2ee8SDavid du Colombier aptr[na] = addr[na];
105219b2ee8SDavid du Colombier na++;
106219b2ee8SDavid du Colombier }
107219b2ee8SDavid du Colombier }
108219b2ee8SDavid du Colombier while(*p && *p != ' ')
109219b2ee8SDavid du Colombier p++;
110219b2ee8SDavid du Colombier if(*p)
111219b2ee8SDavid du Colombier *p++ = 0;
112219b2ee8SDavid du Colombier bp = p;
113219b2ee8SDavid du Colombier }
114219b2ee8SDavid du Colombier if(nn+na == 0){
115219b2ee8SDavid du Colombier h_errno = HOST_NOT_FOUND;
116219b2ee8SDavid du Colombier return 0;
117219b2ee8SDavid du Colombier }
118219b2ee8SDavid du Colombier
119219b2ee8SDavid du Colombier nptr[nn] = 0;
120219b2ee8SDavid du Colombier aptr[na] = 0;
121219b2ee8SDavid du Colombier h.h_aliases = nptr;
122219b2ee8SDavid du Colombier h.h_addr_list = aptr;
123219b2ee8SDavid du Colombier h.h_length = 4;
124219b2ee8SDavid du Colombier h.h_addrtype = AF_INET;
125219b2ee8SDavid du Colombier if(h.h_name == 0)
126219b2ee8SDavid du Colombier h.h_name = nptr[0];
127219b2ee8SDavid du Colombier if(h.h_name == 0)
128219b2ee8SDavid du Colombier h.h_name = aptr[0];
129219b2ee8SDavid du Colombier
130219b2ee8SDavid du Colombier return &h;
131219b2ee8SDavid du Colombier }
132