From 61ffe158f2d3f149b230cc31c4b58d7d025ab28d Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 6 May 2005 01:28:02 +0000 Subject: [PATCH] r6623: This change fixes a few broken commands plus adds some new commands. It also restructures it so you can execute a single command from the command line. Input strings are parsed to allow input of arbitrary characters using the \xx syntax for hex values. (This used to be commit 94e53472666edfb390605b8a7e9f9dffc3c845f5) --- source3/tdb/tdb.c | 3 +- source3/tdb/tdbdump.c | 4 +- source3/tdb/tdbtool.c | 532 +++++++++++++++++++++++++----------------- 3 files changed, 324 insertions(+), 215 deletions(-) diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index 7159550c0c2..e03e571ca15 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -585,8 +585,7 @@ void tdb_dump_all(TDB_CONTEXT *tdb) for (i=0;iheader.hash_size;i++) { tdb_dump_chain(tdb, i); } - printf("freelist:\n"); - tdb_dump_chain(tdb, -1); + tdb_printfreelist(tdb); } int tdb_printfreelist(TDB_CONTEXT *tdb) diff --git a/source3/tdb/tdbdump.c b/source3/tdb/tdbdump.c index d2530f9f54c..17ae536bc4a 100644 --- a/source3/tdb/tdbdump.c +++ b/source3/tdb/tdbdump.c @@ -49,10 +49,10 @@ static void print_data(TDB_DATA d) static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { printf("{\n"); - printf("key = \""); + printf("key(%d) = \"",key.dsize); print_data(key); printf("\"\n"); - printf("data = \""); + printf("data(%d) = \"",dbuf.dsize); print_data(dbuf); printf("\"\n"); printf("}\n"); diff --git a/source3/tdb/tdbtool.c b/source3/tdb/tdbtool.c index 2de3df961cf..70400e1f377 100644 --- a/source3/tdb/tdbtool.c +++ b/source3/tdb/tdbtool.c @@ -35,11 +35,74 @@ #include #include #include "tdb.h" +#include "pstring.h" + +static int do_command(void); +char *cmdname, *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; @@ -55,13 +118,18 @@ 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 TDB_CONTEXT *tdb; +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) { @@ -117,6 +185,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" @@ -124,6 +196,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" @@ -136,102 +209,47 @@ static void terror(const char *why) printf("%s\n", why); } -static char *get_token(int startover) +static void create_tdb(char * tdbname) { - 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) -{ - char *tok = get_token(1); - if (!tok) { - help(); - return; - } if (tdb) tdb_close(tdb); - tdb = tdb_open(tok, 0, TDB_CLEAR_IF_FIRST, + 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(char *tdbname) { - char *tok = get_token(1); - if (!tok) { - help(); - return; - } if (tdb) tdb_close(tdb); - tdb = tdb_open(tok, 0, 0, O_RDWR, 0600); + 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(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - dbuf.dptr = d; - dbuf.dsize = strlen(d)+1; + key.dptr = keyname; + key.dsize = keylen; + dbuf.dptr = 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(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - dbuf.dptr = d; - dbuf.dsize = strlen(d)+1; + key.dptr = keyname; + key.dsize = keylen; + dbuf.dptr = data; + dbuf.dsize = datalen; printf("Storing key:\n"); print_rec(tdb, key, dbuf, NULL); @@ -241,32 +259,19 @@ 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(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; + key.dptr = 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 ); @@ -274,59 +279,40 @@ 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(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; + key.dptr = 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; TDB_CONTEXT *dst_tdb; - if (!k) { - help(); - return; - } - - if ( !file ) { + if ( !tdbname ) { terror("need destination tdb name"); return; } - key.dptr = k; - key.dsize = strlen(k)+1; + key.dptr = 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(file, 0, 0, O_RDWR, 0600); + dst_tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600); if ( !dst_tdb ) { terror("unable to open destination tdb"); return; @@ -343,9 +329,9 @@ static void move_rec(void) return; } -#if 0 static int print_conn_key(TDB_DATA key) { + printf( "\nkey %d bytes\n", 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); @@ -354,6 +340,7 @@ static int print_conn_key(TDB_DATA key) static int print_conn_data(TDB_DATA dbuf) { + printf( "\ndata %d bytes\n", 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); @@ -363,32 +350,52 @@ static int print_conn_data(TDB_DATA dbuf) 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; } -#endif static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { -#if 0 + 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; -#else +} + +static int print_arec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ 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); return 0; -#endif } static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { + printf("key %d bytes: ", key.dsize); print_asc(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", key.dsize); + print_data(key.dptr, key.dsize); + printf("\n"); + return 0; +} + static int total_bytes; static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) @@ -401,7 +408,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); @@ -433,7 +440,6 @@ static void first_record(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); } } @@ -447,98 +453,202 @@ static void next_record(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; + } + } + + 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; + int i; + + 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,' ')) { + 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); -- 2.34.1