| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 | /* vi: set sw=4 ts=4: *//* * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org> * * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball. *//* /etc/networks#   network-name  number     [aliases ...]loopback          127.0.0.0  # optional aliasesnetwork-name: symbolic name of the netwkorknumber: official number of the network in dotted quadaliases: case sensitive optional space or tab separated list of other names*/#include <features.h>#include <netdb.h>#include <string.h>#include <stdlib.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include <unistd.h>#include "internal/parse_config.h"#include <bits/uClibc_mutex.h>__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);#define MINTOKENS	2#define	MAXALIASES	8#define MAXTOKENS	(MINTOKENS + MAXALIASES + 1)#define BUFSZ		(255) /* one line */#define SBUFSIZE	(BUFSZ + 1 + (sizeof(char *) * MAXTOKENS))static parser_t *netp = NULL;static struct netent nete;static char *netbuf = NULL;static smallint net_stayopen;void setnetent(int stayopen){	__UCLIBC_MUTEX_LOCK(mylock);	if (netp)		config_close(netp);	netp = config_open(_PATH_NETWORKS);	if (stayopen)		net_stayopen = 1;	__UCLIBC_MUTEX_UNLOCK(mylock);}libc_hidden_def(setnetent)void endnetent(void){	__UCLIBC_MUTEX_LOCK(mylock);	if (netp) {		config_close(netp);		netp = NULL;	}	net_stayopen = 0;	__UCLIBC_MUTEX_UNLOCK(mylock);}libc_hidden_def(endnetent)int getnetent_r(struct netent *result_buf,				char *buf, size_t buflen, struct netent **result,				int *h_errnop				 ){	char **tok = NULL;	const size_t aliaslen = sizeof(char *) * MAXTOKENS;	int ret = ERANGE;	*result = NULL;	if (buflen < aliaslen		|| (buflen - aliaslen) < BUFSZ + 1)		goto DONE_NOUNLOCK;	__UCLIBC_MUTEX_LOCK(mylock);	ret = ENOENT;	if (netp == NULL)		setnetent(net_stayopen);	if (netp == NULL)		goto DONE;	netp->data = buf;	netp->data_len = aliaslen;	netp->line_len = buflen - aliaslen;	/* <name>[[:space:]]<netnumber>[[:space:]][<aliases>] */	if (!config_read(netp, &tok, MAXTOKENS-1, MINTOKENS, "# \t/", PARSE_NORMAL)) {		goto DONE;	}	result_buf->n_name = *(tok++);	{		struct addrinfo hints, *addri;# define sa4_to_uint32(sa) \	(ntohl(((struct sockaddr_in*)sa)->sin_addr.s_addr))#ifdef __UCLIBC_HAS_IPV6__# define sa6_to_uint8(sa) \	(ntohl(((struct sockaddr_in6*)sa)->sin6_addr.s6_addr))#endif		memset(&hints, 0, sizeof(struct addrinfo));		hints.ai_family = AF_UNSPEC;		hints.ai_flags = AI_NUMERICHOST;		getaddrinfo(*(tok++), NULL, &hints, &addri);		result_buf->n_addrtype = addri->ai_family;		result_buf->n_net =#if 0 /*FIXME: implement me! def __UCLIBC_HAS_IPV6__ */			addri->ai_family == AF_INET6 ? sa6_to_uint8(addri->ai_addr) :#endif			sa4_to_uint32(addri->ai_addr);		freeaddrinfo(addri);	}	result_buf->n_aliases = tok;	*result = result_buf;	ret = 0; DONE:	__UCLIBC_MUTEX_UNLOCK(mylock); DONE_NOUNLOCK:	errno = ret;	return errno;}libc_hidden_def(getnetent_r)static void __initbuf(void){	if (!netbuf) {		netbuf = malloc(SBUFSIZE);		if (!netbuf)			abort();	}}struct netent *getnetent(void){	struct netent *result;	int herrnop;	__initbuf();	getnetent_r(&nete, netbuf, SBUFSIZE, &result, &herrnop);	return result;}int getnetbyname_r(const char *name,					struct netent *result_buf, char *buf, size_t buflen,					struct netent **result,					int *h_errnop					){	register char **cp;	int ret, herrnop;	__UCLIBC_MUTEX_LOCK(mylock);	setnetent(net_stayopen);	while (!(ret = getnetent_r(result_buf, buf, buflen, result, &herrnop))) {		if (strcmp(name, result_buf->n_name) == 0)			break;		for (cp = result_buf->n_aliases; *cp; cp++)			if (strcmp(name, *cp) == 0)				goto gotname;	} gotname:	if (!net_stayopen)		endnetent();	__UCLIBC_MUTEX_UNLOCK(mylock);	return *result ? 0 : ret;}libc_hidden_def(getnetbyname_r)struct netent *getnetbyname(const char *name){	struct netent *result;	int herrnop;	__initbuf();	getnetbyname_r(name, &nete, netbuf, SBUFSIZE, &result, &herrnop);	return result;}int getnetbyaddr_r(uint32_t net, int type,					struct netent *result_buf, char *buf,					size_t buflen, struct netent **result,					int *h_errnop){	int ret, herrnop;	__UCLIBC_MUTEX_LOCK(mylock);	setnetent(net_stayopen);	while (!(ret = getnetent_r(result_buf, buf, buflen, result, &herrnop))) {		if (net == result_buf->n_net && type == result_buf->n_addrtype)			break;	}	if (!net_stayopen)		endnetent();	__UCLIBC_MUTEX_UNLOCK(mylock);	return *result ? 0 : ret;}libc_hidden_def(getnetbyaddr_r)struct netent *getnetbyaddr(uint32_t net, int type){	struct netent *result;	int herrnop;	__initbuf();	getnetbyaddr_r(net, type, &nete, netbuf, SBUFSIZE, &result, &herrnop);	return result;}
 |