xref: /plan9-contrib/sys/src/ape/lib/bsd/gethostbyname.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1*219b2ee8SDavid du Colombier /* posix */
2*219b2ee8SDavid du Colombier #include <sys/types.h>
3*219b2ee8SDavid du Colombier #include <unistd.h>
4*219b2ee8SDavid du Colombier #include <stdlib.h>
5*219b2ee8SDavid du Colombier #include <stdio.h>
6*219b2ee8SDavid du Colombier #include <fcntl.h>
7*219b2ee8SDavid du Colombier #include <string.h>
8*219b2ee8SDavid du Colombier #include <errno.h>
9*219b2ee8SDavid du Colombier 
10*219b2ee8SDavid du Colombier /* bsd extensions */
11*219b2ee8SDavid du Colombier #include <sys/uio.h>
12*219b2ee8SDavid du Colombier #include <sys/socket.h>
13*219b2ee8SDavid du Colombier #include <netinet/in.h>
14*219b2ee8SDavid du Colombier #include <netdb.h>
15*219b2ee8SDavid du Colombier 
16*219b2ee8SDavid du Colombier #include "priv.h"
17*219b2ee8SDavid du Colombier 
18*219b2ee8SDavid du Colombier int h_errno;
19*219b2ee8SDavid du Colombier 
20*219b2ee8SDavid du Colombier enum
21*219b2ee8SDavid du Colombier {
22*219b2ee8SDavid du Colombier 	Nname= 6,
23*219b2ee8SDavid du Colombier };
24*219b2ee8SDavid du Colombier 
25*219b2ee8SDavid du Colombier /*
26*219b2ee8SDavid du Colombier  *  for inet addresses only
27*219b2ee8SDavid du Colombier  */
28*219b2ee8SDavid du Colombier struct hostent*
29*219b2ee8SDavid du Colombier gethostbyname(char *name)
30*219b2ee8SDavid du Colombier {
31*219b2ee8SDavid du Colombier 	int i, t, fd, m;
32*219b2ee8SDavid du Colombier 	char *p, *bp;
33*219b2ee8SDavid du Colombier 	int nn, na;
34*219b2ee8SDavid du Colombier 	unsigned long x;
35*219b2ee8SDavid du Colombier 	static struct hostent h;
36*219b2ee8SDavid du Colombier 	static char buf[1024];
37*219b2ee8SDavid du Colombier 	static char *nptr[Nname+1];
38*219b2ee8SDavid du Colombier 	static char *aptr[Nname+1];
39*219b2ee8SDavid du Colombier 	static char addr[Nname][4];
40*219b2ee8SDavid du Colombier 
41*219b2ee8SDavid du Colombier 	h.h_name = 0;
42*219b2ee8SDavid du Colombier 	t = _sock_ipattr(name);
43*219b2ee8SDavid du Colombier 
44*219b2ee8SDavid du Colombier 	/* connect to server */
45*219b2ee8SDavid du Colombier 	fd = open("/net/cs", O_RDWR);
46*219b2ee8SDavid du Colombier 	if(fd < 0){
47*219b2ee8SDavid du Colombier 		_syserrno();
48*219b2ee8SDavid du Colombier 		h_errno = NO_RECOVERY;
49*219b2ee8SDavid du Colombier 		return 0;
50*219b2ee8SDavid du Colombier 	}
51*219b2ee8SDavid du Colombier 
52*219b2ee8SDavid du Colombier 	/* construct the query, always expect an ip# back */
53*219b2ee8SDavid du Colombier 	switch(t){
54*219b2ee8SDavid du Colombier 	case Tsys:
55*219b2ee8SDavid du Colombier 		sprintf(buf, "!sys=%s ip=*", name);
56*219b2ee8SDavid du Colombier 		break;
57*219b2ee8SDavid du Colombier 	case Tdom:
58*219b2ee8SDavid du Colombier 		sprintf(buf, "!dom=%s ip=*", name);
59*219b2ee8SDavid du Colombier 		break;
60*219b2ee8SDavid du Colombier 	case Tip:
61*219b2ee8SDavid du Colombier 		sprintf(buf, "!ip=%s", name);
62*219b2ee8SDavid du Colombier 		break;
63*219b2ee8SDavid du Colombier 	}
64*219b2ee8SDavid du Colombier 
65*219b2ee8SDavid du Colombier 	/* query the server */
66*219b2ee8SDavid du Colombier 	if(write(fd, buf, strlen(buf)) < 0){
67*219b2ee8SDavid du Colombier 		_syserrno();
68*219b2ee8SDavid du Colombier 		h_errno = TRY_AGAIN;
69*219b2ee8SDavid du Colombier 		return 0;
70*219b2ee8SDavid du Colombier 	}
71*219b2ee8SDavid du Colombier 	lseek(fd, 0, 0);
72*219b2ee8SDavid du Colombier 	for(i = 0; i < sizeof(buf)-1; i += m){
73*219b2ee8SDavid du Colombier 		m = read(fd, buf+i, sizeof(buf) - 1 - i);
74*219b2ee8SDavid du Colombier 		if(m <= 0)
75*219b2ee8SDavid du Colombier 			break;
76*219b2ee8SDavid du Colombier 		buf[i+m++] = ' ';
77*219b2ee8SDavid du Colombier 	}
78*219b2ee8SDavid du Colombier 	close(fd);
79*219b2ee8SDavid du Colombier 	buf[i] = 0;
80*219b2ee8SDavid du Colombier 
81*219b2ee8SDavid du Colombier 	/* parse the reply */
82*219b2ee8SDavid du Colombier 	nn = na = 0;
83*219b2ee8SDavid du Colombier 	for(bp = buf;;){
84*219b2ee8SDavid du Colombier 		p = strchr(bp, '=');
85*219b2ee8SDavid du Colombier 		if(p == 0)
86*219b2ee8SDavid du Colombier 			break;
87*219b2ee8SDavid du Colombier 		*p++ = 0;
88*219b2ee8SDavid du Colombier 		if(strcmp(bp, "dom") == 0){
89*219b2ee8SDavid du Colombier 			if(h.h_name == 0)
90*219b2ee8SDavid du Colombier 				h.h_name = p;
91*219b2ee8SDavid du Colombier 			if(nn < Nname)
92*219b2ee8SDavid du Colombier 				nptr[nn++] = p;
93*219b2ee8SDavid du Colombier 		} else if(strcmp(bp, "sys") == 0){
94*219b2ee8SDavid du Colombier 			if(nn < Nname)
95*219b2ee8SDavid du Colombier 				nptr[nn++] = p;
96*219b2ee8SDavid du Colombier 		} else if(strcmp(bp, "ip") == 0){
97*219b2ee8SDavid du Colombier 			x = inet_addr(p);
98*219b2ee8SDavid du Colombier 			if(na < Nname){
99*219b2ee8SDavid du Colombier 				addr[na][0] = x>>24;
100*219b2ee8SDavid du Colombier 				addr[na][1] = x>>16;
101*219b2ee8SDavid du Colombier 				addr[na][2] = x>>8;
102*219b2ee8SDavid du Colombier 				addr[na][3] = x;
103*219b2ee8SDavid du Colombier 				aptr[na] = addr[na];
104*219b2ee8SDavid du Colombier 				na++;
105*219b2ee8SDavid du Colombier 			}
106*219b2ee8SDavid du Colombier 		}
107*219b2ee8SDavid du Colombier 		while(*p && *p != ' ')
108*219b2ee8SDavid du Colombier 			p++;
109*219b2ee8SDavid du Colombier 		if(*p)
110*219b2ee8SDavid du Colombier 			*p++ = 0;
111*219b2ee8SDavid du Colombier 		bp = p;
112*219b2ee8SDavid du Colombier 	}
113*219b2ee8SDavid du Colombier 	if(nn+na == 0){
114*219b2ee8SDavid du Colombier 		h_errno = HOST_NOT_FOUND;
115*219b2ee8SDavid du Colombier 		return 0;
116*219b2ee8SDavid du Colombier 	}
117*219b2ee8SDavid du Colombier 
118*219b2ee8SDavid du Colombier 	nptr[nn] = 0;
119*219b2ee8SDavid du Colombier 	aptr[na] = 0;
120*219b2ee8SDavid du Colombier 	h.h_aliases = nptr;
121*219b2ee8SDavid du Colombier 	h.h_addr_list = aptr;
122*219b2ee8SDavid du Colombier 	h.h_length = 4;
123*219b2ee8SDavid du Colombier 	h.h_addrtype = AF_INET;
124*219b2ee8SDavid du Colombier 	if(h.h_name == 0)
125*219b2ee8SDavid du Colombier 		h.h_name = nptr[0];
126*219b2ee8SDavid du Colombier 	if(h.h_name == 0)
127*219b2ee8SDavid du Colombier 		h.h_name = aptr[0];
128*219b2ee8SDavid du Colombier 
129*219b2ee8SDavid du Colombier 	return &h;
130*219b2ee8SDavid du Colombier }
131