From a18b522f2b64adb9c1d0f63b3628a0f82a0b3449 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Apr 2007 07:04:37 +0000 Subject: r22052: merge tdbtool from samba3 and build it metze (This used to be commit f471e752161e392ef7324df30517af1818a27d1d) --- source4/lib/tdb/config.mk | 1 - source4/lib/tdb/tools/tdbtool.c | 646 ++++++++++++++++++++++++---------------- 2 files changed, 395 insertions(+), 252 deletions(-) (limited to 'source4') diff --git a/source4/lib/tdb/config.mk b/source4/lib/tdb/config.mk index 0162b78381..24e9de744c 100644 --- a/source4/lib/tdb/config.mk +++ b/source4/lib/tdb/config.mk @@ -18,7 +18,6 @@ PUBLIC_HEADERS = include/tdb.h # Start BINARY tdbtool [BINARY::tdbtool] INSTALLDIR = BINDIR -ENABLE = NO OBJ_FILES= \ tools/tdbtool.o PRIVATE_DEPENDENCIES = \ diff --git a/source4/lib/tdb/tools/tdbtool.c b/source4/lib/tdb/tools/tdbtool.c index de0ecdd7ca..4998ff7323 100644 --- a/source4/lib/tdb/tools/tdbtool.c +++ b/source4/lib/tdb/tools/tdbtool.c @@ -21,26 +21,80 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" #include "tdb.h" +#include "pstring.h" + +static int do_command(void); +const char *cmdname; +char *arg1, *arg2; +size_t arg1len, arg2len; +int do_connections; +int bIterate = 0; +char *line; +TDB_DATA iterate_kbuf; +char cmdline[1024]; + +enum commands { + CMD_CREATE_TDB, + CMD_OPEN_TDB, + CMD_ERASE, + CMD_DUMP, + CMD_CDUMP, + CMD_INSERT, + CMD_MOVE, + CMD_STORE, + CMD_SHOW, + CMD_KEYS, + CMD_HEXKEYS, + CMD_DELETE, + CMD_LIST_HASH_FREE, + CMD_LIST_FREE, + CMD_INFO, + CMD_FIRST, + CMD_NEXT, + CMD_SYSTEM, + CMD_QUIT, + CMD_HELP +}; + +typedef struct { + const char *name; + enum commands cmd; +} COMMAND_TABLE; + +COMMAND_TABLE cmd_table[] = { + {"create", CMD_CREATE_TDB}, + {"open", CMD_OPEN_TDB}, + {"erase", CMD_ERASE}, + {"dump", CMD_DUMP}, + {"cdump", CMD_CDUMP}, + {"insert", CMD_INSERT}, + {"move", CMD_MOVE}, + {"store", CMD_STORE}, + {"show", CMD_SHOW}, + {"keys", CMD_KEYS}, + {"hexkeys", CMD_HEXKEYS}, + {"delete", CMD_DELETE}, + {"list", CMD_LIST_HASH_FREE}, + {"free", CMD_LIST_FREE}, + {"info", CMD_INFO}, + {"first", CMD_FIRST}, + {"1", CMD_FIRST}, + {"next", CMD_NEXT}, + {"n", CMD_NEXT}, + {"quit", CMD_QUIT}, + {"q", CMD_QUIT}, + {"!", CMD_SYSTEM}, + {NULL, CMD_HELP} +}; /* a tdb tool for manipulating a tdb database */ -#define FSTRING_LEN 256 -typedef char fstring[FSTRING_LEN]; +/* these are taken from smb.h - make sure they are in sync */ typedef struct connections_key { pid_t pid; @@ -56,15 +110,20 @@ typedef struct connections_data { gid_t gid; char name[24]; char addr[24]; - char machine[128]; + char machine[FSTRING_LEN]; time_t start; + unsigned bcast_msg_flags; } connections_data; -static struct tdb_context *tdb; +static TDB_CONTEXT *tdb; -static int print_rec(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); +static int print_crec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); +static int print_arec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); +static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); +static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); +static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); -static void print_asc(unsigned char *buf,int len) +static void print_asc(const char *buf,int len) { int i; @@ -78,20 +137,7 @@ static void print_asc(unsigned char *buf,int len) printf("%c",isprint(buf[i])?buf[i]:'.'); } -#ifdef PRINTF_ATTRIBUTE -static void tdb_log(struct tdb_context *t, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log(struct tdb_context *t, enum tdb_debug_level level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -} - -static void print_data(unsigned char *buf,int len) +static void print_data(const char *buf,int len) { int i=0; if (len<=0) return; @@ -131,6 +177,10 @@ static void help(void) " open dbname : open an existing database\n" " erase : erase the database\n" " dump : dump the database as strings\n" +" cdump : dump the database as connection records\n" +" keys : dump the database keys as strings\n" +" hexkeys : dump the database keys as hex values\n" +" info : print summary info about the database\n" " insert key data : insert a record\n" " move key file : move a record to a destination tdb\n" " store key data : store a record (replace)\n" @@ -138,6 +188,7 @@ static void help(void) " delete key : delete a record by key\n" " list : print the database hash table and freelist\n" " free : print the database freelist\n" +" ! command : execute system command\n" " 1 | first : print the first record\n" " n | next : print the next record\n" " q | quit : terminate\n" @@ -150,110 +201,62 @@ static void terror(const char *why) printf("%s\n", why); } -static char *get_token(int startover) -{ - static char tmp[1024]; - static char *cont = NULL; - char *insert, *start; - char *k = strtok(NULL, " "); - - if (!k) - return NULL; - - if (startover) - start = tmp; - else - start = cont; - - strcpy(start, k); - insert = start + strlen(start) - 1; - while (*insert == '\\') { - *insert++ = ' '; - k = strtok(NULL, " "); - if (!k) - break; - strcpy(insert, k); - insert = start + strlen(start) - 1; - } - - /* Get ready for next call */ - cont = start + strlen(start) + 1; - return start; -} - -static void create_tdb(void) +static void create_tdb(const char *tdbname) { - char *tok = get_token(1); - - struct tdb_logging_context log_ctx; - log_ctx.log_fn = tdb_log; - - if (!tok) { - help(); - return; - } if (tdb) tdb_close(tdb); - tdb = tdb_open_ex(tok, 0, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT | O_TRUNC, 0600, &log_ctx, NULL); + tdb = tdb_open(tdbname, 0, TDB_CLEAR_IF_FIRST, + O_RDWR | O_CREAT | O_TRUNC, 0600); if (!tdb) { - printf("Could not create %s: %s\n", tok, strerror(errno)); + printf("Could not create %s: %s\n", tdbname, strerror(errno)); } } -static void open_tdb(void) +static void open_tdb(const char *tdbname) { - struct tdb_logging_context log_ctx; - char *tok = get_token(1); - - log_ctx.log_fn = tdb_log; - - if (!tok) { - help(); - return; - } if (tdb) tdb_close(tdb); - tdb = tdb_open_ex(tok, 0, 0, O_RDWR, 0600, &log_ctx, NULL); + tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600); if (!tdb) { - printf("Could not open %s: %s\n", tok, strerror(errno)); + printf("Could not open %s: %s\n", tdbname, strerror(errno)); } } -static void insert_tdb(void) +static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) { - char *k = get_token(1); - char *d = get_token(0); TDB_DATA key, dbuf; - if (!k || !d) { - help(); + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); return; } - key.dptr = (unsigned char *)k; - key.dsize = strlen(k)+1; - dbuf.dptr = (unsigned char *)d; - dbuf.dsize = strlen(d)+1; + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; + dbuf.dptr = (unsigned char *)data; + dbuf.dsize = datalen; if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) { terror("insert failed"); } } -static void store_tdb(void) +static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) { - char *k = get_token(1); - char *d = get_token(0); TDB_DATA key, dbuf; - if (!k || !d) { - help(); + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); return; } - key.dptr = (unsigned char *)k; - key.dsize = strlen(k)+1; - dbuf.dptr = (unsigned char *)d; - dbuf.dsize = strlen(d)+1; + if ((data == NULL) || (datalen == 0)) { + terror("need data"); + return; + } + + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; + dbuf.dptr = (unsigned char *)data; + dbuf.dsize = datalen; printf("Storing key:\n"); print_rec(tdb, key, dbuf, NULL); @@ -263,32 +266,24 @@ static void store_tdb(void) } } -static void show_tdb(void) +static void show_tdb(char *keyname, size_t keylen) { - char *k = get_token(1); TDB_DATA key, dbuf; - if (!k) { - help(); + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); return; } - key.dptr = (unsigned char *)k; - key.dsize = strlen(k)+1; + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) { - /* maybe it is non-NULL terminated key? */ - key.dsize = strlen(k); - dbuf = tdb_fetch(tdb, key); - - if ( !dbuf.dptr ) { - terror("fetch failed"); - return; - } + terror("fetch failed"); + return; } - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ print_rec(tdb, key, dbuf, NULL); free( dbuf.dptr ); @@ -296,62 +291,50 @@ static void show_tdb(void) return; } -static void delete_tdb(void) +static void delete_tdb(char *keyname, size_t keylen) { - char *k = get_token(1); TDB_DATA key; - if (!k) { - help(); + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); return; } - key.dptr = (unsigned char *)k; - key.dsize = strlen(k)+1; + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; if (tdb_delete(tdb, key) != 0) { terror("delete failed"); } } -static void move_rec(void) +static void move_rec(char *keyname, size_t keylen, char* tdbname) { - char *k = get_token(1); - char *file = get_token(0); TDB_DATA key, dbuf; - struct tdb_context *dst_tdb; - - struct tdb_logging_context log_ctx; - log_ctx.log_fn = tdb_log; + TDB_CONTEXT *dst_tdb; - if (!k) { - help(); + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); return; } - - if ( !file ) { + + if ( !tdbname ) { terror("need destination tdb name"); return; } - key.dptr = (unsigned char *)k; - key.dsize = strlen(k)+1; + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) { - /* maybe it is non-NULL terminated key? */ - key.dsize = strlen(k); - dbuf = tdb_fetch(tdb, key); - - if ( !dbuf.dptr ) { - terror("fetch failed"); - return; - } + terror("fetch failed"); + return; } print_rec(tdb, key, dbuf, NULL); - dst_tdb = tdb_open_ex(file, 0, 0, O_RDWR, 0600, &log_ctx, NULL); + dst_tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600); if ( !dst_tdb ) { terror("unable to open destination tdb"); return; @@ -368,25 +351,76 @@ static void move_rec(void) return; } -static int print_rec(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +static int print_conn_key(TDB_DATA key) +{ + printf( "\nkey %d bytes\n", (int)key.dsize); + printf( "pid =%5d ", ((connections_key*)key.dptr)->pid); + printf( "cnum =%10d ", ((connections_key*)key.dptr)->cnum); + printf( "name =[%s]\n", ((connections_key*)key.dptr)->name); + return 0; +} + +static int print_conn_data(TDB_DATA dbuf) { - printf("\nkey %d bytes\n", key.dsize); - print_asc(key.dptr, key.dsize); - printf("\ndata %d bytes\n", dbuf.dsize); - print_data(dbuf.dptr, dbuf.dsize); + printf( "\ndata %d bytes\n", (int)dbuf.dsize); + printf( "pid =%5d ", ((connections_data*)dbuf.dptr)->pid); + printf( "cnum =%10d ", ((connections_data*)dbuf.dptr)->cnum); + printf( "name =[%s]\n", ((connections_data*)dbuf.dptr)->name); + + printf( "uid =%5d ", ((connections_data*)dbuf.dptr)->uid); + printf( "addr =[%s]\n", ((connections_data*)dbuf.dptr)->addr); + printf( "gid =%5d ", ((connections_data*)dbuf.dptr)->gid); + printf( "machine=[%s]\n", ((connections_data*)dbuf.dptr)->machine); + printf( "start = %s\n", ctime(&((connections_data*)dbuf.dptr)->start)); + printf( "magic = 0x%x ", ((connections_data*)dbuf.dptr)->magic); + printf( "flags = 0x%x\n", ((connections_data*)dbuf.dptr)->bcast_msg_flags); return 0; } -static int print_key(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { - print_asc(key.dptr, key.dsize); + if (do_connections && (dbuf.dsize == sizeof(connections_data))) + print_crec(the_tdb, key, dbuf, state); + else + print_arec(the_tdb, key, dbuf, state); + return 0; +} + +static int print_crec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + print_conn_key(key); + print_conn_data(dbuf); + return 0; +} + +static int print_arec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + printf("\nkey %d bytes\n", (int)key.dsize); + print_asc((const char *)key.dptr, key.dsize); + printf("\ndata %d bytes\n", (int)dbuf.dsize); + print_data((const char *)dbuf.dptr, dbuf.dsize); + return 0; +} + +static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + printf("key %d bytes: ", (int)key.dsize); + print_asc((const char *)key.dptr, key.dsize); + printf("\n"); + return 0; +} + +static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + printf("key %d bytes\n", (int)key.dsize); + print_data((const char *)key.dptr, key.dsize); printf("\n"); return 0; } static int total_bytes; -static int traverse_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { total_bytes += dbuf.dsize; return 0; @@ -396,7 +430,7 @@ static void info_tdb(void) { int count; total_bytes = 0; - if ((count = tdb_traverse(tdb, traverse_fn, NULL) == -1)) + if ((count = tdb_traverse(tdb, traverse_fn, NULL)) == -1) printf("Error = %s\n", tdb_errorstr(tdb)); else printf("%d records totalling %d bytes\n", count, total_bytes); @@ -404,23 +438,23 @@ static void info_tdb(void) static char *tdb_getline(const char *prompt) { - static char line[1024]; + static char thisline[1024]; char *p; fputs(prompt, stdout); - line[0] = 0; - p = fgets(line, sizeof(line)-1, stdin); + thisline[0] = 0; + p = fgets(thisline, sizeof(thisline)-1, stdin); if (p) p = strchr(p, '\n'); if (p) *p = 0; - return p?line:NULL; + return p?thisline:NULL; } -static int do_delete_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, +static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { return tdb_delete(the_tdb, key); } -static void first_record(struct tdb_context *the_tdb, TDB_DATA *pkey) +static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) { TDB_DATA dbuf; *pkey = tdb_firstkey(the_tdb); @@ -428,12 +462,11 @@ static void first_record(struct tdb_context *the_tdb, TDB_DATA *pkey) dbuf = tdb_fetch(the_tdb, *pkey); if (!dbuf.dptr) terror("fetch failed"); else { - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ print_rec(the_tdb, *pkey, dbuf, NULL); } } -static void next_record(struct tdb_context *the_tdb, TDB_DATA *pkey) +static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) { TDB_DATA dbuf; *pkey = tdb_nextkey(the_tdb, *pkey); @@ -442,98 +475,209 @@ static void next_record(struct tdb_context *the_tdb, TDB_DATA *pkey) if (!dbuf.dptr) terror("fetch failed"); else - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ print_rec(the_tdb, *pkey, dbuf, NULL); } +static int do_command(void) +{ + COMMAND_TABLE *ctp = cmd_table; + enum commands mycmd = CMD_HELP; + int cmd_len; + + do_connections = 0; + + if (cmdname && strlen(cmdname) == 0) { + mycmd = CMD_NEXT; + } else { + while (ctp->name) { + cmd_len = strlen(ctp->name); + if (strncmp(ctp->name,cmdname,cmd_len) == 0) { + mycmd = ctp->cmd; + break; + } + ctp++; + } + } + + switch (mycmd) { + case CMD_CREATE_TDB: + bIterate = 0; + create_tdb(arg1); + return 0; + case CMD_OPEN_TDB: + bIterate = 0; + open_tdb(arg1); + return 0; + case CMD_SYSTEM: + /* Shell command */ + system(arg1); + return 0; + case CMD_QUIT: + return 1; + default: + /* all the rest require a open database */ + if (!tdb) { + bIterate = 0; + terror("database not open"); + help(); + return 0; + } + switch (mycmd) { + case CMD_ERASE: + bIterate = 0; + tdb_traverse(tdb, do_delete_fn, NULL); + return 0; + case CMD_DUMP: + bIterate = 0; + tdb_traverse(tdb, print_rec, NULL); + return 0; + case CMD_CDUMP: + do_connections = 1; + bIterate = 0; + tdb_traverse(tdb, print_rec, NULL); + return 0; + case CMD_INSERT: + bIterate = 0; + insert_tdb(arg1, arg1len,arg2,arg2len); + return 0; + case CMD_MOVE: + bIterate = 0; + move_rec(arg1,arg1len,arg2); + return 0; + case CMD_STORE: + bIterate = 0; + store_tdb(arg1,arg1len,arg2,arg2len); + return 0; + case CMD_SHOW: + bIterate = 0; + show_tdb(arg1, arg1len); + return 0; + case CMD_KEYS: + tdb_traverse(tdb, print_key, NULL); + return 0; + case CMD_HEXKEYS: + tdb_traverse(tdb, print_hexkey, NULL); + return 0; + case CMD_DELETE: + bIterate = 0; + delete_tdb(arg1,arg1len); + return 0; + case CMD_LIST_HASH_FREE: + tdb_dump_all(tdb); + return 0; + case CMD_LIST_FREE: + tdb_printfreelist(tdb); + return 0; + case CMD_INFO: + info_tdb(); + return 0; + case CMD_FIRST: + bIterate = 1; + first_record(tdb, &iterate_kbuf); + return 0; + case CMD_NEXT: + if (bIterate) + next_record(tdb, &iterate_kbuf); + return 0; + case CMD_HELP: + help(); + return 0; + case CMD_CREATE_TDB: + case CMD_OPEN_TDB: + case CMD_SYSTEM: + case CMD_QUIT: + /* + * unhandled commands. cases included here to avoid compiler + * warnings. + */ + return 0; + } + } + + return 0; +} + +static char *convert_string(char *instring, size_t *sizep) +{ + size_t length = 0; + char *outp, *inp; + char temp[3]; + + + outp = inp = instring; + + while (*inp) { + if (*inp == '\\') { + inp++; + if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { + temp[0] = *inp++; + temp[1] = '\0'; + if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { + temp[1] = *inp++; + temp[2] = '\0'; + } + *outp++ = (char)strtol((const char *)temp,NULL,16); + } else { + *outp++ = *inp++; + } + } else { + *outp++ = *inp++; + } + length++; + } + *sizep = length; + return instring; +} + int main(int argc, char *argv[]) { - int bIterate = 0; - char *line; - char *tok; - TDB_DATA iterate_kbuf; + cmdname = ""; + arg1 = NULL; + arg1len = 0; + arg2 = NULL; + arg2len = 0; if (argv[1]) { - static char tmp[1024]; - sprintf(tmp, "open %s", argv[1]); - tok=strtok(tmp," "); - open_tdb(); + cmdname = "open"; + arg1 = argv[1]; + do_command(); + cmdname = ""; + arg1 = NULL; } - while ((line = tdb_getline("tdb> "))) { - - /* Shell command */ - - if (line[0] == '!') { - system(line + 1); - continue; - } - - if ((tok = strtok(line," "))==NULL) { - if (bIterate) - next_record(tdb, &iterate_kbuf); - continue; - } - if (strcmp(tok,"create") == 0) { - bIterate = 0; - create_tdb(); - continue; - } else if (strcmp(tok,"open") == 0) { - open_tdb(); - continue; - } else if ((strcmp(tok, "q") == 0) || - (strcmp(tok, "quit") == 0)) { - break; - } - - /* all the rest require a open database */ - if (!tdb) { - bIterate = 0; - terror("database not open"); - help(); - continue; - } - - if (strcmp(tok,"insert") == 0) { - bIterate = 0; - insert_tdb(); - } else if (strcmp(tok,"store") == 0) { - bIterate = 0; - store_tdb(); - } else if (strcmp(tok,"show") == 0) { - bIterate = 0; - show_tdb(); - } else if (strcmp(tok,"erase") == 0) { - bIterate = 0; - tdb_traverse(tdb, do_delete_fn, NULL); - } else if (strcmp(tok,"delete") == 0) { - bIterate = 0; - delete_tdb(); - } else if (strcmp(tok,"dump") == 0) { - bIterate = 0; - tdb_traverse(tdb, print_rec, NULL); - } else if (strcmp(tok,"move") == 0) { - bIterate = 0; - move_rec(); - } else if (strcmp(tok,"list") == 0) { - tdb_dump_all(tdb); - } else if (strcmp(tok, "free") == 0) { - tdb_printfreelist(tdb); - } else if (strcmp(tok,"info") == 0) { - info_tdb(); - } else if ( (strcmp(tok, "1") == 0) || - (strcmp(tok, "first") == 0)) { - bIterate = 1; - first_record(tdb, &iterate_kbuf); - } else if ((strcmp(tok, "n") == 0) || - (strcmp(tok, "next") == 0)) { - next_record(tdb, &iterate_kbuf); - } else if ((strcmp(tok, "keys") == 0)) { - bIterate = 0; - tdb_traverse(tdb, print_key, NULL); - } else { - help(); - } + switch (argc) { + case 1: + case 2: + /* Interactive mode */ + while ((cmdname = tdb_getline("tdb> "))) { + arg2 = arg1 = NULL; + if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { + arg1++; + arg2 = arg1; + while (*arg2) { + if (*arg2 == ' ') { + *arg2++ = '\0'; + break; + } + if ((*arg2++ == '\\') && (*arg2 == ' ')) { + arg2++; + } + } + } + if (arg1) arg1 = convert_string(arg1,&arg1len); + if (arg2) arg2 = convert_string(arg2,&arg2len); + if (do_command()) break; + } + break; + case 5: + arg2 = convert_string(argv[4],&arg2len); + case 4: + arg1 = convert_string(argv[3],&arg1len); + case 3: + cmdname = argv[2]; + default: + do_command(); + break; } if (tdb) tdb_close(tdb); -- cgit