7 simple reader for /etc/hosts
8 it only supports comments, blank lines and lines consisting of an ipv4 hostname pair.
9 this is required so we can return entries from the host db without messing up the
10 non-thread-safe state of libc's gethostent().
19 int hostsreader_open(struct hostsreader
*ctx
) {
20 if(!(ctx
->f
= fopen("/etc/hosts", "r"))) return 0;
24 void hostsreader_close(struct hostsreader
*ctx
) {
28 int hostsreader_get(struct hostsreader
*ctx
, char* buf
, size_t bufsize
) {
30 if(!fgets(buf
, bufsize
, ctx
->f
)) return 0;
31 if(*buf
== '#') continue;
35 while(*p
&& !isspace(*p
) && l
) {
39 if(!l
|| !*p
|| p
== ctx
->ip
) continue;
42 while(*p
&& isspace(*p
) && l
) {
46 if(!l
|| !*p
) continue;
48 while(*p
&& !isspace(*p
) && l
) {
52 if(!l
|| !*p
) continue;
54 if(pc_isnumericipv4(ctx
->ip
)) return 1;
58 char* hostsreader_get_ip_for_name(const char* name
, char* buf
, size_t bufsize
) {
59 struct hostsreader ctx
;
61 if(!hostsreader_open(&ctx
)) return 0;
62 while(hostsreader_get(&ctx
, buf
, bufsize
)) {
63 if(!strcmp(ctx
.name
, name
)) {
68 hostsreader_close(&ctx
);
73 #include <netinet/in.h>
74 #include <sys/socket.h>
75 #include <arpa/inet.h>
76 ip_type4
hostsreader_get_numeric_ip_for_name(const char* name
) {
79 if((hres
= hostsreader_get_ip_for_name(name
, buf
, sizeof buf
))) {
83 memcpy(res
.octet
, &c
.s_addr
, 4);
85 } else return IPT4_INVALID
;
88 #ifdef HOSTSREADER_TEST
90 int main(int a
, char**b
) {
93 char * ret
= hostsreader_get_ip_for_name(b
[1], buf
, sizeof buf
);
94 printf("%s\n", ret
? ret
: "null");