release
[hcoop/zz_old/debian/djbdns.git] / roots.c
1 #include <unistd.h>
2 #include "open.h"
3 #include "error.h"
4 #include "str.h"
5 #include "byte.h"
6 #include "error.h"
7 #include "direntry.h"
8 #include "ip4.h"
9 #include "dns.h"
10 #include "openreadclose.h"
11 #include "roots.h"
12
13 static stralloc data;
14
15 static int roots_find(char *q)
16 {
17 int i;
18 int j;
19
20 i = 0;
21 while (i < data.len) {
22 j = dns_domain_length(data.s + i);
23 if (dns_domain_equal(data.s + i,q)) return i + j;
24 i += j;
25 i += 64;
26 }
27 return -1;
28 }
29
30 static int roots_search(char *q)
31 {
32 int r;
33
34 for (;;) {
35 r = roots_find(q);
36 if (r >= 0) return r;
37 if (!*q) return -1; /* user misconfiguration */
38 q += *q;
39 q += 1;
40 }
41 }
42
43 int roots(char servers[64],char *q)
44 {
45 int r;
46 r = roots_find(q);
47 if (r == -1) return 0;
48 byte_copy(servers,64,data.s + r);
49 return 1;
50 }
51
52 int roots_same(char *q,char *q2)
53 {
54 return roots_search(q) == roots_search(q2);
55 }
56
57 static int init2(DIR *dir)
58 {
59 direntry *d;
60 const char *fqdn;
61 static char *q;
62 static stralloc text;
63 char servers[64];
64 int serverslen;
65 int i;
66 int j;
67
68 for (;;) {
69 errno = 0;
70 d = readdir(dir);
71 if (!d) {
72 if (errno) return 0;
73 return 1;
74 }
75
76 if (d->d_name[0] != '.') {
77 if (openreadclose(d->d_name,&text,32) != 1) return 0;
78 if (!stralloc_append(&text,"\n")) return 0;
79
80 fqdn = d->d_name;
81 if (str_equal(fqdn,"@")) fqdn = ".";
82 if (!dns_domain_fromdot(&q,fqdn,str_len(fqdn))) return 0;
83
84 serverslen = 0;
85 j = 0;
86 for (i = 0;i < text.len;++i)
87 if (text.s[i] == '\n') {
88 if (serverslen <= 60)
89 if (ip4_scan(text.s + j,servers + serverslen))
90 serverslen += 4;
91 j = i + 1;
92 }
93 byte_zero(servers + serverslen,64 - serverslen);
94
95 if (!stralloc_catb(&data,q,dns_domain_length(q))) return 0;
96 if (!stralloc_catb(&data,servers,64)) return 0;
97 }
98 }
99 }
100
101 static int init1(void)
102 {
103 DIR *dir;
104 int r;
105
106 if (chdir("servers") == -1) return 0;
107 dir = opendir(".");
108 if (!dir) return 0;
109 r = init2(dir);
110 closedir(dir);
111 return r;
112 }
113
114 int roots_init(void)
115 {
116 int fddir;
117 int r;
118
119 if (!stralloc_copys(&data,"")) return 0;
120
121 fddir = open_read(".");
122 if (fddir == -1) return 0;
123 r = init1();
124 if (fchdir(fddir) == -1) r = 0;
125 close(fddir);
126 return r;
127 }