2013-03-18 14:39:04 +01:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
2001-12-09 07:49:20 +00:00
simple tdb dump util
Copyright ( C ) Andrew Tridgell 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-12-09 07:49:20 +00:00
( at your option ) any later version .
2013-03-18 14:39:04 +01:00
2001-12-09 07:49:20 +00:00
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 .
2013-03-18 14:39:04 +01:00
2001-12-09 07:49:20 +00:00
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-12-09 07:49:20 +00:00
*/
2007-04-17 16:36:24 +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"
2001-12-09 07:49:20 +00:00
# include "tdb.h"
static void print_data ( TDB_DATA d )
{
2005-10-18 03:24:00 +00:00
unsigned char * p = ( unsigned char * ) d . dptr ;
2001-12-09 07:49:20 +00:00
int len = d . dsize ;
while ( len - - ) {
if ( isprint ( * p ) & & ! strchr ( " \" \\ " , * p ) ) {
fputc ( * p , stdout ) ;
} else {
printf ( " \\ %02X " , * p ) ;
}
p + + ;
}
}
static int traverse_fn ( TDB_CONTEXT * tdb , TDB_DATA key , TDB_DATA dbuf , void * state )
{
printf ( " { \n " ) ;
2018-03-04 10:07:09 +01:00
printf ( " key(%zu) = \" " , key . dsize ) ;
2001-12-09 07:49:20 +00:00
print_data ( key ) ;
printf ( " \" \n " ) ;
2018-03-04 10:07:09 +01:00
printf ( " data(%zu) = \" " , dbuf . dsize ) ;
2001-12-09 07:49:20 +00:00
print_data ( dbuf ) ;
printf ( " \" \n " ) ;
printf ( " } \n " ) ;
return 0 ;
}
2016-08-02 18:17:34 +10:00
static void log_stderr ( struct tdb_context * tdb , enum tdb_debug_level level ,
const char * fmt , . . . ) PRINTF_ATTRIBUTE ( 3 , 4 ) ;
2012-10-04 09:04:23 +09:30
static void log_stderr ( struct tdb_context * tdb , enum tdb_debug_level level ,
const char * fmt , . . . )
{
va_list ap ;
const char * name = tdb_name ( tdb ) ;
const char * prefix = " " ;
if ( ! name )
name = " unnamed " ;
switch ( level ) {
case TDB_DEBUG_ERROR :
prefix = " ERROR: " ;
break ;
case TDB_DEBUG_WARNING :
prefix = " WARNING: " ;
break ;
case TDB_DEBUG_TRACE :
return ;
default :
case TDB_DEBUG_FATAL :
prefix = " FATAL: " ;
break ;
}
va_start ( ap , fmt ) ;
fprintf ( stderr , " tdb(%s): %s " , name , prefix ) ;
vfprintf ( stderr , fmt , ap ) ;
va_end ( ap ) ;
}
2012-10-04 09:04:23 +09:30
static void emergency_walk ( TDB_DATA key , TDB_DATA dbuf , void * keyname )
{
if ( keyname ) {
if ( key . dsize ! = strlen ( keyname ) )
return ;
if ( memcmp ( key . dptr , keyname , key . dsize ) ! = 0 )
return ;
}
traverse_fn ( NULL , key , dbuf , NULL ) ;
}
static int dump_tdb ( const char * fname , const char * keyname , bool emergency )
2001-12-09 07:49:20 +00:00
{
TDB_CONTEXT * tdb ;
2006-01-27 21:49:01 +00:00
TDB_DATA key , value ;
2018-12-13 11:24:12 +01:00
struct tdb_logging_context logfn = {
. log_fn = log_stderr ,
} ;
2013-02-21 16:34:32 +01:00
int tdb_flags = TDB_DEFAULT ;
2013-03-18 14:39:04 +01:00
2013-02-21 16:34:32 +01:00
/*
* Note : that O_RDONLY implies TDB_NOLOCK , but we want to make it
* explicit as it ' s important when working on databases which were
* created with mutex locking .
*/
tdb_flags | = TDB_NOLOCK ;
tdb = tdb_open_ex ( fname , 0 , tdb_flags , O_RDONLY , 0 , & logfn , NULL ) ;
2001-12-09 07:49:20 +00:00
if ( ! tdb ) {
printf ( " Failed to open %s \n " , fname ) ;
return 1 ;
}
2012-10-04 09:04:23 +09:30
if ( emergency ) {
2014-02-03 11:30:12 +01:00
return tdb_rescue ( tdb , emergency_walk , discard_const ( keyname ) ) = = 0 ;
2012-10-04 09:04:23 +09:30
}
2006-01-27 21:49:01 +00:00
if ( ! keyname ) {
2012-10-04 09:04:23 +09:30
return tdb_traverse ( tdb , traverse_fn , NULL ) = = - 1 ? 1 : 0 ;
2006-01-27 21:49:01 +00:00
} else {
2009-10-16 19:02:02 +02:00
key . dptr = discard_const_p ( uint8_t , keyname ) ;
key . dsize = strlen ( keyname ) ;
2006-01-27 21:49:01 +00:00
value = tdb_fetch ( tdb , key ) ;
if ( ! value . dptr ) {
return 1 ;
} else {
print_data ( value ) ;
free ( value . dptr ) ;
}
}
2001-12-09 07:49:20 +00:00
return 0 ;
}
2006-01-27 21:49:01 +00:00
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 " ) ;
2012-10-04 09:04:23 +09:30
printf ( " -e emergency dump, for corrupt databases \n " ) ;
2006-01-27 21:49:01 +00:00
}
2001-12-09 07:49:20 +00:00
int main ( int argc , char * argv [ ] )
{
2006-01-27 21:49:01 +00:00
char * fname , * keyname = NULL ;
2012-10-04 09:04:23 +09:30
bool emergency = false ;
2006-01-27 21:49:01 +00:00
int c ;
2001-12-09 07:49:20 +00:00
if ( argc < 2 ) {
printf ( " Usage: tdbdump <fname> \n " ) ;
exit ( 1 ) ;
}
2015-09-18 10:58:37 +02:00
while ( ( c = getopt ( argc , argv , " hk:e " ) ) ! = - 1 ) {
2006-01-27 21:49:01 +00:00
switch ( c ) {
case ' h ' :
usage ( ) ;
exit ( 0 ) ;
case ' k ' :
keyname = optarg ;
break ;
2012-10-04 09:04:23 +09:30
case ' e ' :
emergency = true ;
break ;
2006-01-27 21:49:01 +00:00
default :
usage ( ) ;
exit ( 1 ) ;
}
}
fname = argv [ optind ] ;
2001-12-09 07:49:20 +00:00
2012-10-04 09:04:23 +09:30
return dump_tdb ( fname , keyname , emergency ) ;
2001-12-09 07:49:20 +00:00
}