xref: /plan9/sys/src/ape/lib/bsd/gethostbyname.c (revision 6ca6a3e703ee2ec4aed99c2177f71d7f127da6d9)
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