xref: /plan9/sys/src/ape/lib/bsd/gethostbyname.c (revision 6ca6a3e703ee2ec4aed99c2177f71d7f127da6d9)
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*
gethostbyname(const char * name)29 gethostbyname(const 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 		snprintf(buf, sizeof buf, "!sys=%s ip=*", name);
56 		break;
57 	case Tdom:
58 		snprintf(buf, sizeof buf, "!dom=%s ip=*", name);
59 		break;
60 	case Tip:
61 		snprintf(buf, sizeof 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 			x = ntohl(x);
99 			if(na < Nname){
100 				addr[na][0] = x>>24;
101 				addr[na][1] = x>>16;
102 				addr[na][2] = x>>8;
103 				addr[na][3] = x;
104 				aptr[na] = addr[na];
105 				na++;
106 			}
107 		}
108 		while(*p && *p != ' ')
109 			p++;
110 		if(*p)
111 			*p++ = 0;
112 		bp = p;
113 	}
114 	if(nn+na == 0){
115 		h_errno = HOST_NOT_FOUND;
116 		return 0;
117 	}
118 
119 	nptr[nn] = 0;
120 	aptr[na] = 0;
121 	h.h_aliases = nptr;
122 	h.h_addr_list = aptr;
123 	h.h_length = 4;
124 	h.h_addrtype = AF_INET;
125 	if(h.h_name == 0)
126 		h.h_name = nptr[0];
127 	if(h.h_name == 0)
128 		h.h_name = aptr[0];
129 
130 	return &h;
131 }
132