2001-08-08 03:21:45 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-08-08 03:21:45 +04: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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2001-08-04 22:17:30 +04:00
# include <errno.h>
1999-12-21 06:04:37 +03:00
# include <stdlib.h>
# include <stdio.h>
# include <fcntl.h>
# include <unistd.h>
# include <string.h>
# include <fcntl.h>
2001-12-04 15:44:10 +03:00
# include <time.h>
1999-12-21 06:04:37 +03:00
# include <sys/mman.h>
# include <sys/stat.h>
# include <sys/time.h>
2000-04-24 18:36:44 +04:00
# include <ctype.h>
1999-12-21 06:04:37 +03:00
# include "tdb.h"
/* a tdb tool for manipulating a tdb database */
2001-12-03 03:23:14 +03:00
# define FSTRING_LEN 256
2001-01-30 00:34:08 +03:00
typedef char fstring [ FSTRING_LEN ] ;
typedef struct connections_key {
pid_t pid ;
int cnum ;
fstring name ;
} connections_key ;
typedef struct connections_data {
int magic ;
pid_t pid ;
int cnum ;
uid_t uid ;
gid_t gid ;
char name [ 24 ] ;
char addr [ 24 ] ;
char machine [ 128 ] ;
time_t start ;
} connections_data ;
1999-12-21 06:04:37 +03:00
static TDB_CONTEXT * tdb ;
2001-12-11 11:24:36 +03:00
static int print_rec ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf , void * state ) ;
2000-04-24 18:36:44 +04:00
static void print_asc ( unsigned char * buf , int len )
{
int i ;
2001-12-03 03:23:14 +03: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 18:36:44 +04:00
for ( i = 0 ; i < len ; i + + )
printf ( " %c " , isprint ( buf [ i ] ) ? buf [ i ] : ' . ' ) ;
}
static void print_data ( unsigned char * buf , int len )
{
int i = 0 ;
if ( len < = 0 ) return ;
printf ( " [%03X] " , i ) ;
for ( i = 0 ; i < len ; ) {
printf ( " %02X " , ( int ) buf [ i ] ) ;
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 06:04:37 +03:00
static void help ( void )
{
printf ( "
tdbtool :
create dbname : create a database
open dbname : open an existing database
erase : erase the database
dump : dump the database as strings
insert key data : insert a record
store key data : store a record ( replace )
show key : show a record by key
delete key : delete a record by key
2001-11-09 04:26:13 +03:00
list : print the database hash table and freelist
2000-12-02 04:04:11 +03:00
free : print the database freelist
2001-11-09 04:26:13 +03:00
1 | first : print the first record
2001-02-13 19:28:48 +03:00
n | next : print the next record
q | quit : terminate
\ \ n : repeat ' next ' command
1999-12-21 06:04:37 +03:00
" );
}
static void terror ( char * why )
{
printf ( " %s \n " , why ) ;
}
2001-08-08 03:21:45 +04:00
static char * get_token ( int startover )
{
2001-12-11 11:24:36 +03:00
static char tmp [ 1024 ] ;
2001-08-08 03:21:45 +04:00
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 ;
}
1999-12-21 06:04:37 +03:00
static void create_tdb ( void )
{
2001-08-08 03:21:45 +04:00
char * tok = get_token ( 1 ) ;
1999-12-21 06:04:37 +03:00
if ( ! tok ) {
help ( ) ;
return ;
}
if ( tdb ) tdb_close ( tdb ) ;
2001-12-04 14:41:12 +03:00
tdb = tdb_open ( tok , 0 , TDB_CLEAR_IF_FIRST ,
O_RDWR | O_CREAT | O_TRUNC , 0600 ) ;
2001-08-04 22:17:30 +04:00
if ( ! tdb ) {
printf ( " Could not create %s: %s \n " , tok , strerror ( errno ) ) ;
}
1999-12-21 06:04:37 +03:00
}
static void open_tdb ( void )
{
2001-08-08 03:21:45 +04:00
char * tok = get_token ( 1 ) ;
1999-12-21 06:04:37 +03:00
if ( ! tok ) {
help ( ) ;
return ;
}
if ( tdb ) tdb_close ( tdb ) ;
2001-12-04 14:41:12 +03:00
tdb = tdb_open ( tok , 0 , 0 , O_RDWR , 0600 ) ;
2001-08-04 22:17:30 +04:00
if ( ! tdb ) {
printf ( " Could not open %s: %s \n " , tok , strerror ( errno ) ) ;
}
1999-12-21 06:04:37 +03:00
}
static void insert_tdb ( void )
{
2001-08-08 03:21:45 +04:00
char * k = get_token ( 1 ) ;
char * d = get_token ( 0 ) ;
1999-12-21 06:04:37 +03:00
TDB_DATA key , dbuf ;
if ( ! k | | ! d ) {
help ( ) ;
return ;
}
key . dptr = k ;
2001-08-08 03:21:45 +04:00
key . dsize = strlen ( k ) + 1 ;
1999-12-21 06:04:37 +03:00
dbuf . dptr = d ;
2001-08-08 03:21:45 +04:00
dbuf . dsize = strlen ( d ) + 1 ;
1999-12-21 06:04:37 +03:00
if ( tdb_store ( tdb , key , dbuf , TDB_INSERT ) = = - 1 ) {
terror ( " insert failed " ) ;
}
}
static void store_tdb ( void )
{
2001-08-08 03:21:45 +04:00
char * k = get_token ( 1 ) ;
char * d = get_token ( 0 ) ;
1999-12-21 06:04:37 +03:00
TDB_DATA key , dbuf ;
if ( ! k | | ! d ) {
help ( ) ;
return ;
}
key . dptr = k ;
2001-08-08 03:21:45 +04:00
key . dsize = strlen ( k ) + 1 ;
1999-12-21 06:04:37 +03:00
dbuf . dptr = d ;
2001-08-08 03:21:45 +04:00
dbuf . dsize = strlen ( d ) + 1 ;
printf ( " Storing key: \n " ) ;
print_rec ( tdb , key , dbuf , NULL ) ;
1999-12-21 06:04:37 +03:00
if ( tdb_store ( tdb , key , dbuf , TDB_REPLACE ) = = - 1 ) {
terror ( " store failed " ) ;
}
}
static void show_tdb ( void )
{
2001-08-08 03:21:45 +04:00
char * k = get_token ( 1 ) ;
1999-12-21 06:04:37 +03:00
TDB_DATA key , dbuf ;
if ( ! k ) {
help ( ) ;
return ;
}
key . dptr = k ;
2000-10-06 02:19:34 +04:00
key . dsize = strlen ( k ) + 1 ;
1999-12-21 06:04:37 +03:00
dbuf = tdb_fetch ( tdb , key ) ;
2001-12-03 07:15:26 +03:00
if ( ! dbuf . dptr ) {
terror ( " fetch failed " ) ;
return ;
}
2000-10-06 02:19:34 +04:00
/* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
print_rec ( tdb , key , dbuf , NULL ) ;
1999-12-21 06:04:37 +03:00
}
static void delete_tdb ( void )
{
2001-08-08 03:21:45 +04:00
char * k = get_token ( 1 ) ;
1999-12-21 06:04:37 +03:00
TDB_DATA key ;
if ( ! k ) {
help ( ) ;
return ;
}
key . dptr = k ;
2001-08-08 03:21:45 +04:00
key . dsize = strlen ( k ) + 1 ;
1999-12-21 06:04:37 +03:00
if ( tdb_delete ( tdb , key ) ! = 0 ) {
terror ( " delete failed " ) ;
}
}
2001-12-11 11:24:36 +03:00
#if 0
2001-01-30 00:34:08 +03:00
static int print_conn_key ( TDB_DATA key )
{
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 ( " 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 ) ) ;
return 0 ;
}
2001-12-11 11:24:36 +03:00
# endif
2001-01-30 00:34:08 +03:00
2001-12-11 11:24:36 +03:00
static int print_rec ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf , void * state )
1999-12-21 06:04:37 +03:00
{
2001-01-30 00:34:08 +03:00
#if 0
print_conn_key ( key ) ;
print_conn_data ( dbuf ) ;
return 0 ;
# else
2000-04-24 18:36:44 +04:00
printf ( " \n key %d bytes \n " , key . dsize ) ;
2001-12-03 03:23:14 +03:00
print_asc ( key . dptr , key . dsize ) ;
2001-12-10 07:59:17 +03:00
printf ( " \n data %d bytes \n " , dbuf . dsize ) ;
2000-04-24 18:36:44 +04:00
print_data ( dbuf . dptr , dbuf . dsize ) ;
1999-12-21 06:04:37 +03:00
return 0 ;
2001-01-30 00:34:08 +03:00
# endif
1999-12-21 06:04:37 +03:00
}
2001-12-11 11:24:36 +03:00
static int print_key ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf , void * state )
2001-11-28 06:58:33 +03:00
{
2001-12-03 03:23:14 +03:00
print_asc ( key . dptr , key . dsize ) ;
printf ( " \n " ) ;
2001-11-28 06:58:33 +03:00
return 0 ;
}
1999-12-21 06:04:37 +03:00
static int total_bytes ;
2001-12-11 11:24:36 +03:00
static int traverse_fn ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf , void * state )
1999-12-21 06:04:37 +03:00
{
total_bytes + = dbuf . dsize ;
return 0 ;
}
static void info_tdb ( void )
{
int count ;
total_bytes = 0 ;
2001-02-13 19:28:48 +03:00
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 ) ;
1999-12-21 06:04:37 +03:00
}
2001-08-08 03:21:45 +04:00
static char * tdb_getline ( char * prompt )
2000-01-07 06:02:13 +03:00
{
static char line [ 1024 ] ;
char * p ;
fputs ( prompt , stdout ) ;
line [ 0 ] = 0 ;
p = fgets ( line , sizeof ( line ) - 1 , stdin ) ;
if ( p ) p = strchr ( p , ' \n ' ) ;
if ( p ) * p = 0 ;
return p ? line : NULL ;
}
2001-12-11 11:24:36 +03:00
static int do_delete_fn ( TDB_CONTEXT * the_tdb , TDB_DATA key , TDB_DATA dbuf ,
2000-02-28 03:37:13 +03:00
void * state )
{
2001-12-11 11:24:36 +03:00
return tdb_delete ( the_tdb , key ) ;
2000-02-28 03:37:13 +03:00
}
2001-12-11 11:24:36 +03:00
static void first_record ( TDB_CONTEXT * the_tdb , TDB_DATA * pkey )
2000-12-07 20:46:11 +03:00
{
TDB_DATA dbuf ;
2001-12-11 11:24:36 +03:00
* pkey = tdb_firstkey ( the_tdb ) ;
2000-12-07 20:46:11 +03:00
2001-12-11 11:24:36 +03:00
dbuf = tdb_fetch ( the_tdb , * pkey ) ;
2000-12-07 20:46:11 +03:00
if ( ! dbuf . dptr ) terror ( " fetch failed " ) ;
/* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
2001-12-11 11:24:36 +03:00
print_rec ( the_tdb , * pkey , dbuf , NULL ) ;
2000-12-07 20:46:11 +03:00
}
2001-12-11 11:24:36 +03:00
static void next_record ( TDB_CONTEXT * the_tdb , TDB_DATA * pkey )
2000-12-07 20:46:11 +03:00
{
TDB_DATA dbuf ;
2001-12-11 11:24:36 +03:00
* pkey = tdb_nextkey ( the_tdb , * pkey ) ;
2000-12-07 20:46:11 +03:00
2001-12-11 11:24:36 +03:00
dbuf = tdb_fetch ( the_tdb , * pkey ) ;
2001-01-30 00:34:08 +03:00
if ( ! dbuf . dptr )
terror ( " fetch failed " ) ;
else
/* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
2001-12-11 11:24:36 +03:00
print_rec ( the_tdb , * pkey , dbuf , NULL ) ;
2000-12-07 20:46:11 +03:00
}
1999-12-21 06:04:37 +03:00
int main ( int argc , char * argv [ ] )
{
2001-01-30 00:34:08 +03:00
int bIterate = 0 ;
2000-03-13 04:35:09 +03:00
char * line ;
char * tok ;
2000-12-07 20:46:11 +03:00
TDB_DATA iterate_kbuf ;
2000-10-06 02:19:34 +04:00
if ( argv [ 1 ] ) {
static char tmp [ 1024 ] ;
sprintf ( tmp , " open %s " , argv [ 1 ] ) ;
tok = strtok ( tmp , " " ) ;
open_tdb ( ) ;
}
2001-08-08 03:21:45 +04:00
while ( ( line = tdb_getline ( " tdb> " ) ) ) {
2000-03-13 04:35:09 +03:00
/* Shell command */
if ( line [ 0 ] = = ' ! ' ) {
system ( line + 1 ) ;
continue ;
}
2000-10-06 02:19:34 +04:00
if ( ( tok = strtok ( line , " " ) ) = = NULL ) {
2001-01-30 00:34:08 +03:00
if ( bIterate )
next_record ( tdb , & iterate_kbuf ) ;
continue ;
2000-10-06 02:19:34 +04:00
}
2000-03-13 04:35:09 +03:00
if ( strcmp ( tok , " create " ) = = 0 ) {
2001-01-30 00:34:08 +03:00
bIterate = 0 ;
2000-03-13 04:35:09 +03:00
create_tdb ( ) ;
continue ;
} else if ( strcmp ( tok , " open " ) = = 0 ) {
open_tdb ( ) ;
continue ;
2001-08-08 03:21:45 +04:00
} else if ( ( strcmp ( tok , " q " ) = = 0 ) | |
( strcmp ( tok , " quit " ) = = 0 ) ) {
break ;
}
2000-03-13 04:35:09 +03:00
/* all the rest require a open database */
if ( ! tdb ) {
2001-01-30 00:34:08 +03:00
bIterate = 0 ;
2000-03-13 04:35:09 +03:00
terror ( " database not open " ) ;
help ( ) ;
continue ;
}
if ( strcmp ( tok , " insert " ) = = 0 ) {
2001-01-30 00:34:08 +03:00
bIterate = 0 ;
2000-03-13 04:35:09 +03:00
insert_tdb ( ) ;
} else if ( strcmp ( tok , " store " ) = = 0 ) {
2001-01-30 00:34:08 +03:00
bIterate = 0 ;
2000-03-13 04:35:09 +03:00
store_tdb ( ) ;
} else if ( strcmp ( tok , " show " ) = = 0 ) {
2001-01-30 00:34:08 +03:00
bIterate = 0 ;
2000-03-13 04:35:09 +03:00
show_tdb ( ) ;
} else if ( strcmp ( tok , " erase " ) = = 0 ) {
2001-01-30 00:34:08 +03:00
bIterate = 0 ;
2000-03-13 04:35:09 +03:00
tdb_traverse ( tdb , do_delete_fn , NULL ) ;
} else if ( strcmp ( tok , " delete " ) = = 0 ) {
2001-01-30 00:34:08 +03:00
bIterate = 0 ;
2000-03-13 04:35:09 +03:00
delete_tdb ( ) ;
} else if ( strcmp ( tok , " dump " ) = = 0 ) {
2001-01-30 00:34:08 +03:00
bIterate = 0 ;
2000-03-13 04:35:09 +03:00
tdb_traverse ( tdb , print_rec , NULL ) ;
2001-05-30 10:22:10 +04:00
} else if ( strcmp ( tok , " list " ) = = 0 ) {
tdb_dump_all ( tdb ) ;
2001-01-30 00:34:08 +03:00
} else if ( strcmp ( tok , " free " ) = = 0 ) {
tdb_printfreelist ( tdb ) ;
2001-08-08 03:21:45 +04:00
} else if ( strcmp ( tok , " info " ) = = 0 ) {
info_tdb ( ) ;
2001-02-13 19:28:48 +03:00
} else if ( ( strcmp ( tok , " 1 " ) = = 0 ) | |
( strcmp ( tok , " first " ) = = 0 ) ) {
2001-01-30 00:34:08 +03:00
bIterate = 1 ;
first_record ( tdb , & iterate_kbuf ) ;
2001-02-13 19:28:48 +03:00
} else if ( ( strcmp ( tok , " n " ) = = 0 ) | |
( strcmp ( tok , " next " ) = = 0 ) ) {
2001-01-30 00:34:08 +03:00
next_record ( tdb , & iterate_kbuf ) ;
2001-11-28 06:58:33 +03:00
} else if ( ( strcmp ( tok , " keys " ) = = 0 ) ) {
bIterate = 0 ;
tdb_traverse ( tdb , print_key , NULL ) ;
2000-03-13 04:35:09 +03:00
} else {
help ( ) ;
}
}
if ( tdb ) tdb_close ( tdb ) ;
return 0 ;
1999-12-21 06:04:37 +03:00
}