|
0
|
1 |
#include "error.h"
|
|
|
2 |
#include "open.h"
|
|
|
3 |
#include "strerr.h"
|
|
|
4 |
#include "cdb_make.h"
|
|
|
5 |
#include "cdb.h"
|
|
|
6 |
|
|
|
7 |
#define FATAL "cdbmake: fatal: "
|
|
|
8 |
|
|
|
9 |
char *fn;
|
|
|
10 |
char *fntmp;
|
|
|
11 |
|
|
|
12 |
void die_usage(void)
|
|
|
13 |
{
|
|
|
14 |
strerr_die1x(100,"cdbmake: usage: cdbmake f ftmp");
|
|
|
15 |
}
|
|
|
16 |
void die_write(void)
|
|
|
17 |
{
|
|
|
18 |
strerr_die4sys(111,FATAL,"unable to create ",fntmp,": ");
|
|
|
19 |
}
|
|
|
20 |
void die_read(void)
|
|
|
21 |
{
|
|
|
22 |
strerr_die2sys(111,FATAL,"unable to read input: ");
|
|
|
23 |
}
|
|
|
24 |
void die_readformat(void)
|
|
|
25 |
{
|
|
|
26 |
strerr_die2x(111,FATAL,"unable to read input: bad format");
|
|
|
27 |
}
|
|
|
28 |
|
|
|
29 |
inline void get(char *ch)
|
|
|
30 |
{
|
|
|
31 |
switch(buffer_GETC(buffer_0,ch)) {
|
|
|
32 |
case 0: die_readformat();
|
|
|
33 |
case -1: die_read();
|
|
|
34 |
}
|
|
|
35 |
}
|
|
|
36 |
|
|
|
37 |
static struct cdb_make c;
|
|
|
38 |
|
|
|
39 |
main(int argc,char **argv)
|
|
|
40 |
{
|
|
|
41 |
unsigned int klen;
|
|
|
42 |
unsigned int dlen;
|
|
|
43 |
unsigned int i;
|
|
|
44 |
uint32 h;
|
|
|
45 |
int fd;
|
|
|
46 |
char ch;
|
|
|
47 |
|
|
|
48 |
if (!*argv) die_usage();
|
|
|
49 |
|
|
|
50 |
if (!*++argv) die_usage();
|
|
|
51 |
fn = *argv;
|
|
|
52 |
|
|
|
53 |
if (!*++argv) die_usage();
|
|
|
54 |
fntmp = *argv;
|
|
|
55 |
|
|
|
56 |
fd = open_trunc(fntmp);
|
|
|
57 |
if (fd == -1) die_write();
|
|
|
58 |
|
|
|
59 |
if (cdb_make_start(&c,fd) == -1) die_write();
|
|
|
60 |
|
|
|
61 |
for (;;) {
|
|
|
62 |
get(&ch);
|
|
|
63 |
if (ch == '\n') break;
|
|
|
64 |
if (ch != '+') die_readformat();
|
|
|
65 |
klen = 0;
|
|
|
66 |
for (;;) {
|
|
|
67 |
get(&ch);
|
|
|
68 |
if (ch == ',') break;
|
|
|
69 |
if ((ch < '0') || (ch > '9')) die_readformat();
|
|
|
70 |
if (klen > 429496720) { errno = error_nomem; die_write(); }
|
|
|
71 |
klen = klen * 10 + (ch - '0');
|
|
|
72 |
}
|
|
|
73 |
dlen = 0;
|
|
|
74 |
for (;;) {
|
|
|
75 |
get(&ch);
|
|
|
76 |
if (ch == ':') break;
|
|
|
77 |
if ((ch < '0') || (ch > '9')) die_readformat();
|
|
|
78 |
if (dlen > 429496720) { errno = error_nomem; die_write(); }
|
|
|
79 |
dlen = dlen * 10 + (ch - '0');
|
|
|
80 |
}
|
|
|
81 |
|
|
|
82 |
if (cdb_make_addbegin(&c,klen,dlen) == -1) die_write();
|
|
|
83 |
h = CDB_HASHSTART;
|
|
|
84 |
for (i = 0;i < klen;++i) {
|
|
|
85 |
get(&ch);
|
|
|
86 |
if (buffer_PUTC(&c.b,ch) == -1) die_write();
|
|
|
87 |
h = cdb_hashadd(h,ch);
|
|
|
88 |
}
|
|
|
89 |
get(&ch);
|
|
|
90 |
if (ch != '-') die_readformat();
|
|
|
91 |
get(&ch);
|
|
|
92 |
if (ch != '>') die_readformat();
|
|
|
93 |
for (i = 0;i < dlen;++i) {
|
|
|
94 |
get(&ch);
|
|
|
95 |
if (buffer_PUTC(&c.b,ch) == -1) die_write();
|
|
|
96 |
}
|
|
|
97 |
if (cdb_make_addend(&c,klen,dlen,h) == -1) die_write();
|
|
|
98 |
|
|
|
99 |
get(&ch);
|
|
|
100 |
if (ch != '\n') die_readformat();
|
|
|
101 |
}
|
|
|
102 |
|
|
|
103 |
if (cdb_make_finish(&c) == -1) die_write();
|
|
|
104 |
if (fsync(fd) == -1) die_write();
|
|
|
105 |
if (close(fd) == -1) die_write(); /* NFS silliness */
|
|
|
106 |
if (rename(fntmp,fn) == -1)
|
|
|
107 |
strerr_die6sys(111,FATAL,"unable to rename ",fntmp," to ",fn,": ");
|
|
|
108 |
|
|
|
109 |
_exit(0);
|
|
|
110 |
}
|