10
#include "gen_allocdefs.h"
22
#define FATAL "pickdns-data: fatal: "
26
strerr_die2x(111,FATAL,"out of memory");
29
void ipprefix_cat(stralloc *out,char *s)
43
if (!stralloc_catb(out,&ch,1)) nomem();
54
int address_diff(struct address *p,struct address *q)
58
r = byte_diff(p->location,2,q->location);
61
if (p->namelen < q->namelen) return -1;
62
if (p->namelen > q->namelen) return 1;
63
return case_diffb(p->name,p->namelen,q->name);
66
void address_sort(struct address *z,unsigned int n)
78
if (i > 1) { --i; t = z[i]; }
79
else { t = z[j]; z[j] = z[i]; --j; }
81
while ((p = q * 2) < j) {
82
if (address_diff(&z[p + 1],&z[p]) >= 0) ++p;
88
while ((q > i) && (address_diff(&t,&z[p = q/2]) > 0)) {
95
GEN_ALLOC_typedef(address_alloc,struct address,s,len,a)
96
GEN_ALLOC_readyplus(address_alloc,struct address,s,len,a,i,n,x,30,address_alloc_readyplus)
97
GEN_ALLOC_append(address_alloc,struct address,s,len,a,i,n,x,30,address_alloc_readyplus,address_alloc_append)
99
static address_alloc x;
108
static stralloc result;
110
static stralloc line;
112
unsigned long linenum = 0;
115
static stralloc f[NUMFIELDS];
117
char strnum[FMT_ULONG];
119
void syntaxerror(const char *why)
121
strnum[fmt_ulong(strnum,linenum)] = 0;
122
strerr_die4x(111,FATAL,"unable to parse data line ",strnum,why);
124
void die_datatmp(void)
126
strerr_die2sys(111,FATAL,"unable to create data.tmp: ");
139
if (!address_alloc_readyplus(&x,0)) nomem();
141
fd = open_read("data");
142
if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
143
buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace);
145
fdcdb = open_trunc("data.tmp");
146
if (fdcdb == -1) die_datatmp();
147
if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();
151
if (getln(&b,&line,&match,'\n') == -1)
152
strerr_die2sys(111,FATAL,"unable to read line: ");
155
ch = line.s[line.len - 1];
156
if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
159
if (!line.len) continue;
162
for (i = 0;i < NUMFIELDS;++i) {
164
if (!stralloc_copys(&f[i],"")) nomem();
167
k = byte_chr(line.s + j,line.len - j,':');
168
if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
175
syntaxerror(": unrecognized leading character");
181
byte_zero(&t,sizeof t);
182
if (!dns_domain_fromdot(&t.name,f[0].s,f[0].len)) nomem();
183
t.namelen = dns_domain_length(t.name);
184
case_lowerb(t.name,t.namelen);
185
if (!stralloc_0(&f[1])) nomem();
186
if (!ip4_scan(f[1].s,t.ip)) syntaxerror(": malformed IP address");
187
if (!stralloc_0(&f[2])) nomem();
188
if (!stralloc_0(&f[2])) nomem();
189
byte_copy(t.location,2,f[2].s);
190
if (!address_alloc_append(&x,&t)) nomem();
193
if (!stralloc_0(&f[0])) nomem();
194
if (!stralloc_0(&f[0])) nomem();
195
if (!stralloc_copyb(&result,f[0].s,2)) nomem();
196
if (!stralloc_0(&f[1])) nomem();
197
if (!stralloc_copys(&key,"%")) nomem();
198
ipprefix_cat(&key,f[1].s);
199
if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1)
206
address_sort(x.s,x.len);
210
for (j = i + 1;j < x.len;++j)
211
if (address_diff(x.s + i,x.s + j))
213
if (!stralloc_copys(&key,"+")) nomem();
214
if (!stralloc_catb(&key,x.s[i].location,2)) nomem();
215
if (!stralloc_catb(&key,x.s[i].name,x.s[i].namelen)) nomem();
216
if (!stralloc_copys(&result,"")) nomem();
218
if (!stralloc_catb(&result,x.s[i++].ip,4)) nomem();
219
if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1)
223
if (cdb_make_finish(&cdb) == -1) die_datatmp();
224
if (fsync(fdcdb) == -1) die_datatmp();
225
if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
226
if (rename("data.tmp","data.cdb") == -1)
227
strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");