2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
Samba utility functions
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
2003-08-13 05:53:07 +04:00
Copyright ( C ) Andrew Tridgell 1992 - 2001
Copyright ( C ) Simo Sorce 2001 - 2002
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
Copyright ( C ) Martin Pool 2003
2006-01-31 09:09:18 +03:00
Copyright ( C ) James Peach 2005
2003-08-13 05:53:07 +04:00
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-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 05:53:07 +04: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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 05:53:07 +04:00
*/
# include "includes.h"
2006-08-30 15:29:34 +04:00
# include "libcli/raw/smb.h"
2005-02-10 08:09:35 +03:00
# include "pstring.h"
2006-05-13 23:14:12 +04:00
# include "system/locale.h"
2003-08-13 05:53:07 +04:00
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
/**
* @ file
* @ brief String utilities .
* */
2003-08-13 05:53:07 +04:00
/**
Trim the specified elements off the front and back of a string .
* */
2007-06-01 16:01:53 +04:00
_PUBLIC_ bool trim_string ( char * s , const char * front , const char * back )
2003-08-13 05:53:07 +04:00
{
2007-06-01 16:01:53 +04:00
bool ret = false ;
2003-08-13 05:53:07 +04:00
size_t front_len ;
size_t back_len ;
size_t len ;
/* Ignore null or empty strings. */
if ( ! s | | ( s [ 0 ] = = ' \0 ' ) )
2007-06-01 16:01:53 +04:00
return false ;
2003-08-13 05:53:07 +04:00
front_len = front ? strlen ( front ) : 0 ;
back_len = back ? strlen ( back ) : 0 ;
len = strlen ( s ) ;
if ( front_len ) {
while ( len & & strncmp ( s , front , front_len ) = = 0 ) {
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
/* Must use memmove here as src & dest can
* easily overlap . Found by valgrind . JRA . */
memmove ( s , s + front_len , ( len - front_len ) + 1 ) ;
2003-08-13 05:53:07 +04:00
len - = front_len ;
2007-06-01 16:01:53 +04:00
ret = true ;
2003-08-13 05:53:07 +04:00
}
}
if ( back_len ) {
while ( ( len > = back_len ) & & strncmp ( s + len - back_len , back , back_len ) = = 0 ) {
s [ len - back_len ] = ' \0 ' ;
len - = back_len ;
2007-06-01 16:01:53 +04:00
ret = true ;
2003-08-13 05:53:07 +04:00
}
}
return ret ;
}
/**
Find the number of ' c ' chars in a string
* */
2007-06-01 16:01:53 +04:00
_PUBLIC_ _PURE_ size_t count_chars ( const char * s , char c )
2003-08-13 05:53:07 +04:00
{
2004-10-08 12:13:00 +04:00
size_t count = 0 ;
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
2004-10-08 12:13:00 +04:00
while ( * s ) {
2006-04-27 23:50:13 +04:00
if ( * s = = c ) count + + ;
s + + ;
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
}
2004-10-08 12:13:00 +04:00
return count ;
2003-08-13 05:53:07 +04:00
}
2006-04-27 23:50:13 +04:00
2003-08-13 05:53:07 +04:00
/**
Safe string copy into a known length string . maxlength does not
include the terminating zero .
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ char * safe_strcpy ( char * dest , const char * src , size_t maxlength )
2003-08-13 05:53:07 +04:00
{
size_t len ;
if ( ! dest ) {
DEBUG ( 0 , ( " ERROR: NULL dest in safe_strcpy \n " ) ) ;
return NULL ;
}
# ifdef DEVELOPER
/* We intentionally write out at the extremity of the destination
* string . If the destination is too short ( e . g . pstrcpy into mallocd
* or fstring ) then this should cause an error under a memory
* checker . */
dest [ maxlength ] = ' \0 ' ;
if ( PTR_DIFF ( & len , dest ) > 0 ) { /* check if destination is on the stack, ok if so */
log_suspicious_usage ( " safe_strcpy " , src ) ;
}
# endif
if ( ! src ) {
* dest = 0 ;
return dest ;
}
len = strlen ( src ) ;
if ( len > maxlength ) {
DEBUG ( 0 , ( " ERROR: string overflow by %u (%u - %u) in safe_strcpy [%.50s] \n " ,
2005-07-17 13:20:52 +04:00
( uint_t ) ( len - maxlength ) , ( unsigned ) len , ( unsigned ) maxlength , src ) ) ;
2003-08-13 05:53:07 +04:00
len = maxlength ;
}
memmove ( dest , src , len ) ;
dest [ len ] = 0 ;
return dest ;
}
/**
Safe string cat into a string . maxlength does not
include the terminating zero .
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ char * safe_strcat ( char * dest , const char * src , size_t maxlength )
2003-08-13 05:53:07 +04:00
{
size_t src_len , dest_len ;
if ( ! dest ) {
DEBUG ( 0 , ( " ERROR: NULL dest in safe_strcat \n " ) ) ;
return NULL ;
}
if ( ! src )
return dest ;
# ifdef DEVELOPER
if ( PTR_DIFF ( & src_len , dest ) > 0 ) { /* check if destination is on the stack, ok if so */
log_suspicious_usage ( " safe_strcat " , src ) ;
}
# endif
src_len = strlen ( src ) ;
dest_len = strlen ( dest ) ;
if ( src_len + dest_len > maxlength ) {
DEBUG ( 0 , ( " ERROR: string overflow by %d in safe_strcat [%.50s] \n " ,
( int ) ( src_len + dest_len - maxlength ) , src ) ) ;
if ( maxlength > dest_len ) {
memcpy ( & dest [ dest_len ] , src , maxlength - dest_len ) ;
}
dest [ maxlength ] = 0 ;
return NULL ;
}
memcpy ( & dest [ dest_len ] , src , src_len ) ;
dest [ dest_len + src_len ] = 0 ;
return dest ;
}
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
/**
Routine to get hex characters and turn them into a 16 byte array .
the array can be variable length , and any non - hex - numeric
characters are skipped . " 0xnn " or " 0Xnn " is specially catered
for .
valid examples : " 0A5D15 " ; " 0x15, 0x49, 0xa2 " ; " 59 \t a9 \t e3 \n "
2005-05-02 18:17:19 +04:00
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ size_t strhex_to_str ( char * p , size_t len , const char * strhex )
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
{
size_t i ;
size_t num_chars = 0 ;
uint8_t lonybble , hinybble ;
const char * hexchars = " 0123456789ABCDEF " ;
char * p1 = NULL , * p2 = NULL ;
for ( i = 0 ; i < len & & strhex [ i ] ! = 0 ; i + + ) {
if ( strncasecmp ( hexchars , " 0x " , 2 ) = = 0 ) {
i + + ; /* skip two chars */
continue ;
}
2006-04-27 20:05:05 +04:00
if ( ! ( p1 = strchr ( hexchars , toupper ( ( unsigned char ) strhex [ i ] ) ) ) )
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
break ;
i + + ; /* next hex digit */
2006-04-27 20:05:05 +04:00
if ( ! ( p2 = strchr ( hexchars , toupper ( ( unsigned char ) strhex [ i ] ) ) ) )
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
break ;
/* get the two nybbles */
hinybble = PTR_DIFF ( p1 , hexchars ) ;
lonybble = PTR_DIFF ( p2 , hexchars ) ;
p [ num_chars ] = ( hinybble < < 4 ) | lonybble ;
num_chars + + ;
p1 = NULL ;
p2 = NULL ;
}
return num_chars ;
}
2006-03-06 03:24:51 +03:00
/**
* Parse a hex string and return a data blob .
*/
2007-06-01 16:01:53 +04:00
_PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob ( const char * strhex )
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
{
DATA_BLOB ret_blob = data_blob ( NULL , strlen ( strhex ) / 2 + 1 ) ;
2006-01-18 18:51:50 +03:00
ret_blob . length = strhex_to_str ( ( char * ) ret_blob . data ,
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
strlen ( strhex ) ,
strhex ) ;
return ret_blob ;
}
2004-10-08 12:13:00 +04:00
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
/**
* Routine to print a buffer as HEX digits , into an allocated string .
*/
2006-03-05 20:15:19 +03:00
_PUBLIC_ void hex_encode ( const unsigned char * buff_in , size_t len , char * * out_hex_buffer )
r2552: Character set conversion and string handling updates.
The intial motivation for this commit was to merge in some of the
bugfixes present in Samba3's chrcnv and string handling code into
Samba4. However, along the way I found a lot of unused functions, and
decided to do a bit more...
The strlen_m code now does not use a fixed buffer, but more work is
needed to finish off other functions in str_util.c. These fixed
length buffers hav caused very nasty, hard to chase down bugs at some
sites.
The strupper_m() function has a strupper_talloc() to replace it (we
need to go around and fix more uses, but it's a start). Use of these
new functions will avoid bugs where the upper or lowercase version of
a string is a different length.
I have removed the push_*_allocate functions, which are replaced by
calls to push_*_talloc. Likewise, pstring and other 'fixed length'
wrappers are removed, where possible.
I have removed the first ('base pointer') argument, used by push_ucs2,
as the Samba4 way of doing things ensures that this is always on an
even boundary anyway. (It was used in only one place, in any case).
(This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392)
2004-09-23 04:51:45 +04:00
{
int i ;
char * hex_buffer ;
* out_hex_buffer = smb_xmalloc ( ( len * 2 ) + 1 ) ;
hex_buffer = * out_hex_buffer ;
for ( i = 0 ; i < len ; i + + )
slprintf ( & hex_buffer [ i * 2 ] , 3 , " %02X " , buff_in [ i ] ) ;
}
2007-07-10 12:07:42 +04:00
/**
* talloc version of hex_encode ( )
*/
_PUBLIC_ char * hex_encode_talloc ( TALLOC_CTX * mem_ctx , const unsigned char * buff_in , size_t len )
{
int i ;
char * hex_buffer ;
hex_buffer = talloc_array ( mem_ctx , char , ( len * 2 ) + 1 ) ;
for ( i = 0 ; i < len ; i + + )
slprintf ( & hex_buffer [ i * 2 ] , 3 , " %02X " , buff_in [ i ] ) ;
return hex_buffer ;
}
2003-08-13 05:53:07 +04:00
/**
Set a string value , allocing the space for the string
* */
static BOOL string_init ( char * * dest , const char * src )
{
if ( ! src ) src = " " ;
( * dest ) = strdup ( src ) ;
if ( ( * dest ) = = NULL ) {
DEBUG ( 0 , ( " Out of memory in string_init \n " ) ) ;
return False ;
}
return True ;
}
/**
Free a string value .
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ void string_free ( char * * s )
2003-08-13 05:53:07 +04:00
{
if ( s ) SAFE_FREE ( * s ) ;
}
/**
Set a string value , deallocating any existing space , and allocing the space
for the string
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ BOOL string_set ( char * * dest , const char * src )
2003-08-13 05:53:07 +04:00
{
string_free ( dest ) ;
return string_init ( dest , src ) ;
}
/**
Substitute a string for a pattern in another string . Make sure there is
enough room !
This routine looks for pattern in s and replaces it with
insert . It may do multiple replacements .
Any of " ; ' $ or ` in the insert string are replaced with _
if len = = 0 then the string cannot be extended . This is different from the old
use of len = = 0 which was for no length checks to be done .
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ void string_sub ( char * s , const char * pattern , const char * insert , size_t len )
2003-08-13 05:53:07 +04:00
{
char * p ;
ssize_t ls , lp , li , i ;
if ( ! insert | | ! pattern | | ! * pattern | | ! s )
return ;
ls = ( ssize_t ) strlen ( s ) ;
lp = ( ssize_t ) strlen ( pattern ) ;
li = ( ssize_t ) strlen ( insert ) ;
if ( len = = 0 )
len = ls + 1 ; /* len is number of *bytes* */
while ( lp < = ls & & ( p = strstr ( s , pattern ) ) ) {
if ( ls + ( li - lp ) > = len ) {
DEBUG ( 0 , ( " ERROR: string overflow by %d in string_sub(%.50s, %d) \n " ,
( int ) ( ls + ( li - lp ) - len ) ,
pattern , ( int ) len ) ) ;
break ;
}
if ( li ! = lp ) {
memmove ( p + li , p + lp , strlen ( p + lp ) + 1 ) ;
}
for ( i = 0 ; i < li ; i + + ) {
switch ( insert [ i ] ) {
case ' ` ' :
case ' " ' :
case ' \' ' :
case ' ; ' :
case ' $ ' :
case ' % ' :
case ' \r ' :
case ' \n ' :
p [ i ] = ' _ ' ;
break ;
default :
p [ i ] = insert [ i ] ;
}
}
s = p + li ;
ls + = ( li - lp ) ;
}
}
/**
Similar to string_sub ( ) but allows for any character to be substituted .
Use with caution !
if len = = 0 then the string cannot be extended . This is different from the old
use of len = = 0 which was for no length checks to be done .
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ void all_string_sub ( char * s , const char * pattern , const char * insert , size_t len )
2003-08-13 05:53:07 +04:00
{
char * p ;
ssize_t ls , lp , li ;
if ( ! insert | | ! pattern | | ! s )
return ;
ls = ( ssize_t ) strlen ( s ) ;
lp = ( ssize_t ) strlen ( pattern ) ;
li = ( ssize_t ) strlen ( insert ) ;
if ( ! * pattern )
return ;
if ( len = = 0 )
len = ls + 1 ; /* len is number of *bytes* */
while ( lp < = ls & & ( p = strstr ( s , pattern ) ) ) {
if ( ls + ( li - lp ) > = len ) {
DEBUG ( 0 , ( " ERROR: string overflow by %d in all_string_sub(%.50s, %d) \n " ,
( int ) ( ls + ( li - lp ) - len ) ,
pattern , ( int ) len ) ) ;
break ;
}
if ( li ! = lp ) {
memmove ( p + li , p + lp , strlen ( p + lp ) + 1 ) ;
}
memcpy ( p , insert , li ) ;
s = p + li ;
ls + = ( li - lp ) ;
}
}
2003-11-23 13:50:52 +03:00
2003-08-13 05:53:07 +04:00
/**
Unescape a URL encoded string , in place .
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ void rfc1738_unescape ( char * buf )
2003-08-13 05:53:07 +04:00
{
char * p = buf ;
2006-04-27 23:50:13 +04:00
while ( ( p = strchr ( p , ' + ' ) ) )
2003-08-13 05:53:07 +04:00
* p = ' ' ;
p = buf ;
2006-04-27 23:50:13 +04:00
while ( p & & * p & & ( p = strchr ( p , ' % ' ) ) ) {
2003-08-13 05:53:07 +04:00
int c1 = p [ 1 ] ;
int c2 = p [ 2 ] ;
if ( c1 > = ' 0 ' & & c1 < = ' 9 ' )
c1 = c1 - ' 0 ' ;
else if ( c1 > = ' A ' & & c1 < = ' F ' )
c1 = 10 + c1 - ' A ' ;
else if ( c1 > = ' a ' & & c1 < = ' f ' )
c1 = 10 + c1 - ' a ' ;
else { p + + ; continue ; }
if ( c2 > = ' 0 ' & & c2 < = ' 9 ' )
c2 = c2 - ' 0 ' ;
else if ( c2 > = ' A ' & & c2 < = ' F ' )
c2 = 10 + c2 - ' A ' ;
else if ( c2 > = ' a ' & & c2 < = ' f ' )
c2 = 10 + c2 - ' a ' ;
else { p + + ; continue ; }
* p = ( c1 < < 4 ) | c2 ;
memmove ( p + 1 , p + 3 , strlen ( p + 3 ) + 1 ) ;
p + + ;
}
}
# ifdef VALGRIND
size_t valgrind_strlen ( const char * s )
{
size_t count ;
for ( count = 0 ; * s + + ; count + + )
;
return count ;
}
# endif
2004-06-06 16:59:14 +04:00
2006-02-28 16:12:39 +03:00
/**
2004-06-06 16:59:14 +04:00
format a string into length - prefixed dotted domain format , as used in NBT
and in some ADS structures
2006-02-28 16:12:39 +03:00
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ const char * str_format_nbt_domain ( TALLOC_CTX * mem_ctx , const char * s )
2004-06-06 16:59:14 +04:00
{
char * ret ;
int i ;
if ( ! s | | ! * s ) {
return talloc_strdup ( mem_ctx , " " ) ;
}
2005-01-06 06:06:58 +03:00
ret = talloc_size ( mem_ctx , strlen ( s ) + 2 ) ;
2004-06-06 16:59:14 +04:00
if ( ! ret ) {
return ret ;
}
memcpy ( ret + 1 , s , strlen ( s ) + 1 ) ;
ret [ 0 ] = ' . ' ;
for ( i = 0 ; ret [ i ] ; i + + ) {
if ( ret [ i ] = = ' . ' ) {
char * p = strchr ( ret + i + 1 , ' . ' ) ;
if ( p ) {
ret [ i ] = p - ( ret + i + 1 ) ;
} else {
ret [ i ] = strlen ( ret + i + 1 ) ;
}
}
}
return ret ;
}
2004-08-12 10:30:03 +04:00
2006-03-06 03:24:51 +03:00
/**
* Add a string to an array of strings .
*
* num should be a pointer to an integer that holds the current
* number of elements in strings . It will be updated by this function .
*/
2006-03-05 20:15:19 +03:00
_PUBLIC_ BOOL add_string_to_array ( TALLOC_CTX * mem_ctx ,
2004-08-12 10:30:03 +04:00
const char * str , const char * * * strings , int * num )
{
char * dup_str = talloc_strdup ( mem_ctx , str ) ;
2005-01-27 10:08:20 +03:00
* strings = talloc_realloc ( mem_ctx ,
2004-09-27 05:36:19 +04:00
* strings ,
const char * , ( ( * num ) + 1 ) ) ;
2004-08-12 10:30:03 +04:00
if ( ( * strings = = NULL ) | | ( dup_str = = NULL ) )
return False ;
( * strings ) [ * num ] = dup_str ;
* num + = 1 ;
return True ;
}
2004-08-14 09:57:43 +04:00
2006-02-28 16:12:39 +03:00
/**
2004-08-14 09:57:43 +04:00
varient of strcmp ( ) that handles NULL ptrs
2006-02-28 16:12:39 +03:00
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ int strcmp_safe ( const char * s1 , const char * s2 )
2004-08-14 09:57:43 +04:00
{
if ( s1 = = s2 ) {
return 0 ;
}
if ( s1 = = NULL | | s2 = = NULL ) {
return s1 ? - 1 : 1 ;
}
return strcmp ( s1 , s2 ) ;
}
2004-09-20 11:21:26 +04:00
2006-02-28 16:12:39 +03:00
/**
2004-10-20 06:02:00 +04:00
return the number of bytes occupied by a buffer in ASCII format
the result includes the null termination
limited by ' n ' bytes
2006-02-28 16:12:39 +03:00
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ size_t ascii_len_n ( const char * src , size_t n )
2004-10-20 06:02:00 +04:00
{
size_t len ;
len = strnlen ( src , n ) ;
if ( len + 1 < = n ) {
len + = 1 ;
}
return len ;
}
2006-02-28 16:12:39 +03:00
/**
2004-09-20 11:21:26 +04:00
Return a string representing a CIFS attribute for a file .
2006-02-28 16:12:39 +03:00
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ char * attrib_string ( TALLOC_CTX * mem_ctx , uint32_t attrib )
2004-09-20 11:21:26 +04:00
{
int i , len ;
const struct {
char c ;
uint16_t attr ;
} attr_strs [ ] = {
{ ' V ' , FILE_ATTRIBUTE_VOLUME } ,
{ ' D ' , FILE_ATTRIBUTE_DIRECTORY } ,
{ ' A ' , FILE_ATTRIBUTE_ARCHIVE } ,
{ ' H ' , FILE_ATTRIBUTE_HIDDEN } ,
{ ' S ' , FILE_ATTRIBUTE_SYSTEM } ,
2004-12-18 04:16:04 +03:00
{ ' N ' , FILE_ATTRIBUTE_NORMAL } ,
2004-09-20 11:21:26 +04:00
{ ' R ' , FILE_ATTRIBUTE_READONLY } ,
{ ' d ' , FILE_ATTRIBUTE_DEVICE } ,
{ ' t ' , FILE_ATTRIBUTE_TEMPORARY } ,
{ ' s ' , FILE_ATTRIBUTE_SPARSE } ,
{ ' r ' , FILE_ATTRIBUTE_REPARSE_POINT } ,
{ ' c ' , FILE_ATTRIBUTE_COMPRESSED } ,
{ ' o ' , FILE_ATTRIBUTE_OFFLINE } ,
{ ' n ' , FILE_ATTRIBUTE_NONINDEXED } ,
{ ' e ' , FILE_ATTRIBUTE_ENCRYPTED }
} ;
char * ret ;
2005-01-06 06:06:58 +03:00
ret = talloc_size ( mem_ctx , ARRAY_SIZE ( attr_strs ) + 1 ) ;
2004-09-20 11:21:26 +04:00
if ( ! ret ) {
return NULL ;
}
for ( len = i = 0 ; i < ARRAY_SIZE ( attr_strs ) ; i + + ) {
if ( attrib & attr_strs [ i ] . attr ) {
ret [ len + + ] = attr_strs [ i ] . c ;
}
}
ret [ len ] = 0 ;
return ret ;
}
2006-01-28 15:15:24 +03:00
2006-02-28 16:12:39 +03:00
/**
2006-01-28 15:15:24 +03:00
Set a boolean variable from the text value stored in the passed string .
Returns True in success , False if the passed string does not correctly
represent a boolean .
2006-02-28 16:12:39 +03:00
* */
2006-01-28 15:15:24 +03:00
2006-03-05 20:15:19 +03:00
_PUBLIC_ BOOL set_boolean ( const char * boolean_string , BOOL * boolean )
2006-01-28 15:15:24 +03:00
{
if ( strwicmp ( boolean_string , " yes " ) = = 0 | |
strwicmp ( boolean_string , " true " ) = = 0 | |
strwicmp ( boolean_string , " on " ) = = 0 | |
strwicmp ( boolean_string , " 1 " ) = = 0 ) {
* boolean = True ;
return True ;
} else if ( strwicmp ( boolean_string , " no " ) = = 0 | |
strwicmp ( boolean_string , " false " ) = = 0 | |
strwicmp ( boolean_string , " off " ) = = 0 | |
strwicmp ( boolean_string , " 0 " ) = = 0 ) {
* boolean = False ;
return True ;
}
return False ;
}
2006-03-06 03:24:51 +03:00
/**
* Parse a string containing a boolean value .
*
* val will be set to the read value .
*
* @ retval True if a boolean value was parsed , False otherwise .
*/
2006-03-05 20:15:19 +03:00
_PUBLIC_ BOOL conv_str_bool ( const char * str , BOOL * val )
2006-01-31 09:09:18 +03:00
{
char * end = NULL ;
long lval ;
if ( str = = NULL | | * str = = ' \0 ' ) {
return False ;
}
lval = strtol ( str , & end , 10 /* base */ ) ;
if ( end = = NULL | | * end ! = ' \0 ' | | end = = str ) {
return set_boolean ( str , val ) ;
}
* val = ( lval ) ? True : False ;
return True ;
}
2006-02-28 16:12:39 +03:00
/**
* Convert a size specification like 16 K into an integral number of bytes .
* */
2006-03-05 20:15:19 +03:00
_PUBLIC_ BOOL conv_str_size ( const char * str , uint64_t * val )
2006-01-31 09:09:18 +03:00
{
char * end = NULL ;
unsigned long long lval ;
if ( str = = NULL | | * str = = ' \0 ' ) {
return False ;
}
lval = strtoull ( str , & end , 10 /* base */ ) ;
if ( end = = NULL | | end = = str ) {
return False ;
}
if ( * end ) {
if ( strwicmp ( end , " K " ) = = 0 ) {
lval * = 1024ULL ;
} else if ( strwicmp ( end , " M " ) = = 0 ) {
lval * = ( 1024ULL * 1024ULL ) ;
} else if ( strwicmp ( end , " G " ) = = 0 ) {
lval * = ( 1024ULL * 1024ULL * 1024ULL ) ;
} else if ( strwicmp ( end , " T " ) = = 0 ) {
lval * = ( 1024ULL * 1024ULL * 1024ULL * 1024ULL ) ;
} else if ( strwicmp ( end , " P " ) = = 0 ) {
lval * = ( 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL ) ;
} else {
return False ;
}
}
* val = ( uint64_t ) lval ;
return True ;
}
2006-03-06 03:24:51 +03:00
/**
* Parse a uint64_t value from a string
*
* val will be set to the value read .
*
* @ retval True if parsing was successful , False otherwise
*/
2006-03-05 20:15:19 +03:00
_PUBLIC_ BOOL conv_str_u64 ( const char * str , uint64_t * val )
2006-01-31 09:09:18 +03:00
{
char * end = NULL ;
unsigned long long lval ;
if ( str = = NULL | | * str = = ' \0 ' ) {
return False ;
}
lval = strtoull ( str , & end , 10 /* base */ ) ;
if ( end = = NULL | | * end ! = ' \0 ' | | end = = str ) {
return False ;
}
* val = ( uint64_t ) lval ;
return True ;
}
2006-04-27 20:05:05 +04:00
/**
return the number of bytes occupied by a buffer in CH_UTF16 format
the result includes the null termination
* */
_PUBLIC_ size_t utf16_len ( const void * buf )
{
size_t len ;
for ( len = 0 ; SVAL ( buf , len ) ; len + = 2 ) ;
return len + 2 ;
}
/**
return the number of bytes occupied by a buffer in CH_UTF16 format
the result includes the null termination
limited by ' n ' bytes
* */
_PUBLIC_ size_t utf16_len_n ( const void * src , size_t n )
{
size_t len ;
for ( len = 0 ; ( len + 2 < n ) & & SVAL ( src , len ) ; len + = 2 ) ;
if ( len + 2 < = n ) {
len + = 2 ;
}
return len ;
}
_PUBLIC_ size_t ucs2_align ( const void * base_ptr , const void * p , int flags )
{
if ( flags & ( STR_NOALIGN | STR_ASCII ) )
return 0 ;
return PTR_DIFF ( p , base_ptr ) & 1 ;
}
/**
Do a case - insensitive , whitespace - ignoring string compare .
* */
_PUBLIC_ int strwicmp ( const char * psz1 , const char * psz2 )
{
/* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
/* appropriate value. */
if ( psz1 = = psz2 )
return ( 0 ) ;
else if ( psz1 = = NULL )
return ( - 1 ) ;
else if ( psz2 = = NULL )
return ( 1 ) ;
/* sync the strings on first non-whitespace */
while ( 1 ) {
while ( isspace ( ( int ) * psz1 ) )
psz1 + + ;
while ( isspace ( ( int ) * psz2 ) )
psz2 + + ;
if ( toupper ( ( unsigned char ) * psz1 ) ! = toupper ( ( unsigned char ) * psz2 )
| | * psz1 = = ' \0 '
| | * psz2 = = ' \0 ' )
break ;
psz1 + + ;
psz2 + + ;
}
return ( * psz1 - * psz2 ) ;
}
/**
String replace .
* */
_PUBLIC_ void string_replace ( char * s , char oldc , char newc )
{
2006-04-29 15:32:54 +04:00
while ( * s ) {
2006-04-27 20:05:05 +04:00
if ( * s = = oldc ) * s = newc ;
2006-04-29 15:32:54 +04:00
s + + ;
2006-04-27 20:05:05 +04:00
}
}
/**
* Compare 2 strings .
*
* @ note The comparison is case - insensitive .
* */
_PUBLIC_ BOOL strequal ( const char * s1 , const char * s2 )
{
if ( s1 = = s2 )
return ( True ) ;
if ( ! s1 | | ! s2 )
return ( False ) ;
return strcasecmp ( s1 , s2 ) = = 0 ;
}