release
[hcoop/zz_old/debian/djbdns.git] / rbldns-data.c
CommitLineData
dc0d77d7
CE
1#include <stdio.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <unistd.h>
5#include "buffer.h"
6#include "exit.h"
7#include "cdb_make.h"
8#include "open.h"
9#include "stralloc.h"
10#include "getln.h"
11#include "strerr.h"
12#include "byte.h"
13#include "scan.h"
14#include "fmt.h"
15#include "ip4.h"
16
17#define FATAL "rbldns-data: fatal: "
18
19void nomem(void)
20{
21 strerr_die2x(111,FATAL,"out of memory");
22}
23
24int fd;
25buffer b;
26char bspace[1024];
27
28int fdcdb;
29struct cdb_make cdb;
30static stralloc tmp;
31
32static stralloc line;
33int match = 1;
34unsigned long linenum = 0;
35
36char strnum[FMT_ULONG];
37
38void syntaxerror(const char *why)
39{
40 strnum[fmt_ulong(strnum,linenum)] = 0;
41 strerr_die4x(111,FATAL,"unable to parse data line ",strnum,why);
42}
43void die_datatmp(void)
44{
45 strerr_die2sys(111,FATAL,"unable to create data.tmp: ");
46}
47
48int main()
49{
50 char ip[4];
51 unsigned long u;
52 unsigned int j;
53 unsigned int k;
54 char ch;
55
56 umask(022);
57
58 fd = open_read("data");
59 if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
60 buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace);
61
62 fdcdb = open_trunc("data.tmp");
63 if (fdcdb == -1) die_datatmp();
64 if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();
65
66 while (match) {
67 ++linenum;
68 if (getln(&b,&line,&match,'\n') == -1)
69 strerr_die2sys(111,FATAL,"unable to read line: ");
70
71 while (line.len) {
72 ch = line.s[line.len - 1];
73 if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
74 --line.len;
75 }
76 if (!line.len) continue;
77
78 switch(line.s[0]) {
79 default:
80 syntaxerror(": unrecognized leading character");
81 case '#':
82 break;
83 case ':':
84 j = byte_chr(line.s + 1,line.len - 1,':');
85 if (j >= line.len - 1) syntaxerror(": missing colon");
86 if (ip4_scan(line.s + 1,ip) != j) syntaxerror(": malformed IP address");
87 if (!stralloc_copyb(&tmp,ip,4)) nomem();
88 if (!stralloc_catb(&tmp,line.s + j + 2,line.len - j - 2)) nomem();
89 if (cdb_make_add(&cdb,"",0,tmp.s,tmp.len) == -1)
90 die_datatmp();
91 break;
92 case '0': case '1': case '2': case '3': case '4':
93 case '5': case '6': case '7': case '8': case '9':
94 if (!stralloc_0(&line)) nomem();
95 j = 0;
96 if (!stralloc_copys(&tmp,"")) nomem();
97 for (;;) {
98 k = scan_ulong(line.s + j,&u);
99 if (!k) break;
100 ch = u;
101 if (!stralloc_catb(&tmp,&ch,1)) nomem();
102 j += k;
103 if (line.s[j] != '.') break;
104 ++j;
105 }
106 if (!stralloc_catb(&tmp,"\0\0\0\0",4)) nomem();
107 tmp.len = 4;
108 if (line.s[j] == '/')
109 scan_ulong(line.s + j + 1,&u);
110 else
111 u = 32;
112 if (u > 32) u = 32;
113 ch = u;
114 if (!stralloc_catb(&tmp,&ch,1)) nomem();
115 if (cdb_make_add(&cdb,tmp.s,tmp.len,"",0) == -1)
116 die_datatmp();
117 break;
118 }
119 }
120
121 if (cdb_make_finish(&cdb) == -1) die_datatmp();
122 if (fsync(fdcdb) == -1) die_datatmp();
123 if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
124 if (rename("data.tmp","data.cdb") == -1)
125 strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");
126
127 _exit(0);
128}