1 #include <unistd.h>
2 #include "milliseconds.h"
3 #include "env.h"
4 #include "byte.h"
5 #include "str.h"
6 #include "openreadclose.h"
7 #include "dns.h"
8
9 static stralloc data = {0};
10
init(stralloc * rules)11 static int init(stralloc *rules)
12 {
13 char host[256];
14 const char *x;
15 int i;
16 int j;
17 int k;
18 int flagds = 0;
19
20 if (!stralloc_copys(rules,"")) return -1;
21
22 x = env_get("DNSREWRITEFILE");
23 if (!x) x = "/etc/dnsrewrite";
24
25 i = openreadclose(x,&data,64);
26 if (i == -1) return -1;
27
28 if (i) {
29 if (!stralloc_append(&data,"\n")) return -1;
30 i = 0;
31 for (j = 0;j < data.len;++j)
32 if (data.s[j] == '\n') {
33 if (!stralloc_catb(rules,data.s + i,j - i)) return -1;
34 while (rules->len) {
35 if (rules->s[rules->len - 1] != ' ')
36 if (rules->s[rules->len - 1] != '\t')
37 if (rules->s[rules->len - 1] != '\r')
38 break;
39 --rules->len;
40 }
41 if (!stralloc_0(rules)) return -1;
42 i = j + 1;
43 }
44 return 0;
45 }
46
47 x = env_get("LOCALDOMAIN");
48 if (x) {
49 if (!stralloc_copys(&data,x)) return -1;
50 if (!stralloc_append(&data," ")) return -1;
51 if (!stralloc_copys(rules,"?:")) return -1;
52 i = 0;
53 for (j = 0;j < data.len;++j)
54 if (data.s[j] == ' ') {
55 if (!stralloc_cats(rules,"+.")) return -1;
56 if (!stralloc_catb(rules,data.s + i,j - i)) return -1;
57 i = j + 1;
58 }
59 if (!stralloc_0(rules)) return -1;
60 if (!stralloc_cats(rules,"*.:")) return -1;
61 if (!stralloc_0(rules)) return -1;
62 return 0;
63 }
64
65 i = openreadclose("/etc/resolv.conf",&data,64);
66 if (i == -1) return -1;
67
68 if (i) {
69 if (!stralloc_append(&data,"\n")) return -1;
70 i = 0;
71 for (j = 0;j < data.len;++j)
72 if (data.s[j] == '\n') {
73 if (byte_isequal("domain ",7,data.s + i) || byte_isequal("domain\t",7,data.s + i)) {
74 flagds = 1;
75 }
76 if (byte_isequal("search ",7,data.s + i) || byte_isequal("search\t",7,data.s + i)) {
77 flagds = 2;
78 }
79 if (flagds) {
80 if (!stralloc_copys(rules,"?:")) return -1;
81 i += 7;
82 while (i < j) {
83 k = byte_chr(data.s + i,j - i,' ');
84 k = byte_chr(data.s + i,k,'\t');
85 if (!k) { ++i; continue; }
86 if (!stralloc_cats(rules,"+.")) return -1;
87 if (!stralloc_catb(rules,data.s + i,k)) return -1;
88 i += k;
89 }
90 if (!stralloc_0(rules)) return -1;
91 if (!stralloc_cats(rules,"*.:")) return -1;
92 if (!stralloc_0(rules)) return -1;
93 if (flagds > 1) return 0;
94 }
95 i = j + 1;
96 }
97 if (flagds > 0) return 0;
98 }
99
100 host[0] = 0;
101 if (gethostname(host,sizeof host) == -1) return -1;
102 host[(sizeof host) - 1] = 0;
103 i = str_chr(host,'.');
104 if (host[i]) {
105 if (!stralloc_copys(rules,"?:")) return -1;
106 if (!stralloc_cats(rules,host + i)) return -1;
107 if (!stralloc_0(rules)) return -1;
108 }
109 if (!stralloc_cats(rules,"*.:")) return -1;
110 if (!stralloc_0(rules)) return -1;
111
112 return 0;
113 }
114
115 static int ok = 0;
116 static long long uses;
117 static long long deadline;
118 static stralloc rules = {0}; /* defined if ok */
119
dns_resolvconfrewrite(stralloc * out)120 int dns_resolvconfrewrite(stralloc *out) {
121
122 long long now;
123
124 now = milliseconds();
125 if (deadline < now) ok = 0;
126 if (uses <= 0) ok = 0;
127
128 if (!ok) {
129 if (init(&rules) == -1) return -1;
130 deadline = 600000 + now;
131 uses = 10000;
132 ok = 1;
133 }
134
135 --uses;
136 if (!stralloc_copy(out, &rules)) return -1;
137 return 0;
138 }
139