xref: /plan9/sys/src/ape/lib/bsd/getservbyname.c (revision 7e125112574862ca44c733e2ecf7b75e72c6ed0e)
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 #include <ctype.h>
10219b2ee8SDavid du Colombier 
11219b2ee8SDavid du Colombier /* bsd extensions */
12219b2ee8SDavid du Colombier #include <sys/uio.h>
13219b2ee8SDavid du Colombier #include <sys/socket.h>
14219b2ee8SDavid du Colombier #include <netinet/in.h>
15219b2ee8SDavid du Colombier #include <netdb.h>
16219b2ee8SDavid du Colombier 
17219b2ee8SDavid du Colombier #include "priv.h"
18219b2ee8SDavid du Colombier 
19219b2ee8SDavid du Colombier enum
20219b2ee8SDavid du Colombier {
21219b2ee8SDavid du Colombier 	Nname= 6,
22219b2ee8SDavid du Colombier };
23219b2ee8SDavid du Colombier 
24219b2ee8SDavid du Colombier /*
25219b2ee8SDavid du Colombier  *  for inet addresses only
26219b2ee8SDavid du Colombier  */
27219b2ee8SDavid du Colombier struct servent*
getservbyname(char * name,char * proto)28219b2ee8SDavid du Colombier getservbyname(char *name, char *proto)
29219b2ee8SDavid du Colombier {
30219b2ee8SDavid du Colombier 	int i, fd, m, num;
31219b2ee8SDavid du Colombier 	char *p, *bp;
32219b2ee8SDavid du Colombier 	int nn, na;
33219b2ee8SDavid du Colombier 	static struct servent s;
34219b2ee8SDavid du Colombier 	static char buf[1024];
35219b2ee8SDavid du Colombier 	static char *nptr[Nname+1];
36219b2ee8SDavid du Colombier 
37219b2ee8SDavid du Colombier 	num = 1;
38219b2ee8SDavid du Colombier 	for(p = name; *p; p++)
39219b2ee8SDavid du Colombier 		if(!isdigit(*p))
40219b2ee8SDavid du Colombier 			num = 0;
41219b2ee8SDavid du Colombier 
42219b2ee8SDavid du Colombier 	s.s_name = 0;
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 		return 0;
49219b2ee8SDavid du Colombier 	}
50219b2ee8SDavid du Colombier 
51219b2ee8SDavid du Colombier 	/* construct the query, always expect an ip# back */
52219b2ee8SDavid du Colombier 	if(num)
53*7e125112SDavid du Colombier 		snprintf(buf, sizeof buf, "!port=%s %s=*", name, proto);
54219b2ee8SDavid du Colombier 	else
55*7e125112SDavid du Colombier 		snprintf(buf, sizeof buf, "!%s=%s port=*", proto, name);
56219b2ee8SDavid du Colombier 
57219b2ee8SDavid du Colombier 	/* query the server */
58219b2ee8SDavid du Colombier 	if(write(fd, buf, strlen(buf)) < 0){
59219b2ee8SDavid du Colombier 		_syserrno();
60219b2ee8SDavid du Colombier 		return 0;
61219b2ee8SDavid du Colombier 	}
62219b2ee8SDavid du Colombier 	lseek(fd, 0, 0);
63219b2ee8SDavid du Colombier 	for(i = 0; i < sizeof(buf)-1; i += m){
64219b2ee8SDavid du Colombier 		m = read(fd, buf+i, sizeof(buf) - 1 - i);
65219b2ee8SDavid du Colombier 		if(m <= 0)
66219b2ee8SDavid du Colombier 			break;
67219b2ee8SDavid du Colombier 		buf[i+m++] = ' ';
68219b2ee8SDavid du Colombier 	}
69219b2ee8SDavid du Colombier 	close(fd);
70219b2ee8SDavid du Colombier 	buf[i] = 0;
71219b2ee8SDavid du Colombier 
72219b2ee8SDavid du Colombier 	/* parse the reply */
73219b2ee8SDavid du Colombier 	nn = na = 0;
74219b2ee8SDavid du Colombier 	for(bp = buf;;){
75219b2ee8SDavid du Colombier 		p = strchr(bp, '=');
76219b2ee8SDavid du Colombier 		if(p == 0)
77219b2ee8SDavid du Colombier 			break;
78219b2ee8SDavid du Colombier 		*p++ = 0;
79219b2ee8SDavid du Colombier 		if(strcmp(bp, proto) == 0){
80219b2ee8SDavid du Colombier 			if(nn < Nname)
81219b2ee8SDavid du Colombier 				nptr[nn++] = p;
82219b2ee8SDavid du Colombier 		} else if(strcmp(bp, "port") == 0){
83219b2ee8SDavid du Colombier 			s.s_port = htons(atoi(p));
84219b2ee8SDavid du Colombier 		}
85219b2ee8SDavid du Colombier 		while(*p && *p != ' ')
86219b2ee8SDavid du Colombier 			p++;
87219b2ee8SDavid du Colombier 		if(*p)
88219b2ee8SDavid du Colombier 			*p++ = 0;
89219b2ee8SDavid du Colombier 		bp = p;
90219b2ee8SDavid du Colombier 	}
91219b2ee8SDavid du Colombier 	if(nn+na == 0)
92219b2ee8SDavid du Colombier 		return 0;
93219b2ee8SDavid du Colombier 
94219b2ee8SDavid du Colombier 	nptr[nn] = 0;
95219b2ee8SDavid du Colombier 	s.s_aliases = nptr;
96219b2ee8SDavid du Colombier 	if(s.s_name == 0)
97219b2ee8SDavid du Colombier 		s.s_name = nptr[0];
98219b2ee8SDavid du Colombier 
99219b2ee8SDavid du Colombier 	return &s;
100219b2ee8SDavid du Colombier }
101