10 #define FATAL "setforward: fatal: "
14 strerr_die1x(100,"setforward: usage: setforward data.cdb data.tmp");
18 strerr_die2x(111,FATAL
,"out of memory");
20 void missingsemicolon()
22 strerr_die2x(100,FATAL
,"final instruction must end with semicolon");
26 strerr_die2x(100,FATAL
,"double colons are not permitted");
30 strerr_die2x(100,FATAL
,"commas are not permitted before colons");
34 strerr_die2x(100,FATAL
,"NUL bytes are not permitted");
38 strerr_die2x(100,FATAL
,"addresses over 800 bytes are not permitted");
47 stralloc target
= {0}; /* always initialized; no NUL */
48 stralloc command
= {0}; /* always initialized; no NUL */
49 stralloc instr
= {0}; /* always initialized */
52 /* 0: reading target; command is empty; instr is empty */
53 /* 1: target is complete; instr still has to be written; reading command */
57 strerr_die4sys(111,FATAL
,"unable to write to ",fntmp
,": ");
60 void doit(prepend
,data
,datalen
)
65 if (!stralloc_copys(&key
,prepend
)) nomem();
66 if (!stralloc_cat(&key
,&target
)) nomem();
67 case_lowerb(key
.s
,key
.len
);
68 if (cdbmss_add(&cdbmss
,key
.s
,key
.len
,data
,datalen
) == -1)
77 r
= substdio_get(subfdinsmall
,ch
,1);
79 strerr_die2sys(111,FATAL
,"unable to read input: ");
90 if (!stralloc_copys(&target
,"")) nomem();
91 if (!stralloc_copys(&command
,"")) nomem();
92 if (!stralloc_copys(&instr
,"")) nomem();
94 fncdb
= argv
[1]; if (!fncdb
) usage();
95 fntmp
= argv
[2]; if (!fntmp
) usage();
97 fd
= open_trunc(fntmp
);
99 strerr_die4sys(111,FATAL
,"unable to create ",fntmp
,": ");
101 if (cdbmss_start(&cdbmss
,fd
) == -1) writeerr();
104 if (!getch(&ch
)) goto eof
;
107 while (ch
!= '\n') if (!getch(&ch
)) goto eof
;
111 if (ch
== ' ') continue;
112 if (ch
== '\n') continue;
113 if (ch
== '\t') continue;
116 if (flagtarget
) extracolon();
121 if ((ch
== ',') || (ch
== ';')) {
122 if (!flagtarget
) extracomma();
124 if (command
.s
[0] == '?') {
125 doit("?",command
.s
+ 1,command
.len
- 1);
127 else if ((command
.s
[0] == '|') || (command
.s
[0] == '!')) {
128 if (!stralloc_cat(&instr
,&command
)) nomem();
129 if (!stralloc_0(&instr
)) nomem();
131 else if ((command
.s
[0] == '.') || (command
.s
[0] == '/')) {
132 if (!stralloc_cat(&instr
,&command
)) nomem();
133 if (!stralloc_0(&instr
)) nomem();
136 if (command
.len
> 800) longaddress();
137 if (command
.s
[0] != '&')
138 if (!stralloc_cats(&instr
,"&")) nomem();
139 if (!stralloc_cat(&instr
,&command
)) nomem();
140 if (!stralloc_0(&instr
)) nomem();
144 if (!stralloc_copys(&command
,"")) nomem();
148 doit(":",instr
.s
,instr
.len
);
150 if (!stralloc_copys(&target
,"")) nomem();
151 if (!stralloc_copys(&instr
,"")) nomem();
157 if (ch
== '\\') if (!getch(&ch
)) goto eof
;
158 if (ch
== 0) nulbyte();
159 if (!stralloc_append(flagtarget ?
&command
: &target
,&ch
)) nomem();
163 if (flagtarget
|| target
.len
)
166 if (cdbmss_finish(&cdbmss
) == -1) writeerr();
167 if (fsync(fd
) == -1) writeerr();
168 if (close(fd
) == -1) writeerr(); /* NFS stupidity */
170 if (rename(fntmp
,fncdb
) == -1)
171 strerr_die6sys(111,FATAL
,"unable to move ",fntmp
," to ",fncdb
,": ");