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