|
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 } |