2000-04-29 04:05:38 +00:00
/*
Unix SMB / Netbios implementation .
Version 3.0
tdb utility functions
Copyright ( C ) Andrew Tridgell 1992 - 1998
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 .
*/
# include "includes.h"
/* these are little tdb utility functions that are meant to make
dealing with a tdb database a little less cumbersome in Samba */
2000-10-10 06:43:26 +00:00
/* lock a chain by string */
int tdb_lock_bystring ( TDB_CONTEXT * tdb , char * keyval )
{
TDB_DATA key ;
key . dptr = keyval ;
key . dsize = strlen ( keyval ) + 1 ;
2000-12-06 00:05:15 +00:00
return tdb_chainlock ( tdb , key ) ;
2000-10-10 06:43:26 +00:00
}
/* unlock a chain by string */
2000-12-06 02:53:36 +00:00
void tdb_unlock_bystring ( TDB_CONTEXT * tdb , char * keyval )
2000-10-10 06:43:26 +00:00
{
TDB_DATA key ;
key . dptr = keyval ;
key . dsize = strlen ( keyval ) + 1 ;
2000-12-06 02:53:36 +00:00
tdb_chainunlock ( tdb , key ) ;
2000-10-10 06:43:26 +00:00
}
/* lock a chain by string key */
2000-04-29 04:05:38 +00:00
/* fetch a value by a arbitrary blob key, return -1 if not found */
2000-05-12 06:27:35 +00:00
int tdb_fetch_int_byblob ( TDB_CONTEXT * tdb , char * keyval , size_t len )
2000-04-29 04:05:38 +00:00
{
TDB_DATA key , data ;
int ret ;
key . dptr = keyval ;
key . dsize = len ;
data = tdb_fetch ( tdb , key ) ;
if ( ! data . dptr | | data . dsize ! = sizeof ( int ) ) return - 1 ;
memcpy ( & ret , data . dptr , sizeof ( int ) ) ;
free ( data . dptr ) ;
return ret ;
}
/* fetch a value by string key, return -1 if not found */
2000-05-12 06:27:35 +00:00
int tdb_fetch_int ( TDB_CONTEXT * tdb , char * keystr )
2000-04-29 04:05:38 +00:00
{
2000-05-12 06:27:35 +00:00
return tdb_fetch_int_byblob ( tdb , keystr , strlen ( keystr ) + 1 ) ;
2000-04-29 04:05:38 +00:00
}
/* store a value by an arbitary blob key, return 0 on success, -1 on failure */
int tdb_store_int_byblob ( TDB_CONTEXT * tdb , char * keystr , size_t len , int v )
{
TDB_DATA key , data ;
key . dptr = keystr ;
key . dsize = len ;
data . dptr = ( void * ) & v ;
data . dsize = sizeof ( int ) ;
return tdb_store ( tdb , key , data , TDB_REPLACE ) ;
}
/* store a value by string key, return 0 on success, -1 on failure */
int tdb_store_int ( TDB_CONTEXT * tdb , char * keystr , int v )
{
2000-05-12 06:27:35 +00:00
return tdb_store_int_byblob ( tdb , keystr , strlen ( keystr ) + 1 , v ) ;
2000-04-29 04:05:38 +00:00
}
2000-05-09 06:22:12 +00:00
/* Store a buffer by a null terminated string key. Return 0 on success, -1
on failure */
int tdb_store_by_string ( TDB_CONTEXT * tdb , char * keystr , void * buffer , int len )
{
TDB_DATA key , data ;
key . dptr = keystr ;
key . dsize = strlen ( keystr ) + 1 ;
data . dptr = buffer ;
data . dsize = len ;
return tdb_store ( tdb , key , data , TDB_REPLACE ) ;
}
/* Fetch a buffer using a null terminated string key. Don't forget to call
free ( ) on the result dptr . */
TDB_DATA tdb_fetch_by_string ( TDB_CONTEXT * tdb , char * keystr )
{
TDB_DATA key ;
key . dptr = keystr ;
key . dsize = strlen ( keystr ) + 1 ;
return tdb_fetch ( tdb , key ) ;
}
2000-05-24 06:36:58 +00:00
/* useful pair of routines for packing/unpacking data consisting of
integers and strings */
2001-04-10 21:07:04 +00:00
# ifdef HAVE_STDARG_H
2000-05-24 06:36:58 +00:00
size_t tdb_pack ( char * buf , int bufsize , char * fmt , . . . )
{
2001-04-10 21:07:04 +00:00
# else /* HAVE_STDARG_H */
size_t tdb_pack ( va_alist )
va_dcl
{
char * buf , * fmt ;
int bufsize ;
# endif /* HAVE_STDARG_H */
va_list ap ;
2000-05-24 06:36:58 +00:00
uint16 w ;
uint32 d ;
int i ;
void * p ;
2001-04-11 01:50:12 +00:00
int len = 0 ;
2000-05-24 06:36:58 +00:00
char * s ;
2001-04-10 21:07:04 +00:00
char c ;
# ifdef HAVE_STDARG_H
2000-05-24 06:36:58 +00:00
char * buf0 = buf ;
2000-06-04 02:29:45 +00:00
char * fmt0 = fmt ;
int bufsize0 = bufsize ;
2000-05-24 06:36:58 +00:00
va_start ( ap , fmt ) ;
2001-04-10 21:07:04 +00:00
# else /* HAVE_STDARG_H */
char * buf0 ;
char * fmt0 ;
int bufsize0 ;
va_start ( ap ) ;
buf = va_arg ( ap , char * ) ;
bufsize = va_arg ( ap , int ) ;
fmt = va_arg ( ap , char * ) ;
buf0 = buf ;
fmt0 = fmt ;
bufsize0 = bufsize ;
# endif /* HAVE_STDARG_H */
2000-05-24 06:36:58 +00:00
while ( * fmt ) {
switch ( ( c = * fmt + + ) ) {
case ' w ' :
len = 2 ;
2000-11-10 21:24:09 +00:00
w = ( uint16 ) va_arg ( ap , int ) ;
2000-05-24 06:36:58 +00:00
if ( bufsize > = len ) {
SSVAL ( buf , 0 , w ) ;
}
break ;
case ' d ' :
len = 4 ;
d = va_arg ( ap , uint32 ) ;
if ( bufsize > = len ) {
SIVAL ( buf , 0 , d ) ;
}
break ;
case ' p ' :
len = 4 ;
p = va_arg ( ap , void * ) ;
d = p ? 1 : 0 ;
if ( bufsize > = len ) {
SIVAL ( buf , 0 , d ) ;
}
break ;
2000-07-31 20:41:51 +00:00
case ' P ' :
s = va_arg ( ap , char * ) ;
w = strlen ( s ) ;
len = w + 1 ;
if ( bufsize > = len ) {
memcpy ( buf , s , len ) ;
}
break ;
2000-05-24 06:36:58 +00:00
case ' f ' :
s = va_arg ( ap , char * ) ;
w = strlen ( s ) ;
len = w + 1 ;
if ( bufsize > = len ) {
memcpy ( buf , s , len ) ;
}
break ;
case ' B ' :
i = va_arg ( ap , int ) ;
s = va_arg ( ap , char * ) ;
len = 4 + i ;
if ( bufsize > = len ) {
SIVAL ( buf , 0 , i ) ;
memcpy ( buf + 4 , s , i ) ;
}
break ;
default :
DEBUG ( 0 , ( " Unknown tdb_pack format %c in %s \n " ,
c , fmt ) ) ;
break ;
}
buf + = len ;
bufsize - = len ;
}
va_end ( ap ) ;
2000-06-04 02:29:45 +00:00
DEBUG ( 8 , ( " tdb_pack(%s, %d) -> %d \n " ,
fmt0 , bufsize0 , ( int ) PTR_DIFF ( buf , buf0 ) ) ) ;
2000-05-24 06:36:58 +00:00
return PTR_DIFF ( buf , buf0 ) ;
}
/* useful pair of routines for packing/unpacking data consisting of
integers and strings */
2001-04-10 21:07:04 +00:00
# ifdef HAVE_STDARG_H
2000-05-24 06:36:58 +00:00
int tdb_unpack ( char * buf , int bufsize , char * fmt , . . . )
{
2001-04-10 21:07:04 +00:00
# else /* HAVE_STDARG_H */
int tdb_unpack ( va_alist )
va_dcl
{
char * buf , * fmt ;
int bufsize ;
# endif /* HAVE_STDARG_H */
va_list ap ;
2000-05-24 06:36:58 +00:00
uint16 * w ;
uint32 * d ;
2001-04-11 01:50:12 +00:00
int len = 0 ;
2000-05-24 06:36:58 +00:00
int * i ;
void * * p ;
char * s , * * b ;
2001-04-10 21:07:04 +00:00
char c ;
# ifdef HAVE_STDARG_H
2000-05-24 06:36:58 +00:00
char * buf0 = buf ;
2000-06-04 02:29:45 +00:00
char * fmt0 = fmt ;
int bufsize0 = bufsize ;
2000-05-24 06:36:58 +00:00
va_start ( ap , fmt ) ;
2001-04-10 21:07:04 +00:00
# else /* HAVE_STDARG_H */
char * buf0 ;
char * fmt0 ;
int bufsize0 ;
va_start ( ap ) ;
buf = va_arg ( ap , char * ) ;
bufsize = va_arg ( ap , int ) ;
fmt = va_arg ( ap , char * ) ;
buf0 = buf ;
fmt0 = fmt ;
bufsize0 = bufsize ;
# endif /* HAVE_STDARG_H */
2000-05-24 06:36:58 +00:00
while ( * fmt ) {
switch ( ( c = * fmt + + ) ) {
case ' w ' :
len = 2 ;
w = va_arg ( ap , uint16 * ) ;
if ( bufsize < len ) goto no_space ;
* w = SVAL ( buf , 0 ) ;
break ;
case ' d ' :
len = 4 ;
d = va_arg ( ap , uint32 * ) ;
2000-05-27 09:53:11 +00:00
if ( bufsize < len ) goto no_space ;
2000-05-24 06:36:58 +00:00
* d = IVAL ( buf , 0 ) ;
break ;
case ' p ' :
len = 4 ;
p = va_arg ( ap , void * * ) ;
2000-05-27 09:53:11 +00:00
if ( bufsize < len ) goto no_space ;
2000-05-24 06:36:58 +00:00
* p = ( void * ) IVAL ( buf , 0 ) ;
break ;
2000-07-31 20:41:51 +00:00
case ' P ' :
s = va_arg ( ap , char * ) ;
len = strlen ( buf ) + 1 ;
if ( bufsize < len | | len > sizeof ( pstring ) ) goto no_space ;
memcpy ( s , buf , len ) ;
break ;
2000-05-24 06:36:58 +00:00
case ' f ' :
s = va_arg ( ap , char * ) ;
len = strlen ( buf ) + 1 ;
if ( bufsize < len | | len > sizeof ( fstring ) ) goto no_space ;
memcpy ( s , buf , len ) ;
break ;
case ' B ' :
i = va_arg ( ap , int * ) ;
b = va_arg ( ap , char * * ) ;
len = 4 ;
2000-05-27 09:53:11 +00:00
if ( bufsize < len ) goto no_space ;
* i = IVAL ( buf , 0 ) ;
if ( ! * i ) break ;
len + = * i ;
if ( bufsize < len ) goto no_space ;
* b = ( char * ) malloc ( * i ) ;
if ( ! * b ) goto no_space ;
memcpy ( * b , buf + 4 , * i ) ;
2000-05-24 06:36:58 +00:00
break ;
default :
DEBUG ( 0 , ( " Unknown tdb_unpack format %c in %s \n " ,
c , fmt ) ) ;
break ;
}
buf + = len ;
bufsize - = len ;
}
va_end ( ap ) ;
2000-06-04 02:29:45 +00:00
DEBUG ( 8 , ( " tdb_unpack(%s, %d) -> %d \n " ,
fmt0 , bufsize0 , ( int ) PTR_DIFF ( buf , buf0 ) ) ) ;
2000-05-24 06:36:58 +00:00
return PTR_DIFF ( buf , buf0 ) ;
no_space :
return - 1 ;
}