123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- /*
- * 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 != '\n') && (*line != ' ') && (*line != '\t'))
- line++;
- while (*line && (*line != '\n') && ((*line == ' ') || (*line == '\t')))
- line++;
- return (*line && (*line != '\n')) ? 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 = strpbrk(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;
- }
|