release
[hcoop/zz_old/debian/djbdns.git] / roots.c
CommitLineData
dc0d77d7
CE
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
13static stralloc data;
14
15static 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
30static 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
43int 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
52int roots_same(char *q,char *q2)
53{
54 return roots_search(q) == roots_search(q2);
55}
56
57static 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
101static 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
114int 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}