Commit | Line | Data |
---|---|---|
dc0d77d7 CE |
1 | #include <unistd.h> |
2 | #include "taia.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 | ||
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 | ||
19 | if (!stralloc_copys(rules,"")) return -1; | |
20 | ||
21 | x = env_get("DNSREWRITEFILE"); | |
22 | if (!x) x = "/etc/dnsrewrite"; | |
23 | ||
24 | i = openreadclose(x,&data,64); | |
25 | if (i == -1) return -1; | |
26 | ||
27 | if (i) { | |
28 | if (!stralloc_append(&data,"\n")) return -1; | |
29 | i = 0; | |
30 | for (j = 0;j < data.len;++j) | |
31 | if (data.s[j] == '\n') { | |
32 | if (!stralloc_catb(rules,data.s + i,j - i)) return -1; | |
33 | while (rules->len) { | |
34 | if (rules->s[rules->len - 1] != ' ') | |
35 | if (rules->s[rules->len - 1] != '\t') | |
36 | if (rules->s[rules->len - 1] != '\r') | |
37 | break; | |
38 | --rules->len; | |
39 | } | |
40 | if (!stralloc_0(rules)) return -1; | |
41 | i = j + 1; | |
42 | } | |
43 | return 0; | |
44 | } | |
45 | ||
46 | x = env_get("LOCALDOMAIN"); | |
47 | if (x) { | |
48 | if (!stralloc_copys(&data,x)) return -1; | |
49 | if (!stralloc_append(&data," ")) return -1; | |
50 | if (!stralloc_copys(rules,"?:")) return -1; | |
51 | i = 0; | |
52 | for (j = 0;j < data.len;++j) | |
53 | if (data.s[j] == ' ') { | |
54 | if (!stralloc_cats(rules,"+.")) return -1; | |
55 | if (!stralloc_catb(rules,data.s + i,j - i)) return -1; | |
56 | i = j + 1; | |
57 | } | |
58 | if (!stralloc_0(rules)) return -1; | |
59 | if (!stralloc_cats(rules,"*.:")) return -1; | |
60 | if (!stralloc_0(rules)) return -1; | |
61 | return 0; | |
62 | } | |
63 | ||
64 | i = openreadclose("/etc/resolv.conf",&data,64); | |
65 | if (i == -1) return -1; | |
66 | ||
67 | if (i) { | |
68 | if (!stralloc_append(&data,"\n")) return -1; | |
69 | i = 0; | |
70 | for (j = 0;j < data.len;++j) | |
71 | if (data.s[j] == '\n') { | |
72 | if (byte_equal("search ",7,data.s + i) || byte_equal("search\t",7,data.s + i) || byte_equal("domain ",7,data.s + i) || byte_equal("domain\t",7,data.s + i)) { | |
73 | if (!stralloc_copys(rules,"?:")) return -1; | |
74 | i += 7; | |
75 | while (i < j) { | |
76 | k = byte_chr(data.s + i,j - i,' '); | |
77 | k = byte_chr(data.s + i,k,'\t'); | |
78 | if (!k) { ++i; continue; } | |
79 | if (!stralloc_cats(rules,"+.")) return -1; | |
80 | if (!stralloc_catb(rules,data.s + i,k)) return -1; | |
81 | i += k; | |
82 | } | |
83 | if (!stralloc_0(rules)) return -1; | |
84 | if (!stralloc_cats(rules,"*.:")) return -1; | |
85 | if (!stralloc_0(rules)) return -1; | |
86 | return 0; | |
87 | } | |
88 | i = j + 1; | |
89 | } | |
90 | } | |
91 | ||
92 | host[0] = 0; | |
93 | if (gethostname(host,sizeof host) == -1) return -1; | |
94 | host[(sizeof host) - 1] = 0; | |
95 | i = str_chr(host,'.'); | |
96 | if (host[i]) { | |
97 | if (!stralloc_copys(rules,"?:")) return -1; | |
98 | if (!stralloc_cats(rules,host + i)) return -1; | |
99 | if (!stralloc_0(rules)) return -1; | |
100 | } | |
101 | if (!stralloc_cats(rules,"*.:")) return -1; | |
102 | if (!stralloc_0(rules)) return -1; | |
103 | ||
104 | return 0; | |
105 | } | |
106 | ||
107 | static int ok = 0; | |
108 | static unsigned int uses; | |
109 | static struct taia deadline; | |
110 | static stralloc rules = {0}; /* defined if ok */ | |
111 | ||
112 | int dns_resolvconfrewrite(stralloc *out) | |
113 | { | |
114 | struct taia now; | |
115 | ||
116 | taia_now(&now); | |
117 | if (taia_less(&deadline,&now)) ok = 0; | |
118 | if (!uses) ok = 0; | |
119 | ||
120 | if (!ok) { | |
121 | if (init(&rules) == -1) return -1; | |
122 | taia_uint(&deadline,600); | |
123 | taia_add(&deadline,&now,&deadline); | |
124 | uses = 10000; | |
125 | ok = 1; | |
126 | } | |
127 | ||
128 | --uses; | |
129 | if (!stralloc_copy(out,&rules)) return -1; | |
130 | return 0; | |
131 | } |