2001-08-07 23:21:45 +00:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
2001-08-07 23:21:45 +00:00
Samba database functions
Copyright ( C ) Andrew Tridgell 1999 - 2000
Copyright ( C ) Paul ` Rusty ' Russell 2000
Copyright ( C ) Jeremy Allison 2000
Copyright ( C ) Andrew Esh 2001
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 19:25:36 +00:00
the Free Software Foundation ; either version 3 of the License , or
2001-08-07 23:21:45 +00:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 00:52:41 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2001-08-07 23:21:45 +00:00
*/
2007-04-03 07:00:53 +00:00
# include "replace.h"
# include "system/locale.h"
# include "system/time.h"
# include "system/filesys.h"
2007-11-06 21:47:57 -08:00
# include "system/wait.h"
1999-12-21 03:04:37 +00:00
# include "tdb.h"
2005-05-06 01:28:02 +00:00
static int do_command ( void ) ;
2007-04-02 18:42:56 +00:00
const char * cmdname ;
char * arg1 , * arg2 ;
2005-05-06 01:28:02 +00:00
size_t arg1len , arg2len ;
int bIterate = 0 ;
char * line ;
TDB_DATA iterate_kbuf ;
char cmdline [ 1024 ] ;
2007-05-29 10:15:01 +00:00
static int disable_mmap ;
2005-05-06 01:28:02 +00:00
enum commands {
CMD_CREATE_TDB ,
CMD_OPEN_TDB ,
2009-09-20 23:58:27 +02:00
CMD_TRANSACTION_START ,
CMD_TRANSACTION_COMMIT ,
CMD_TRANSACTION_CANCEL ,
2005-05-06 01:28:02 +00:00
CMD_ERASE ,
CMD_DUMP ,
CMD_INSERT ,
CMD_MOVE ,
CMD_STORE ,
CMD_SHOW ,
CMD_KEYS ,
CMD_HEXKEYS ,
CMD_DELETE ,
CMD_LIST_HASH_FREE ,
CMD_LIST_FREE ,
CMD_INFO ,
2007-05-29 10:15:01 +00:00
CMD_MMAP ,
CMD_SPEED ,
2005-05-06 01:28:02 +00:00
CMD_FIRST ,
CMD_NEXT ,
CMD_SYSTEM ,
2008-11-02 00:12:32 +01:00
CMD_CHECK ,
2005-05-06 01:28:02 +00:00
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 } ,
2009-09-20 23:58:27 +02:00
{ " transaction_start " , CMD_TRANSACTION_START } ,
{ " transaction_commit " , CMD_TRANSACTION_COMMIT } ,
{ " transaction_cancel " , CMD_TRANSACTION_CANCEL } ,
2005-05-06 01:28:02 +00:00
{ " erase " , CMD_ERASE } ,
{ " dump " , CMD_DUMP } ,
{ " 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 } ,
2007-05-29 10:15:01 +00:00
{ " speed " , CMD_SPEED } ,
{ " mmap " , CMD_MMAP } ,
2005-05-06 01:28:02 +00:00
{ " first " , CMD_FIRST } ,
{ " 1 " , CMD_FIRST } ,
{ " next " , CMD_NEXT } ,
{ " n " , CMD_NEXT } ,
2008-11-02 00:12:32 +01:00
{ " check " , CMD_CHECK } ,
2005-05-06 01:28:02 +00:00
{ " quit " , CMD_QUIT } ,
{ " q " , CMD_QUIT } ,
{ " ! " , CMD_SYSTEM } ,
{ NULL , CMD_HELP }
} ;
1999-12-21 03:04:37 +00:00
2007-05-29 10:15:01 +00:00
struct timeval tp1 , tp2 ;
static void _start_timer ( void )
{
gettimeofday ( & tp1 , NULL ) ;
}
static double _end_timer ( void )
{
gettimeofday ( & tp2 , NULL ) ;
return ( ( tp2 . tv_sec - tp1 . tv_sec ) +
( tp2 . tv_usec - tp1 . tv_usec ) * 1.0e-6 ) ;
}
2009-10-22 00:11:34 +10:30
# ifdef PRINTF_ATTRIBUTE
static void tdb_log ( struct tdb_context * tdb , enum tdb_debug_level level , const char * format , . . . ) PRINTF_ATTRIBUTE ( 3 , 4 ) ;
# endif
static void tdb_log ( struct tdb_context * tdb , enum tdb_debug_level level , const char * format , . . . )
{
va_list ap ;
va_start ( ap , format ) ;
vfprintf ( stderr , format , ap ) ;
va_end ( ap ) ;
}
1999-12-21 03:04:37 +00:00
/* a tdb tool for manipulating a tdb database */
static TDB_CONTEXT * tdb ;
2001-12-11 08:24:36 +00:00
static int print_rec ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf , void * state ) ;
2005-05-06 01:28:02 +00:00
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 ) ;
2000-04-24 14:36:44 +00:00
2005-10-18 03:24:00 +00:00
static void print_asc ( const char * buf , int len )
2000-04-24 14:36:44 +00:00
{
int i ;
2001-12-03 00:23:14 +00:00
/* We're probably printing ASCII strings so don't try to display
the trailing NULL character . */
if ( buf [ len - 1 ] = = 0 )
len - - ;
2000-04-24 14:36:44 +00:00
for ( i = 0 ; i < len ; i + + )
printf ( " %c " , isprint ( buf [ i ] ) ? buf [ i ] : ' . ' ) ;
}
2005-10-18 03:24:00 +00:00
static void print_data ( const char * buf , int len )
2000-04-24 14:36:44 +00:00
{
int i = 0 ;
if ( len < = 0 ) return ;
printf ( " [%03X] " , i ) ;
for ( i = 0 ; i < len ; ) {
2007-12-20 14:57:29 -08:00
printf ( " %02X " , ( int ) ( ( unsigned char ) buf [ i ] ) ) ;
2000-04-24 14:36:44 +00:00
i + + ;
if ( i % 8 = = 0 ) printf ( " " ) ;
if ( i % 16 = = 0 ) {
print_asc ( & buf [ i - 16 ] , 8 ) ; printf ( " " ) ;
print_asc ( & buf [ i - 8 ] , 8 ) ; printf ( " \n " ) ;
if ( i < len ) printf ( " [%03X] " , i ) ;
}
}
if ( i % 16 ) {
int n ;
n = 16 - ( i % 16 ) ;
printf ( " " ) ;
if ( n > 8 ) printf ( " " ) ;
while ( n - - ) printf ( " " ) ;
n = i % 16 ;
if ( n > 8 ) n = 8 ;
print_asc ( & buf [ i - ( i % 16 ) ] , n ) ; printf ( " " ) ;
n = ( i % 16 ) - n ;
if ( n > 0 ) print_asc ( & buf [ i - n ] , n ) ;
printf ( " \n " ) ;
}
}
1999-12-21 03:04:37 +00:00
static void help ( void )
{
2003-04-14 01:47:16 +00:00
printf ( " \n "
" tdbtool: \n "
" create dbname : create a database \n "
" open dbname : open an existing database \n "
2009-09-20 23:58:27 +02:00
" transaction_start : start a transaction \n "
" transaction_commit : commit a transaction \n "
" transaction_cancel : cancel a transaction \n "
2003-04-14 01:47:16 +00:00
" erase : erase the database \n "
" dump : dump the database as strings \n "
2005-05-06 01:28:02 +00:00
" 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 "
2003-04-14 01:47:16 +00:00
" insert key data : insert a record \n "
2003-07-16 16:51:51 +00:00
" move key file : move a record to a destination tdb \n "
2003-04-14 01:47:16 +00:00
" store key data : store a record (replace) \n "
" show key : show a record by key \n "
" delete key : delete a record by key \n "
" list : print the database hash table and freelist \n "
" free : print the database freelist \n "
2008-11-02 00:12:32 +01:00
" check : check the integrity of an opened database \n "
2009-09-20 23:58:05 +02:00
" speed : perform speed tests on the database \n "
2008-11-02 00:12:32 +01:00
" ! command : execute system command \n "
2003-04-14 01:47:16 +00:00
" 1 | first : print the first record \n "
" n | next : print the next record \n "
" q | quit : terminate \n "
" \\ n : repeat 'next' command \n "
" \n " ) ;
1999-12-21 03:04:37 +00:00
}
2005-03-17 18:25:15 +00:00
static void terror ( const char * why )
1999-12-21 03:04:37 +00:00
{
printf ( " %s \n " , why ) ;
}
2007-04-02 18:42:56 +00:00
static void create_tdb ( const char * tdbname )
2001-08-07 23:21:45 +00:00
{
2009-10-22 00:11:34 +10:30
struct tdb_logging_context log_ctx ;
log_ctx . log_fn = tdb_log ;
1999-12-21 03:04:37 +00:00
if ( tdb ) tdb_close ( tdb ) ;
2009-10-22 00:11:34 +10:30
tdb = tdb_open_ex ( tdbname , 0 , TDB_CLEAR_IF_FIRST | ( disable_mmap ? TDB_NOMMAP : 0 ) ,
O_RDWR | O_CREAT | O_TRUNC , 0600 , & log_ctx , NULL ) ;
2001-08-04 18:17:30 +00:00
if ( ! tdb ) {
2005-05-06 01:28:02 +00:00
printf ( " Could not create %s: %s \n " , tdbname , strerror ( errno ) ) ;
2001-08-04 18:17:30 +00:00
}
1999-12-21 03:04:37 +00:00
}
2007-04-02 18:42:56 +00:00
static void open_tdb ( const char * tdbname )
1999-12-21 03:04:37 +00:00
{
2009-10-22 00:11:34 +10:30
struct tdb_logging_context log_ctx ;
log_ctx . log_fn = tdb_log ;
1999-12-21 03:04:37 +00:00
if ( tdb ) tdb_close ( tdb ) ;
2009-10-22 00:11:34 +10:30
tdb = tdb_open_ex ( tdbname , 0 , disable_mmap ? TDB_NOMMAP : 0 , O_RDWR , 0600 ,
& log_ctx , NULL ) ;
2001-08-04 18:17:30 +00:00
if ( ! tdb ) {
2005-05-06 01:28:02 +00:00
printf ( " Could not open %s: %s \n " , tdbname , strerror ( errno ) ) ;
2001-08-04 18:17:30 +00:00
}
1999-12-21 03:04:37 +00:00
}
2005-05-06 01:28:02 +00:00
static void insert_tdb ( char * keyname , size_t keylen , char * data , size_t datalen )
1999-12-21 03:04:37 +00:00
{
TDB_DATA key , dbuf ;
2006-01-07 22:11:30 +00:00
if ( ( keyname = = NULL ) | | ( keylen = = 0 ) ) {
terror ( " need key " ) ;
return ;
}
2007-03-29 09:35:51 +00:00
key . dptr = ( unsigned char * ) keyname ;
2005-05-06 01:28:02 +00:00
key . dsize = keylen ;
2007-03-29 09:35:51 +00:00
dbuf . dptr = ( unsigned char * ) data ;
2005-05-06 01:28:02 +00:00
dbuf . dsize = datalen ;
1999-12-21 03:04:37 +00:00
if ( tdb_store ( tdb , key , dbuf , TDB_INSERT ) = = - 1 ) {
terror ( " insert failed " ) ;
}
}
2005-05-06 01:28:02 +00:00
static void store_tdb ( char * keyname , size_t keylen , char * data , size_t datalen )
1999-12-21 03:04:37 +00:00
{
TDB_DATA key , dbuf ;
2006-01-07 22:11:30 +00:00
if ( ( keyname = = NULL ) | | ( keylen = = 0 ) ) {
terror ( " need key " ) ;
return ;
}
if ( ( data = = NULL ) | | ( datalen = = 0 ) ) {
terror ( " need data " ) ;
return ;
}
2007-03-29 09:35:51 +00:00
key . dptr = ( unsigned char * ) keyname ;
2005-05-06 01:28:02 +00:00
key . dsize = keylen ;
2007-03-29 09:35:51 +00:00
dbuf . dptr = ( unsigned char * ) data ;
2005-05-06 01:28:02 +00:00
dbuf . dsize = datalen ;
2001-08-07 23:21:45 +00:00
printf ( " Storing key: \n " ) ;
print_rec ( tdb , key , dbuf , NULL ) ;
1999-12-21 03:04:37 +00:00
if ( tdb_store ( tdb , key , dbuf , TDB_REPLACE ) = = - 1 ) {
terror ( " store failed " ) ;
}
}
2005-05-06 01:28:02 +00:00
static void show_tdb ( char * keyname , size_t keylen )
1999-12-21 03:04:37 +00:00
{
TDB_DATA key , dbuf ;
2006-01-07 22:11:30 +00:00
if ( ( keyname = = NULL ) | | ( keylen = = 0 ) ) {
terror ( " need key " ) ;
return ;
}
2007-03-29 09:35:51 +00:00
key . dptr = ( unsigned char * ) keyname ;
2005-05-06 01:28:02 +00:00
key . dsize = keylen ;
1999-12-21 03:04:37 +00:00
dbuf = tdb_fetch ( tdb , key ) ;
2001-12-03 04:15:26 +00:00
if ( ! dbuf . dptr ) {
2005-05-06 01:28:02 +00:00
terror ( " fetch failed " ) ;
return ;
2001-12-03 04:15:26 +00:00
}
2003-07-16 16:26:40 +00:00
2000-10-05 22:19:34 +00:00
print_rec ( tdb , key , dbuf , NULL ) ;
2003-07-16 16:26:40 +00:00
free ( dbuf . dptr ) ;
return ;
1999-12-21 03:04:37 +00:00
}
2005-05-06 01:28:02 +00:00
static void delete_tdb ( char * keyname , size_t keylen )
1999-12-21 03:04:37 +00:00
{
TDB_DATA key ;
2006-01-07 22:11:30 +00:00
if ( ( keyname = = NULL ) | | ( keylen = = 0 ) ) {
terror ( " need key " ) ;
return ;
}
2007-03-29 09:35:51 +00:00
key . dptr = ( unsigned char * ) keyname ;
2005-05-06 01:28:02 +00:00
key . dsize = keylen ;
1999-12-21 03:04:37 +00:00
if ( tdb_delete ( tdb , key ) ! = 0 ) {
terror ( " delete failed " ) ;
}
}
2005-05-06 01:28:02 +00:00
static void move_rec ( char * keyname , size_t keylen , char * tdbname )
2003-07-16 16:51:51 +00:00
{
TDB_DATA key , dbuf ;
TDB_CONTEXT * dst_tdb ;
2006-01-07 22:11:30 +00:00
if ( ( keyname = = NULL ) | | ( keylen = = 0 ) ) {
terror ( " need key " ) ;
return ;
}
2005-05-06 01:28:02 +00:00
if ( ! tdbname ) {
2003-07-16 16:51:51 +00:00
terror ( " need destination tdb name " ) ;
return ;
}
2007-03-29 09:35:51 +00:00
key . dptr = ( unsigned char * ) keyname ;
2005-05-06 01:28:02 +00:00
key . dsize = keylen ;
2003-07-16 16:51:51 +00:00
dbuf = tdb_fetch ( tdb , key ) ;
if ( ! dbuf . dptr ) {
2005-05-06 01:28:02 +00:00
terror ( " fetch failed " ) ;
return ;
2003-07-16 16:51:51 +00:00
}
print_rec ( tdb , key , dbuf , NULL ) ;
2005-05-06 01:28:02 +00:00
dst_tdb = tdb_open ( tdbname , 0 , 0 , O_RDWR , 0600 ) ;
2003-07-16 16:51:51 +00:00
if ( ! dst_tdb ) {
terror ( " unable to open destination tdb " ) ;
return ;
}
if ( tdb_store ( dst_tdb , key , dbuf , TDB_REPLACE ) = = - 1 ) {
terror ( " failed to move record " ) ;
}
else
printf ( " record moved \n " ) ;
tdb_close ( dst_tdb ) ;
return ;
}
2001-12-11 08:24:36 +00:00
static int print_rec ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf , void * state )
2005-05-06 01:28:02 +00:00
{
2005-09-30 17:13:37 +00:00
printf ( " \n key %d bytes \n " , ( int ) key . dsize ) ;
2007-03-29 09:35:51 +00:00
print_asc ( ( const char * ) key . dptr , key . dsize ) ;
2005-09-30 17:13:37 +00:00
printf ( " \n data %d bytes \n " , ( int ) dbuf . dsize ) ;
2007-03-29 09:35:51 +00:00
print_data ( ( const char * ) dbuf . dptr , dbuf . dsize ) ;
1999-12-21 03:04:37 +00:00
return 0 ;
}
2001-12-11 08:24:36 +00:00
static int print_key ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf , void * state )
2001-11-28 03:58:33 +00:00
{
2005-09-30 17:13:37 +00:00
printf ( " key %d bytes: " , ( int ) key . dsize ) ;
2007-03-29 09:35:51 +00:00
print_asc ( ( const char * ) key . dptr , key . dsize ) ;
2001-12-03 00:23:14 +00:00
printf ( " \n " ) ;
2001-11-28 03:58:33 +00:00
return 0 ;
}
2005-05-06 01:28:02 +00:00
static int print_hexkey ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf , void * state )
{
2005-09-30 17:13:37 +00:00
printf ( " key %d bytes \n " , ( int ) key . dsize ) ;
2007-03-29 09:35:51 +00:00
print_data ( ( const char * ) key . dptr , key . dsize ) ;
2005-05-06 01:28:02 +00:00
printf ( " \n " ) ;
return 0 ;
}
1999-12-21 03:04:37 +00:00
static int total_bytes ;
2001-12-11 08:24:36 +00:00
static int traverse_fn ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf , void * state )
1999-12-21 03:04:37 +00:00
{
total_bytes + = dbuf . dsize ;
return 0 ;
}
static void info_tdb ( void )
{
int count ;
total_bytes = 0 ;
2005-05-06 01:28:02 +00:00
if ( ( count = tdb_traverse ( tdb , traverse_fn , NULL ) ) = = - 1 )
2001-02-13 16:28:48 +00:00
printf ( " Error = %s \n " , tdb_errorstr ( tdb ) ) ;
else
printf ( " %d records totalling %d bytes \n " , count , total_bytes ) ;
1999-12-21 03:04:37 +00:00
}
2007-05-29 10:15:01 +00:00
static void speed_tdb ( const char * tlimit )
{
2009-10-16 19:02:02 +02:00
const char * str = " store test " , * str2 = " transaction test " ;
2007-05-29 10:15:01 +00:00
unsigned timelimit = tlimit ? atoi ( tlimit ) : 0 ;
double t ;
2009-05-26 09:24:37 +10:00
int ops ;
if ( timelimit = = 0 ) timelimit = 5 ;
ops = 0 ;
printf ( " Testing store speed for %u seconds \n " , timelimit ) ;
_start_timer ( ) ;
do {
long int r = random ( ) ;
TDB_DATA key , dbuf ;
2009-10-16 19:02:02 +02:00
key . dptr = discard_const_p ( uint8_t , str ) ;
2009-05-27 12:52:37 -07:00
key . dsize = strlen ( ( char * ) key . dptr ) ;
2009-10-16 19:02:02 +02:00
dbuf . dptr = ( uint8_t * ) & r ;
2009-05-26 09:24:37 +10:00
dbuf . dsize = sizeof ( r ) ;
tdb_store ( tdb , key , dbuf , TDB_REPLACE ) ;
t = _end_timer ( ) ;
ops + + ;
} while ( t < timelimit ) ;
printf ( " %10.3f ops/sec \n " , ops / t ) ;
ops = 0 ;
printf ( " Testing fetch speed for %u seconds \n " , timelimit ) ;
_start_timer ( ) ;
do {
long int r = random ( ) ;
TDB_DATA key , dbuf ;
2009-10-16 19:02:02 +02:00
key . dptr = discard_const_p ( uint8_t , str ) ;
2009-05-27 12:52:37 -07:00
key . dsize = strlen ( ( char * ) key . dptr ) ;
2009-10-16 19:02:02 +02:00
dbuf . dptr = ( uint8_t * ) & r ;
2009-05-26 09:24:37 +10:00
dbuf . dsize = sizeof ( r ) ;
tdb_fetch ( tdb , key ) ;
t = _end_timer ( ) ;
ops + + ;
} while ( t < timelimit ) ;
printf ( " %10.3f ops/sec \n " , ops / t ) ;
ops = 0 ;
printf ( " Testing transaction speed for %u seconds \n " , timelimit ) ;
_start_timer ( ) ;
do {
long int r = random ( ) ;
TDB_DATA key , dbuf ;
2009-10-16 19:02:02 +02:00
key . dptr = discard_const_p ( uint8_t , str2 ) ;
2009-05-27 12:52:37 -07:00
key . dsize = strlen ( ( char * ) key . dptr ) ;
2009-10-16 19:02:02 +02:00
dbuf . dptr = ( uint8_t * ) & r ;
2009-05-26 09:24:37 +10:00
dbuf . dsize = sizeof ( r ) ;
tdb_transaction_start ( tdb ) ;
tdb_store ( tdb , key , dbuf , TDB_REPLACE ) ;
tdb_transaction_commit ( tdb ) ;
t = _end_timer ( ) ;
ops + + ;
} while ( t < timelimit ) ;
printf ( " %10.3f ops/sec \n " , ops / t ) ;
ops = 0 ;
2007-05-29 10:15:01 +00:00
printf ( " Testing traverse speed for %u seconds \n " , timelimit ) ;
_start_timer ( ) ;
2009-05-26 09:24:37 +10:00
do {
2007-05-29 10:15:01 +00:00
tdb_traverse ( tdb , traverse_fn , NULL ) ;
2009-05-26 09:24:37 +10:00
t = _end_timer ( ) ;
ops + + ;
} while ( t < timelimit ) ;
printf ( " %10.3f ops/sec \n " , ops / t ) ;
2007-05-29 10:15:01 +00:00
}
static void toggle_mmap ( void )
{
disable_mmap = ! disable_mmap ;
if ( disable_mmap ) {
printf ( " mmap is disabled \n " ) ;
} else {
printf ( " mmap is enabled \n " ) ;
}
}
2005-03-17 18:25:15 +00:00
static char * tdb_getline ( const char * prompt )
2000-01-07 03:02:13 +00:00
{
2005-05-27 14:38:00 +00:00
static char thisline [ 1024 ] ;
2000-01-07 03:02:13 +00:00
char * p ;
fputs ( prompt , stdout ) ;
2005-05-27 14:38:00 +00:00
thisline [ 0 ] = 0 ;
p = fgets ( thisline , sizeof ( thisline ) - 1 , stdin ) ;
2000-01-07 03:02:13 +00:00
if ( p ) p = strchr ( p , ' \n ' ) ;
if ( p ) * p = 0 ;
2005-05-27 14:38:00 +00:00
return p ? thisline : NULL ;
2000-01-07 03:02:13 +00:00
}
2001-12-11 08:24:36 +00:00
static int do_delete_fn ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf ,
2000-02-28 00:37:13 +00:00
void * state )
{
2001-12-11 08:24:36 +00:00
return tdb_delete ( the_tdb , key ) ;
2000-02-28 00:37:13 +00:00
}
2001-12-11 08:24:36 +00:00
static void first_record ( TDB_CONTEXT * the_tdb , TDB_DATA * pkey )
2000-12-07 17:46:11 +00:00
{
TDB_DATA dbuf ;
2001-12-11 08:24:36 +00:00
* pkey = tdb_firstkey ( the_tdb ) ;
2000-12-07 17:46:11 +00:00
2001-12-11 08:24:36 +00:00
dbuf = tdb_fetch ( the_tdb , * pkey ) ;
2000-12-07 17:46:11 +00:00
if ( ! dbuf . dptr ) terror ( " fetch failed " ) ;
2002-07-15 10:35:28 +00:00
else {
print_rec ( the_tdb , * pkey , dbuf , NULL ) ;
}
2000-12-07 17:46:11 +00:00
}
2001-12-11 08:24:36 +00:00
static void next_record ( TDB_CONTEXT * the_tdb , TDB_DATA * pkey )
2000-12-07 17:46:11 +00:00
{
TDB_DATA dbuf ;
2001-12-11 08:24:36 +00:00
* pkey = tdb_nextkey ( the_tdb , * pkey ) ;
2000-12-07 17:46:11 +00:00
2001-12-11 08:24:36 +00:00
dbuf = tdb_fetch ( the_tdb , * pkey ) ;
2001-01-29 21:34:08 +00:00
if ( ! dbuf . dptr )
terror ( " fetch failed " ) ;
else
2001-12-11 08:24:36 +00:00
print_rec ( the_tdb , * pkey , dbuf , NULL ) ;
2000-12-07 17:46:11 +00:00
}
2009-12-17 00:13:23 +01:00
static int count ( TDB_DATA key , TDB_DATA data , void * private_data )
2008-11-02 00:12:32 +01:00
{
2009-12-17 00:13:23 +01:00
( * ( unsigned int * ) private_data ) + + ;
2008-11-02 00:12:32 +01:00
return 0 ;
}
static void check_db ( TDB_CONTEXT * the_tdb )
{
2009-10-22 00:11:34 +10:30
int tdbcount = 0 ;
if ( ! the_tdb )
2008-11-02 00:12:32 +01:00
printf ( " Error: No database opened! \n " ) ;
2009-10-22 00:11:34 +10:30
else if ( tdb_check ( the_tdb , count , & tdbcount ) = = - 1 )
2008-11-02 00:12:32 +01:00
printf ( " Integrity check for the opened database failed. \n " ) ;
2009-10-22 00:11:34 +10:30
else
printf ( " Database integrity is OK and has %d records. \n " ,
tdbcount ) ;
2008-11-02 00:12:32 +01:00
}
2005-05-06 01:28:02 +00:00
static int do_command ( void )
{
COMMAND_TABLE * ctp = cmd_table ;
enum commands mycmd = CMD_HELP ;
int cmd_len ;
if ( cmdname & & strlen ( cmdname ) = = 0 ) {
2009-09-21 00:08:34 +02:00
mycmd = CMD_NEXT ;
2005-05-06 01:28:02 +00:00
} else {
2009-09-21 00:08:34 +02:00
while ( ctp - > name ) {
cmd_len = strlen ( ctp - > name ) ;
if ( strncmp ( ctp - > name , cmdname , cmd_len ) = = 0 ) {
mycmd = ctp - > cmd ;
break ;
}
ctp + + ;
2005-05-06 01:28:02 +00:00
}
}
switch ( mycmd ) {
case CMD_CREATE_TDB :
bIterate = 0 ;
2009-09-21 00:08:34 +02:00
create_tdb ( arg1 ) ;
2005-05-06 01:28:02 +00:00
return 0 ;
2009-09-21 00:08:34 +02:00
case CMD_OPEN_TDB :
2005-05-06 01:28:02 +00:00
bIterate = 0 ;
2009-09-21 00:08:34 +02:00
open_tdb ( arg1 ) ;
2005-05-06 01:28:02 +00:00
return 0 ;
2009-09-21 00:08:34 +02:00
case CMD_SYSTEM :
/* Shell command */
if ( system ( arg1 ) = = - 1 ) {
terror ( " system() call failed \n " ) ;
}
2005-05-06 01:28:02 +00:00
return 0 ;
2009-09-21 00:08:34 +02:00
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_TRANSACTION_START :
bIterate = 0 ;
tdb_transaction_start ( tdb ) ;
return 0 ;
case CMD_TRANSACTION_COMMIT :
bIterate = 0 ;
tdb_transaction_commit ( tdb ) ;
return 0 ;
case CMD_TRANSACTION_CANCEL :
bIterate = 0 ;
tdb_transaction_cancel ( tdb ) ;
return 0 ;
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_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_SPEED :
speed_tdb ( arg1 ) ;
return 0 ;
case CMD_MMAP :
toggle_mmap ( ) ;
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_CHECK :
check_db ( tdb ) ;
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 ;
}
2005-05-06 01:28:02 +00:00
}
return 0 ;
}
static char * convert_string ( char * instring , size_t * sizep )
{
2009-09-21 00:08:34 +02:00
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 + + ;
2005-05-06 01:28:02 +00:00
}
2009-09-21 00:08:34 +02:00
length + + ;
2005-05-06 01:28:02 +00:00
}
2009-09-21 00:08:34 +02:00
* sizep = length ;
return instring ;
2005-05-06 01:28:02 +00:00
}
1999-12-21 03:04:37 +00:00
int main ( int argc , char * argv [ ] )
{
2009-09-21 00:08:34 +02:00
cmdname = " " ;
2005-05-06 01:28:02 +00:00
arg1 = NULL ;
2009-09-21 00:08:34 +02:00
arg1len = 0 ;
arg2 = NULL ;
arg2len = 0 ;
if ( argv [ 1 ] ) {
cmdname = " open " ;
arg1 = argv [ 1 ] ;
do_command ( ) ;
cmdname = " " ;
arg1 = NULL ;
}
2000-10-05 22:19:34 +00:00
2009-09-21 00:08:34 +02:00
switch ( argc ) {
2005-05-06 01:28:02 +00:00
case 1 :
case 2 :
2009-09-21 00:08:34 +02:00
/* 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 + + ;
}
}
2005-05-06 01:28:02 +00:00
}
2009-09-21 00:08:34 +02:00
if ( arg1 ) arg1 = convert_string ( arg1 , & arg1len ) ;
if ( arg2 ) arg2 = convert_string ( arg2 , & arg2len ) ;
if ( do_command ( ) ) break ;
2005-05-06 01:28:02 +00:00
}
2009-09-21 00:08:34 +02:00
break ;
2005-05-06 01:28:02 +00:00
case 5 :
2009-09-21 00:08:34 +02:00
arg2 = convert_string ( argv [ 4 ] , & arg2len ) ;
2005-05-06 01:28:02 +00:00
case 4 :
2009-09-21 00:08:34 +02:00
arg1 = convert_string ( argv [ 3 ] , & arg1len ) ;
2005-05-06 01:28:02 +00:00
case 3 :
2009-09-21 00:08:34 +02:00
cmdname = argv [ 2 ] ;
2005-05-06 01:28:02 +00:00
default :
2009-09-21 00:08:34 +02:00
do_command ( ) ;
break ;
}
2000-03-13 01:35:09 +00:00
2009-09-21 00:08:34 +02:00
if ( tdb ) tdb_close ( tdb ) ;
2000-03-13 01:35:09 +00:00
2009-09-21 00:08:34 +02:00
return 0 ;
1999-12-21 03:04:37 +00:00
}