#include #include #include /* just for rename() */ #include "open.h" #include "strerr.h" #include "cdb_make.h" #include "cdb.h" #include "inbuf.h" #ifdef CDB64 #define FATAL "cdb64make: fatal: " #else #define FATAL "cdbmake: fatal: " #endif static char *fn; static char *fntmp; static void die_usage(void) { strerr_die1x(100,"cdbmake: usage: cdbmake f ftmp"); } static void die_write(void) { strerr_die4sys(111,FATAL,"unable to create ",fntmp,": "); } static void die_read(void) { strerr_die2sys(111,FATAL,"unable to read input: "); } static void die_readformat(void) { strerr_die2x(111,FATAL,"unable to read input: bad format"); } static inline void get(char *ch) { switch(inbuf_GETC(inbuf_0,ch)) { case 0: die_readformat(); case -1: die_read(); } } static struct cdb_make c; int main(int argc,char **argv) { num klen; num dlen; num i; num h; num fd; char ch; if (!*argv) die_usage(); if (!*++argv) die_usage(); fn = *argv; if (!*++argv) die_usage(); fntmp = *argv; fd = open_trunc(fntmp); if (fd == -1) die_write(); if (cdb_make_start(&c,fd) == -1) die_write(); for (;;) { get(&ch); if (ch == '\n') break; if (ch != '+') die_readformat(); klen = 0; for (;;) { get(&ch); if (ch == ',') break; if ((ch < '0') || (ch > '9')) die_readformat(); if (klen > CDB_LIMIT/10) { errno = ENOMEM; die_write(); } klen = klen * 10 + (ch - '0'); if (klen > CDB_LIMIT) { errno = ENOMEM; die_write(); } } dlen = 0; for (;;) { get(&ch); if (ch == ':') break; if ((ch < '0') || (ch > '9')) die_readformat(); if (dlen > CDB_LIMIT/10) { errno = ENOMEM; die_write(); } dlen = dlen * 10 + (ch - '0'); if (dlen > CDB_LIMIT) { errno = ENOMEM; die_write(); } } if (cdb_make_addbegin(&c,klen,dlen) == -1) die_write(); h = CDB_HASHSTART; for (i = 0;i < klen;++i) { get(&ch); if (outbuf_PUTC(&c.b,ch) == -1) die_write(); h = cdb_hashadd(h,ch); } get(&ch); if (ch != '-') die_readformat(); get(&ch); if (ch != '>') die_readformat(); for (i = 0;i < dlen;++i) { get(&ch); if (outbuf_PUTC(&c.b,ch) == -1) die_write(); } if (cdb_make_addend(&c,klen,dlen,h) == -1) die_write(); get(&ch); if (ch != '\n') die_readformat(); } if (cdb_make_finish(&c) == -1) die_write(); if (fsync(fd) == -1) die_write(); if (close(fd) == -1) die_write(); /* NFS silliness */ if (rename(fntmp,fn) == -1) strerr_die6sys(111,FATAL,"unable to rename ",fntmp," to ",fn,": "); _exit(0); return 0; }