diff options
Diffstat (limited to 'lib/tdb/tools/tdbdump.c')
-rw-r--r-- | lib/tdb/tools/tdbdump.c | 285 |
1 files changed, 1 insertions, 284 deletions
diff --git a/lib/tdb/tools/tdbdump.c b/lib/tdb/tools/tdbdump.c index aa5054023a7..9a0a7fe6d49 100644 --- a/lib/tdb/tools/tdbdump.c +++ b/lib/tdb/tools/tdbdump.c @@ -23,7 +23,6 @@ #include "system/filesys.h" #include "system/wait.h" #include "tdb.h" -#include <regex.h> static void print_data(TDB_DATA d) { @@ -135,293 +134,18 @@ static int dump_tdb(const char *fname, const char *keyname, bool emergency) return 0; } -static bool file_parse_lines(FILE *f, - bool (*cb)(char *buf, size_t buflen, - void *private_data), - void *private_data) -{ - char *buf; - size_t buflen; - - buflen = 1024; - buf = malloc(1024); - if (buf == NULL) { - return false; - } - - while (true) { - size_t pos = 0; - int c; - bool ok; - - while ((c = fgetc(f)) != EOF) { - - buf[pos++] = c; - - if (pos == (buflen-1)) { - char *tmp; - tmp = realloc(buf, buflen*2); - if (tmp == NULL) { - free(buf); - return false; - } - buf = tmp; - buflen *= 2; - } - - if (c == '\n') { - break; - } - } - - if (c == EOF) { - free(buf); - return (pos == 0); - } - - buf[pos] = '\0'; - - ok = cb(buf, buflen, private_data); - if (!ok) { - break; - } - } - free(buf); - return true; -} - -struct undump_state { - struct tdb_context *tdb; - TDB_DATA key; - TDB_DATA data; - int line; -}; - -static ssize_t match_len(const regmatch_t *m, size_t buflen) -{ - if ((m->rm_eo < m->rm_so) || - (m->rm_eo > buflen) || (m->rm_so > buflen)) { - return -1; - } - return m->rm_eo - m->rm_so; -} - -static int nibble(char c) -{ - if ((c >= '0') && (c <= '9')) { - return c - '0'; - } - if ((c >= 'A') && (c <= 'F')) { - return c - 'A' + 10; - } - if ((c >= 'a') && (c <= 'f')) { - return c - 'a' + 10; - } - return -1; -} - -static bool undump_regmatch(int line, char *buf, size_t buflen, - const regmatch_t *nummatch, - const regmatch_t *datamatch, - TDB_DATA *pret) -{ - ssize_t numlen = match_len(nummatch, buflen); - ssize_t datalen = match_len(datamatch, buflen); - long long num; - size_t col; - - TDB_DATA ret = {0}; - - if ((numlen == -1) || (datalen == -1)) { - fprintf(stderr, "No matches in line %d\n", line); - return false; - } - - { - char numbuf[numlen+1]; - memcpy(numbuf, buf+nummatch->rm_so, numlen); - numbuf[numlen] = '\0'; - num = atoll(numbuf); - } - - if (num == 0) { - *pret = ret; - return true; - } - - ret.dptr = malloc(datalen); - if (ret.dptr == NULL) { - fprintf(stderr, "malloc failed for line %d\n", line); - return false; - } - - col = datamatch->rm_so; - while (col < datamatch->rm_eo) { - int n; - - if (buf[col] != '\\') { - ret.dptr[ret.dsize++] = buf[col++]; - continue; - } - - if ((datamatch->rm_eo - col) < 3) { - fprintf(stderr, "hex char too short in line %d, " - "col %d\n", line, (int)col); - goto fail; - } - - n = nibble(buf[col+1]); - if (n == -1) { - fprintf(stderr, "Could not convert '%c' in line %d " - "col %d\n", buf[col+1], line, (int)col); - goto fail; - } - ret.dptr[ret.dsize] = n << 4; - - n = nibble(buf[col+2]); - if (n == -1) { - fprintf(stderr, "Could not convert '%c' in line %d, " - "col %d\n", buf[col+2], line, (int)col); - goto fail; - } - ret.dptr[ret.dsize] |= n; - - ret.dsize += 1; - col += 3; - } - - if (ret.dsize != num) { - fprintf(stderr, "Expected %d chars, got %d in line %d\n", - (int)num, (int)ret.dsize, line); - goto fail; - } - - *pret = ret; - return true; - -fail: - free(ret.dptr); - return false; -} - -static bool undump_cb(char *buf, size_t buflen, void *private_data) -{ - struct undump_state *state = private_data; - regex_t regex; - regmatch_t matches[3]; - int ret; - bool ok; - - state->line++; - - ret = regcomp(®ex, "^key(\\([[:digit:]]*\\)) = \"\\(.*\\)\"\n$", 0); - if (ret != 0) { - return false; - } - - ret = regexec(®ex, buf, 3, matches, 0); - if (ret == 0) { - if (state->key.dsize != 0) { - fprintf(stderr, "line %d has duplicate key\n", - state->line); - regfree(®ex); - return false; - } - ok = undump_regmatch(state->line, buf, buflen, - &matches[1], &matches[2], - &state->key); - if (!ok) { - regfree(®ex); - return false; - } - } - regfree(®ex); - - ret = regcomp(®ex, "^data(\\([[:digit:]]*\\)) = \"\\(.*\\)\"\n$", - 0); - if (ret != 0) { - return false; - } - - ret = regexec(®ex, buf, 3, matches, 0); - if (ret == 0) { - if (state->key.dsize == 0) { - fprintf(stderr, "line %d has data without key\n", - state->line); - regfree(®ex); - return false; - } - if (state->data.dsize != 0) { - fprintf(stderr, "line %d has duplicate data\n", - state->line); - regfree(®ex); - return false; - } - ok = undump_regmatch(state->line, buf, buflen, - &matches[1], &matches[2], - &state->data); - if (!ok) { - return false; - } - - ret = tdb_store(state->tdb, state->key, state->data, 0); - - free(state->key.dptr); - state->key = (TDB_DATA) {0}; - - free(state->data.dptr); - state->data = (TDB_DATA) {0}; - - if (ret == -1) { - fprintf(stderr, "tdb_store for line %d failed: %s\n", - state->line, tdb_errorstr(state->tdb)); - return false; - } - } - - regfree(®ex); - - return true; -} - -static int undump_tdb(const char *fname) -{ - struct tdb_logging_context logfn = { log_stderr }; - struct undump_state state = {0}; - bool ok; - - state.tdb = tdb_open_ex(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600, - &logfn, NULL); - if (state.tdb == NULL) { - printf("Failed to open %s\n", fname); - return 1; - } - - ok = file_parse_lines(stdin, undump_cb, &state); - if (!ok) { - printf("Failed to parse stdin\n"); - return 1; - } - - tdb_close(state.tdb); - - return 0; -} - static void usage( void) { printf( "Usage: tdbdump [options] <filename>\n\n"); printf( " -h this help message\n"); printf( " -k keyname dumps value of keyname\n"); printf( " -e emergency dump, for corrupt databases\n"); - printf( " -u undump stdin\n"); } int main(int argc, char *argv[]) { char *fname, *keyname=NULL; bool emergency = false; - bool undump = false; int c; if (argc < 2) { @@ -429,7 +153,7 @@ static void usage( void) exit(1); } - while ((c = getopt( argc, argv, "hk:eu")) != -1) { + while ((c = getopt( argc, argv, "hk:e")) != -1) { switch (c) { case 'h': usage(); @@ -440,9 +164,6 @@ static void usage( void) case 'e': emergency = true; break; - case 'u': - undump = true; - break; default: usage(); exit( 1); @@ -451,9 +172,5 @@ static void usage( void) fname = argv[optind]; - if (undump) { - return undump_tdb(fname); - } - return dump_tdb(fname, keyname, emergency); } |