| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 | /* * libc/inet/ethers.c * * Programmatic interface for the /etc/ethers file * * Copyright 2007 by Matthew Wilcox <matthew@wil.cx> * * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */#include <ctype.h>#include <stdio.h>#include <string.h>#include <netinet/ether.h>#define ETHER_LINE_LEN	256/* * Internal function which returns a pointer to the part of the line * with the start of the hostname, or NULL if we couldn't parse the line. * Note that this line may have a comment symbol on it somewhere; if so * it will return NULL if the # is before or within the ether_addr, and * succeed if the # is before or within the host.  It's up to the callers * to be aware of this. * * I would have preferred to write a NUL to the location of the comment * character, but ether_line takes a const argument.  See __ether_line_w. */static const char *__ether_line(const char *line, struct ether_addr *addr){	struct ether_addr *res = ether_aton_r(line, addr);	if (!res)		return NULL;	while (*line && (*line != ' ') && (*line != '\t'))		line++;	while (*line && ((*line == ' ')	|| (*line == '\t')))		line++;	return (*line) ? line : NULL;}/* * Strips out the comment before calling __ether_line.  We can do this, * since we know the buffer is writable. */static const char *__ether_line_w(char *line, struct ether_addr *addr){	char *end = strchr(line, '#');	if (!end)		end = strchr(line, '\n');	if (end)		*end = '\0';	return __ether_line(line, addr);}int ether_line(const char *line, struct ether_addr *addr, char *hostname){	const char *name = __ether_line(line, addr);	if (!name)		return -1;	while (*name) {		if ((*name == '#') || isspace(*name))			break;		*hostname++ = *name++;	}	*hostname = '\0';	return 0;}int ether_ntohost(char *hostname, const struct ether_addr *addr){	int res = -1;	FILE *fp;	char buf[ETHER_LINE_LEN];	fp = fopen(ETHER_FILE_NAME, "r");	if (!fp)		return -1;	while (fgets(buf, sizeof(buf), fp)) {		struct ether_addr tmp_addr;		const char *cp = __ether_line_w(buf, &tmp_addr);		if (!cp)			continue;		if (memcmp(addr, &tmp_addr, sizeof(tmp_addr)))			continue;		strcpy(hostname, cp);		res = 0;		break;	}	fclose(fp);	return res;}int ether_hostton(const char *hostname, struct ether_addr *addr){	int res = -1;	FILE *fp;	char buf[ETHER_LINE_LEN];	fp = fopen(ETHER_FILE_NAME, "r");	if (!fp)		return -1;	while (fgets(buf, sizeof(buf), fp)) {		const char *cp = __ether_line_w(buf, addr);		if (!cp)			continue;		if (strcasecmp(hostname, cp))			continue;		res = 0;		break;	}	fclose(fp);	return res;}
 |