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: ");