aboutsummaryrefslogtreecommitdiff
path: root/eperd/readresolv.c
blob: 9d04866135cb7d11e6fc00a372f10c15627c1848 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

#define LINEL (INET6_ADDRSTRLEN * 2)
#include "libbb.h"
#include "resolv.h"
#include "eperd.h"
#include <math.h>

static  void nameserver_ip_add (char *nsentry, char *ip_as_string) 
{

	strncpy (nsentry, ip_as_string, LINEL);
	// printf("AA added nameserver %s\n", ip_as_string);
	// printf("AA added nameserver to ns %s\n", nsentry);
	return;
}

static int resolv_conf_parse_line (char *nsentry, char *line)  
{

#define NEXT_TOKEN strtok_r(NULL, delims, &strtok_state)
	char *strtok_state;
	static const char *const delims = " \t";
	char *const first_token = strtok_r(line, delims, &strtok_state);  

	if (!first_token) return 0;

	if (!strcmp(first_token, "nameserver")) { 
		char *const nameserver = NEXT_TOKEN;
		if (nameserver) {
			if(nameserver[(strlen(nameserver) - 1)] == '\n')
			nameserver[(strlen(nameserver) - 1)] = NULL;
			nameserver_ip_add(nsentry, nameserver);
		        //printf("AA added nameserver %s\n", nsentry);
			return 1;
		}
	}
	return 0;
} 

void get_local_resolvers(char  nslist[MAXNS][INET6_ADDRSTRLEN * 2], 
		int *resolv_max)
{

#ifndef RESOLV_CONF 
#define RESOLV_CONF     "/etc/resolv.conf"
#endif 	
	char buf[LINEL]; 
	char *buf_start;
	int  i = 0;
	time_t now;
	int r;
	struct stat sb;

	static resolv_last_check = -1;
	static time_t last_time= -1;

	now = time(NULL);

	if(*resolv_max){
		if ( pow (resolv_last_check - now, 2) > 3) {
			crondlog(LVL5 "check the %s", RESOLV_CONF);
		}
		else {
			return;
		}

	}


	r = stat(RESOLV_CONF, &sb);
	if (r == -1)
	{
		crondlog(LVL8 "error accessing resolv.conf: %s",
				strerror(errno));
		return;
	}

	resolv_last_check = now;

	if (last_time  == sb.st_mtime) 
	{
		/* nothing changed */
		crondlog(LVL5 "re-read %s. not reading this time", RESOLV_CONF);
		return;
	}
	else {
		crondlog(LVL5 "re-read %s . it has changed", RESOLV_CONF);
	}

	FILE *R = fopen (RESOLV_CONF, "r");
	if (R != NULL) {
		while ( (fgets (buf, LINEL, R)) && (i < MAXNS)) {	
			buf_start = buf;
			if(resolv_conf_parse_line(nslist[i], buf) ) {
				crondlog(LVL5 "parsed file %s , line %s i=%d", RESOLV_CONF, buf_start, i);
				i++;
			}
			else 
				crondlog(LVL5 "ERROR failed to parse from  %s i=%d, line %s", RESOLV_CONF, i, buf_start);
		}
		fclose (R);
	}

	last_time = sb.st_mtime;

	*resolv_max = i;
	return;
}

void get_local_resolvers_nocache(char  nslist[MAXNS][INET6_ADDRSTRLEN * 2], 
		int *resolv_max)
{

#ifndef RESOLV_CONF 
#define RESOLV_CONF     "/etc/resolv.conf"
#endif 	
	FILE *R;
	char buf[LINEL]; 
	char *buf_start;
	int  i = 0;
	int r;
	struct stat sb;

	r = stat(RESOLV_CONF, &sb);
	if (r == -1)
	{
		crondlog(LVL8 "error accessing resolv.conf: %s",
				strerror(errno));
		return;
	}

	R = fopen (RESOLV_CONF, "r");
	if (R != NULL) {
		while ( (fgets (buf, LINEL, R)) && (i < MAXNS)) {	
			buf_start = buf;
			if(resolv_conf_parse_line(nslist[i], buf) ) {
				crondlog(LVL5 "parsed file %s , line %s i=%d", RESOLV_CONF, buf_start, i);
				i++;
			}
			else 
				crondlog(LVL5 "ERROR failed to parse from  %s i=%d, line %s", RESOLV_CONF, i, buf_start);
		}
		fclose (R);
	}

	*resolv_max = i;
}