release
[hcoop/zz_old/debian/djbdns.git] / dns_rcrw.c
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 }