xref: /plan9/sys/src/ape/lib/bsd/getprotobyname.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
180ee5cbfSDavid du Colombier /* posix */
280ee5cbfSDavid du Colombier #include <sys/types.h>
380ee5cbfSDavid du Colombier #include <unistd.h>
480ee5cbfSDavid du Colombier #include <stdlib.h>
580ee5cbfSDavid du Colombier #include <stdio.h>
680ee5cbfSDavid du Colombier #include <fcntl.h>
780ee5cbfSDavid du Colombier #include <string.h>
880ee5cbfSDavid du Colombier #include <errno.h>
980ee5cbfSDavid du Colombier 
1080ee5cbfSDavid du Colombier /* bsd extensions */
1180ee5cbfSDavid du Colombier #include <sys/uio.h>
1280ee5cbfSDavid du Colombier #include <sys/socket.h>
1380ee5cbfSDavid du Colombier #include <netinet/in.h>
1480ee5cbfSDavid du Colombier #include <netdb.h>
1580ee5cbfSDavid du Colombier 
1680ee5cbfSDavid du Colombier #include "priv.h"
1780ee5cbfSDavid du Colombier 
1880ee5cbfSDavid du Colombier extern int h_errno;
1980ee5cbfSDavid du Colombier 
2080ee5cbfSDavid du Colombier enum
2180ee5cbfSDavid du Colombier {
2280ee5cbfSDavid du Colombier 	Nname= 6,
2380ee5cbfSDavid du Colombier };
2480ee5cbfSDavid du Colombier 
2580ee5cbfSDavid du Colombier static struct protoent r;
2680ee5cbfSDavid du Colombier 
getprotobyname(const char * name)2780ee5cbfSDavid du Colombier struct protoent *getprotobyname(const char *name) {
2880ee5cbfSDavid du Colombier 	int fd, i, m;
2980ee5cbfSDavid du Colombier 	char *p, *bp;
3080ee5cbfSDavid du Colombier 	int nn, na;
3180ee5cbfSDavid du Colombier 	static char buf[1024], proto[1024];
3280ee5cbfSDavid du Colombier 	static char *nptr[Nname+1];
3380ee5cbfSDavid du Colombier 
3480ee5cbfSDavid du Colombier 	/* connect to server */
3580ee5cbfSDavid du Colombier 	fd = open("/net/cs", O_RDWR);
3680ee5cbfSDavid du Colombier 	if(fd < 0){
3780ee5cbfSDavid du Colombier 		_syserrno();
3880ee5cbfSDavid du Colombier 		h_errno = NO_RECOVERY;
3980ee5cbfSDavid du Colombier 		return 0;
4080ee5cbfSDavid du Colombier 	}
4180ee5cbfSDavid du Colombier 
4280ee5cbfSDavid du Colombier 	/* construct the query, always expect a protocol# back */
43*7e125112SDavid du Colombier 	snprintf(buf, sizeof buf, "!protocol=%s ipv4proto=*", name);
4480ee5cbfSDavid du Colombier 
4580ee5cbfSDavid du Colombier 	/* query the server */
4680ee5cbfSDavid du Colombier 	if(write(fd, buf, strlen(buf)) < 0){
4780ee5cbfSDavid du Colombier 		_syserrno();
4880ee5cbfSDavid du Colombier 		h_errno = TRY_AGAIN;
4980ee5cbfSDavid du Colombier 		return 0;
5080ee5cbfSDavid du Colombier 	}
5180ee5cbfSDavid du Colombier 	lseek(fd, 0, 0);
5280ee5cbfSDavid du Colombier 	for(i = 0; i < sizeof(buf)-1; i += m){
5380ee5cbfSDavid du Colombier 		m = read(fd, buf+i, sizeof(buf) - 1 - i);
5480ee5cbfSDavid du Colombier 		if(m <= 0)
5580ee5cbfSDavid du Colombier 			break;
5680ee5cbfSDavid du Colombier 		buf[i+m++] = ' ';
5780ee5cbfSDavid du Colombier 	}
5880ee5cbfSDavid du Colombier 	close(fd);
5980ee5cbfSDavid du Colombier 	buf[i] = 0;
6080ee5cbfSDavid du Colombier 
6180ee5cbfSDavid du Colombier 	/* parse the reply */
6280ee5cbfSDavid du Colombier 	nn = na = 0;
6380ee5cbfSDavid du Colombier 	for(bp = buf;;){
6480ee5cbfSDavid du Colombier 		p = strchr(bp, '=');
6580ee5cbfSDavid du Colombier 		if(p == 0)
6680ee5cbfSDavid du Colombier 			break;
6780ee5cbfSDavid du Colombier 		*p++ = 0;
6880ee5cbfSDavid du Colombier 		if(strcmp(bp, "protocol") == 0){
6980ee5cbfSDavid du Colombier 			if(!nn)
7080ee5cbfSDavid du Colombier 				r.p_name = p;
7180ee5cbfSDavid du Colombier 			if(nn < Nname)
7280ee5cbfSDavid du Colombier 				nptr[nn++] = p;
7380ee5cbfSDavid du Colombier 		} else if(strcmp(bp, "ipv4proto") == 0){
7480ee5cbfSDavid du Colombier 			r.p_proto = atoi(p);
7580ee5cbfSDavid du Colombier 			na++;
7680ee5cbfSDavid du Colombier 		}
7780ee5cbfSDavid du Colombier 		while(*p && *p != ' ')
7880ee5cbfSDavid du Colombier 			p++;
7980ee5cbfSDavid du Colombier 		if(*p)
8080ee5cbfSDavid du Colombier 			*p++ = 0;
8180ee5cbfSDavid du Colombier 		bp = p;
8280ee5cbfSDavid du Colombier 	}
8380ee5cbfSDavid du Colombier 	nptr[nn] = 0;
8480ee5cbfSDavid du Colombier 	r.p_aliases = nptr;
8580ee5cbfSDavid du Colombier 	if (nn+na == 0)
8680ee5cbfSDavid du Colombier 		return 0;
8780ee5cbfSDavid du Colombier 
8880ee5cbfSDavid du Colombier 	return &r;
8980ee5cbfSDavid du Colombier }
90