]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/inet/ethers.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / inet / ethers.c
1 /*
2  * libc/inet/ethers.c
3  *
4  * Programmatic interface for the /etc/ethers file
5  *
6  * Copyright 2007 by Matthew Wilcox <matthew@wil.cx>
7  *
8  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
9  */
10
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <netinet/ether.h>
15
16 #define ETHER_LINE_LEN  256
17
18 /*
19  * Internal function which returns a pointer to the part of the line
20  * with the start of the hostname, or NULL if we couldn't parse the line.
21  * Note that this line may have a comment symbol on it somewhere; if so
22  * it will return NULL if the # is before or within the ether_addr, and
23  * succeed if the # is before or within the host.  It's up to the callers
24  * to be aware of this.
25  *
26  * I would have preferred to write a NUL to the location of the comment
27  * character, but ether_line takes a const argument.  See __ether_line_w.
28  */
29 static const char *__ether_line(const char *line, struct ether_addr *addr)
30 {
31         struct ether_addr *res = ether_aton_r(line, addr);
32         if (!res)
33                 return NULL;
34
35         while (*line && (*line != ' ') && (*line != '\t'))
36                 line++;
37         while (*line && ((*line == ' ') || (*line == '\t')))
38                 line++;
39         return (*line) ? line : NULL;
40 }
41
42 /*
43  * Strips out the comment before calling __ether_line.  We can do this,
44  * since we know the buffer is writable.
45  */
46 static const char *__ether_line_w(char *line, struct ether_addr *addr)
47 {
48         char *end = strchr(line, '#');
49         if (!end)
50                 end = strchr(line, '\n');
51         if (end)
52                 *end = '\0';
53         return __ether_line(line, addr);
54 }
55
56 int ether_line(const char *line, struct ether_addr *addr, char *hostname)
57 {
58         const char *name = __ether_line(line, addr);
59         if (!name)
60                 return -1;
61
62         while (*name) {
63                 if ((*name == '#') || isspace(*name))
64                         break;
65                 *hostname++ = *name++;
66         }
67         *hostname = '\0';
68
69         return 0;
70 }
71
72 int ether_ntohost(char *hostname, const struct ether_addr *addr)
73 {
74         int res = -1;
75         FILE *fp;
76         char buf[ETHER_LINE_LEN];
77
78         fp = fopen(ETHER_FILE_NAME, "r");
79         if (!fp)
80                 return -1;
81
82         while (fgets(buf, sizeof(buf), fp)) {
83                 struct ether_addr tmp_addr;
84                 const char *cp = __ether_line_w(buf, &tmp_addr);
85                 if (!cp)
86                         continue;
87                 if (memcmp(addr, &tmp_addr, sizeof(tmp_addr)))
88                         continue;
89
90                 strcpy(hostname, cp);
91                 res = 0;
92                 break;
93         }
94
95         fclose(fp);
96         return res;
97 }
98
99 int ether_hostton(const char *hostname, struct ether_addr *addr)
100 {
101         int res = -1;
102         FILE *fp;
103         char buf[ETHER_LINE_LEN];
104
105         fp = fopen(ETHER_FILE_NAME, "r");
106         if (!fp)
107                 return -1;
108
109         while (fgets(buf, sizeof(buf), fp)) {
110                 const char *cp = __ether_line_w(buf, addr);
111                 if (!cp)
112                         continue;
113                 if (strcasecmp(hostname, cp))
114                         continue;
115
116                 res = 0;
117                 break;
118         }
119
120         fclose(fp);
121         return res;
122 }