Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ndb.h>
5 #include <ip.h>
6 #include "dns.h"
8 Area *owned;
9 Area *delegated;
11 /*
12 * true if a name is in our area
13 */
14 Area*
15 inmyarea(char *name)
16 {
17 int len;
18 Area *s, *d;
20 len = strlen(name);
21 for(s = owned; s; s = s->next){
22 if(s->len > len)
23 continue;
24 if(cistrcmp(s->soarr->owner->name, name + len - s->len) == 0)
25 if(len == s->len || name[len - s->len - 1] == '.')
26 break;
27 }
28 if(s == 0)
29 return 0;
31 for(d = delegated; d; d = d->next){
32 if(d->len > len)
33 continue;
34 if(cistrcmp(d->soarr->owner->name, name + len - d->len) == 0)
35 if(len == d->len || name[len - d->len - 1] == '.')
36 return 0;
37 }
39 return s;
40 }
42 /*
43 * our area is the part of the domain tree that
44 * we serve
45 */
46 void
47 addarea(DN *dp, RR *rp, Ndbtuple *t)
48 {
49 Area **l, *s;
51 if(t->val[0])
52 l = &delegated;
53 else
54 l = &owned;
56 /*
57 * The area contains a copy of the soa rr that created it.
58 * The owner of the the soa rr should stick around as long
59 * as the area does.
60 */
61 s = emalloc(sizeof(*s));
62 s->len = strlen(dp->name);
63 rrcopy(rp, &s->soarr);
64 s->soarr->owner = dp;
65 s->soarr->db = 1;
66 s->soarr->ttl = Hour;
67 s->neednotify = 1;
68 s->needrefresh = 0;
70 syslog(0, logfile, "new area %s", dp->name);
72 s->next = *l;
73 *l = s;
74 }
76 void
77 freearea(Area **l)
78 {
79 Area *s;
81 while(s = *l){
82 *l = s->next;
83 rrfree(s->soarr);
84 free(s);
85 }
86 }
88 /*
89 * refresh all areas that need it
90 * this entails running a command 'zonerefreshprogram'. This could
91 * copy over databases from elsewhere or just do a zone transfer.
92 */
93 void
94 refresh_areas(Area *s)
95 {
96 int pid;
97 Waitmsg *w;
99 for(; s != nil; s = s->next){
100 if(!s->needrefresh)
101 continue;
103 if(zonerefreshprogram == nil){
104 s->needrefresh = 0;
105 continue;
108 switch(pid = fork()){
109 case -1:
110 break;
111 case 0:
112 execl(zonerefreshprogram, "zonerefresh", s->soarr->owner->name, 0);
113 exits(0);
114 break;
115 default:
116 for(;;){
117 w = wait();
118 if(w == nil)
119 break;
120 if(w->pid == pid){
121 if(w->msg == nil || *w->msg == 0)
122 s->needrefresh = 0;
123 free(w);
124 break;
126 free(w);