mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
Revert "tdb: Add tdbdump -u"
This reverts commit ea53e86c25
.
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Fri Sep 18 14:03:12 CEST 2015 on sn-devel-104
This commit is contained in:
parent
6ce3643e45
commit
a36a734717
@ -22,7 +22,6 @@
|
||||
<command>tdbdump</command>
|
||||
<arg choice="opt">-k <replaceable>keyname</replaceable></arg>
|
||||
<arg choice="opt">-e</arg>
|
||||
<arg choice="opt">-u</arg>
|
||||
<arg choice="opt">-h</arg>
|
||||
<arg choice="req">filename</arg>
|
||||
</cmdsynopsis>
|
||||
@ -70,14 +69,6 @@
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-u</term>
|
||||
<listitem><para>
|
||||
'Undumps' a database, turning the tdbdump output on stdin
|
||||
into a tdb again.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user