xref: /plan9/sys/src/ape/lib/bsd/getservbyname.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 #include <ctype.h>
10*219b2ee8SDavid du Colombier 
11*219b2ee8SDavid du Colombier /* bsd extensions */
12*219b2ee8SDavid du Colombier #include <sys/uio.h>
13*219b2ee8SDavid du Colombier #include <sys/socket.h>
14*219b2ee8SDavid du Colombier #include <netinet/in.h>
15*219b2ee8SDavid du Colombier #include <netdb.h>
16*219b2ee8SDavid du Colombier 
17*219b2ee8SDavid du Colombier #include "priv.h"
18*219b2ee8SDavid du Colombier 
19*219b2ee8SDavid du Colombier enum
20*219b2ee8SDavid du Colombier {
21*219b2ee8SDavid du Colombier 	Nname= 6,
22*219b2ee8SDavid du Colombier };
23*219b2ee8SDavid du Colombier 
24*219b2ee8SDavid du Colombier /*
25*219b2ee8SDavid du Colombier  *  for inet addresses only
26*219b2ee8SDavid du Colombier  */
27*219b2ee8SDavid du Colombier struct servent*
28*219b2ee8SDavid du Colombier getservbyname(char *name, char *proto)
29*219b2ee8SDavid du Colombier {
30*219b2ee8SDavid du Colombier 	int i, fd, m, num;
31*219b2ee8SDavid du Colombier 	char *p, *bp;
32*219b2ee8SDavid du Colombier 	int nn, na;
33*219b2ee8SDavid du Colombier 	static struct servent s;
34*219b2ee8SDavid du Colombier 	static char buf[1024];
35*219b2ee8SDavid du Colombier 	static char *nptr[Nname+1];
36*219b2ee8SDavid du Colombier 
37*219b2ee8SDavid du Colombier 	num = 1;
38*219b2ee8SDavid du Colombier 	for(p = name; *p; p++)
39*219b2ee8SDavid du Colombier 		if(!isdigit(*p))
40*219b2ee8SDavid du Colombier 			num = 0;
41*219b2ee8SDavid du Colombier 
42*219b2ee8SDavid du Colombier 	s.s_name = 0;
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 		return 0;
49*219b2ee8SDavid du Colombier 	}
50*219b2ee8SDavid du Colombier 
51*219b2ee8SDavid du Colombier 	/* construct the query, always expect an ip# back */
52*219b2ee8SDavid du Colombier 	if(num)
53*219b2ee8SDavid du Colombier 		sprintf(buf, "!port=%s %s=*", name, proto);
54*219b2ee8SDavid du Colombier 	else
55*219b2ee8SDavid du Colombier 		sprintf(buf, "!%s=%s port=*", proto, name);
56*219b2ee8SDavid du Colombier 
57*219b2ee8SDavid du Colombier 	/* query the server */
58*219b2ee8SDavid du Colombier 	if(write(fd, buf, strlen(buf)) < 0){
59*219b2ee8SDavid du Colombier 		_syserrno();
60*219b2ee8SDavid du Colombier 		return 0;
61*219b2ee8SDavid du Colombier 	}
62*219b2ee8SDavid du Colombier 	lseek(fd, 0, 0);
63*219b2ee8SDavid du Colombier 	for(i = 0; i < sizeof(buf)-1; i += m){
64*219b2ee8SDavid du Colombier 		m = read(fd, buf+i, sizeof(buf) - 1 - i);
65*219b2ee8SDavid du Colombier 		if(m <= 0)
66*219b2ee8SDavid du Colombier 			break;
67*219b2ee8SDavid du Colombier 		buf[i+m++] = ' ';
68*219b2ee8SDavid du Colombier 	}
69*219b2ee8SDavid du Colombier 	close(fd);
70*219b2ee8SDavid du Colombier 	buf[i] = 0;
71*219b2ee8SDavid du Colombier 
72*219b2ee8SDavid du Colombier 	/* parse the reply */
73*219b2ee8SDavid du Colombier 	nn = na = 0;
74*219b2ee8SDavid du Colombier 	for(bp = buf;;){
75*219b2ee8SDavid du Colombier 		p = strchr(bp, '=');
76*219b2ee8SDavid du Colombier 		if(p == 0)
77*219b2ee8SDavid du Colombier 			break;
78*219b2ee8SDavid du Colombier 		*p++ = 0;
79*219b2ee8SDavid du Colombier 		if(strcmp(bp, proto) == 0){
80*219b2ee8SDavid du Colombier 			if(nn < Nname)
81*219b2ee8SDavid du Colombier 				nptr[nn++] = p;
82*219b2ee8SDavid du Colombier 		} else if(strcmp(bp, "port") == 0){
83*219b2ee8SDavid du Colombier 			s.s_port = htons(atoi(p));
84*219b2ee8SDavid du Colombier 		}
85*219b2ee8SDavid du Colombier 		while(*p && *p != ' ')
86*219b2ee8SDavid du Colombier 			p++;
87*219b2ee8SDavid du Colombier 		if(*p)
88*219b2ee8SDavid du Colombier 			*p++ = 0;
89*219b2ee8SDavid du Colombier 		bp = p;
90*219b2ee8SDavid du Colombier 	}
91*219b2ee8SDavid du Colombier 	if(nn+na == 0)
92*219b2ee8SDavid du Colombier 		return 0;
93*219b2ee8SDavid du Colombier 
94*219b2ee8SDavid du Colombier 	nptr[nn] = 0;
95*219b2ee8SDavid du Colombier 	s.s_aliases = nptr;
96*219b2ee8SDavid du Colombier 	if(s.s_name == 0)
97*219b2ee8SDavid du Colombier 		s.s_name = nptr[0];
98*219b2ee8SDavid du Colombier 
99*219b2ee8SDavid du Colombier 	return &s;
100*219b2ee8SDavid du Colombier }
101