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
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
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"
2004-11-02 04:42:45 +03:00
# include "system/iconv.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
/**
* Get the next token from a string , return False if none found .
* Handles double - quotes .
*
* Based on a routine by GJC @ VILLAGE . COM .
* Extensively modified by Andrew . Tridgell @ anu . edu . au
* */
BOOL next_token ( const char * * ptr , char * buff , const char * sep , size_t bufsize )
{
const char * s ;
BOOL quoted ;
size_t len = 1 ;
if ( ! ptr )
return ( False ) ;
s = * ptr ;
/* default to simple separators */
if ( ! sep )
sep = " \t \n \r " ;
/* find the first non sep char */
while ( * s & & strchr_m ( sep , * s ) )
s + + ;
/* nothing left? */
if ( ! * s )
return ( False ) ;
/* copy over the token */
for ( quoted = False ; len < bufsize & & * s & & ( quoted | | ! strchr_m ( sep , * s ) ) ; s + + ) {
if ( * s = = ' \" ' ) {
quoted = ! quoted ;
} else {
len + + ;
* buff + + = * s ;
}
}
* ptr = ( * s ) ? s + 1 : s ;
* buff = 0 ;
return ( True ) ;
}
/**
2004-10-08 12:13:00 +04:00
Case insensitive string compararison
2003-08-13 05:53:07 +04:00
* */
2004-10-08 12:13:00 +04:00
int StrCaseCmp ( const char * s1 , const char * s2 )
2003-08-13 05:53:07 +04:00
{
2004-10-08 12:13:00 +04:00
codepoint_t c1 = 0 , c2 = 0 ;
size_t size1 , size2 ;
2004-09-20 11:21:26 +04:00
2004-10-08 12:13:00 +04:00
while ( * s1 & & * s2 ) {
c1 = next_codepoint ( s1 , & size1 ) ;
c2 = next_codepoint ( s2 , & size2 ) ;
2004-09-20 11:21:26 +04:00
2004-10-08 12:13:00 +04:00
s1 + = size1 ;
s2 + = size2 ;
2004-09-20 11:21:26 +04:00
2004-10-08 12:13:00 +04:00
if ( c1 = = c2 ) {
continue ;
}
2003-08-13 05:53:07 +04:00
2004-10-08 12:13:00 +04:00
if ( c1 = = INVALID_CODEPOINT | |
c2 = = INVALID_CODEPOINT ) {
/* what else can we do?? */
return c1 - c2 ;
2004-09-20 11:21:26 +04:00
}
2004-10-08 12:13:00 +04:00
if ( toupper_w ( c1 ) ! = toupper_w ( c2 ) ) {
return c1 - c2 ;
}
2004-09-20 11:21:26 +04:00
}
2004-10-08 12:13:00 +04:00
return * s1 - * s2 ;
2003-08-13 05:53:07 +04:00
}
/**
* Compare 2 strings .
*
* @ note The comparison is case - insensitive .
* */
BOOL strequal ( const char * s1 , const char * s2 )
{
if ( s1 = = s2 )
return ( True ) ;
if ( ! s1 | | ! s2 )
return ( False ) ;
2004-10-08 12:13:00 +04:00
return StrCaseCmp ( s1 , s2 ) = = 0 ;
2003-08-13 05:53:07 +04:00
}
/**
Compare 2 strings ( case sensitive ) .
* */
BOOL strcsequal ( const char * s1 , const char * s2 )
{
2004-10-08 12:13:00 +04:00
if ( s1 = = s2 )
return ( True ) ;
if ( ! s1 | | ! s2 )
return ( False ) ;
return strcmp ( s1 , s2 ) = = 0 ;
2003-08-13 05:53:07 +04:00
}
2004-10-08 12:13:00 +04:00
2003-08-13 05:53:07 +04:00
/**
Do a case - insensitive , whitespace - ignoring string compare .
* */
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 ( * psz1 ) ! = toupper ( * psz2 ) | | * psz1 = = ' \0 '
| | * psz2 = = ' \0 ' )
break ;
psz1 + + ;
psz2 + + ;
}
return ( * psz1 - * psz2 ) ;
}
/**
String replace .
NOTE : oldc and newc must be 7 bit characters
* */
2004-10-08 12:13:00 +04:00
void string_replace ( char * s , char oldc , char newc )
2003-08-13 05:53:07 +04:00
{
2004-10-08 12:13:00 +04:00
while ( * s ) {
size_t size ;
codepoint_t c = next_codepoint ( s , & size ) ;
if ( c = = oldc ) {
* s = newc ;
}
s + = size ;
2003-08-13 05:53:07 +04:00
}
}
/**
Trim the specified elements off the front and back of a string .
* */
BOOL trim_string ( char * s , const char * front , const char * back )
{
BOOL ret = False ;
size_t front_len ;
size_t back_len ;
size_t len ;
/* Ignore null or empty strings. */
if ( ! s | | ( s [ 0 ] = = ' \0 ' ) )
return False ;
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 ;
ret = True ;
}
}
if ( back_len ) {
while ( ( len > = back_len ) & & strncmp ( s + len - back_len , back , back_len ) = = 0 ) {
s [ len - back_len ] = ' \0 ' ;
len - = back_len ;
ret = True ;
}
}
return ret ;
}
/**
Find the number of ' c ' chars in a string
* */
2004-10-08 12:13:00 +04:00
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 ) {
size_t size ;
codepoint_t c2 = next_codepoint ( s , & size ) ;
if ( c2 = = c ) count + + ;
s + = size ;
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
}
/**
Safe string copy into a known length string . maxlength does not
include the terminating zero .
* */
char * safe_strcpy ( char * dest , const char * src , size_t maxlength )
{
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 " ,
2004-06-01 12:12:45 +04:00
( uint_t ) ( len - maxlength ) , len , 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 .
* */
char * safe_strcat ( char * dest , const char * src , size_t maxlength )
{
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 ;
}
/**
Paranoid strcpy into a buffer of given length ( includes terminating
zero . Strips out all but ' a - Z0 - 9 ' and the character in other_safe_chars
and replaces with ' _ ' . Deliberately does * NOT * check for multibyte
characters . Don ' t change it !
* */
char * alpha_strcpy ( char * dest , const char * src , const char * other_safe_chars , size_t maxlength )
{
size_t len , i ;
if ( maxlength = = 0 ) {
/* can't fit any bytes at all! */
return NULL ;
}
if ( ! dest ) {
DEBUG ( 0 , ( " ERROR: NULL dest in alpha_strcpy \n " ) ) ;
return NULL ;
}
if ( ! src ) {
* dest = 0 ;
return dest ;
}
len = strlen ( src ) ;
if ( len > = maxlength )
len = maxlength - 1 ;
if ( ! other_safe_chars )
other_safe_chars = " " ;
for ( i = 0 ; i < len ; i + + ) {
int val = ( src [ i ] & 0xff ) ;
if ( isupper ( val ) | | islower ( val ) | | isdigit ( val ) | | strchr_m ( other_safe_chars , val ) )
dest [ i ] = src [ i ] ;
else
dest [ i ] = ' _ ' ;
}
dest [ i ] = ' \0 ' ;
return dest ;
}
/**
Like strncpy but always null terminates . Make sure there is room !
The variable n should always be one less than the available size .
* */
char * StrnCpy ( char * dest , const char * src , size_t n )
{
char * d = dest ;
if ( ! dest )
return ( NULL ) ;
if ( ! src ) {
* dest = 0 ;
return ( dest ) ;
}
while ( n - - & & ( * d + + = * src + + ) )
;
* d = 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 "
* */
size_t strhex_to_str ( char * p , size_t len , const char * strhex )
{
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 ;
}
if ( ! ( p1 = strchr_m ( hexchars , toupper ( strhex [ i ] ) ) ) )
break ;
i + + ; /* next hex digit */
if ( ! ( p2 = strchr_m ( hexchars , toupper ( strhex [ i ] ) ) ) )
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 ;
}
DATA_BLOB strhex_to_data_blob ( const char * strhex )
{
DATA_BLOB ret_blob = data_blob ( NULL , strlen ( strhex ) / 2 + 1 ) ;
ret_blob . length = strhex_to_str ( ret_blob . data ,
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 .
*/
void hex_encode ( const unsigned char * buff_in , size_t len , char * * out_hex_buffer )
{
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 ] ) ;
}
2003-08-13 05:53:07 +04:00
/**
Check if a string is part of a list .
* */
BOOL in_list ( const char * s , const char * list , BOOL casesensitive )
{
pstring tok ;
const char * p = list ;
if ( ! list )
return ( False ) ;
while ( next_token ( & p , tok , LIST_SEP , sizeof ( tok ) ) ) {
if ( casesensitive ) {
if ( strcmp ( tok , s ) = = 0 )
return ( True ) ;
} else {
if ( StrCaseCmp ( tok , s ) = = 0 )
return ( True ) ;
}
}
return ( False ) ;
}
/**
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 .
* */
void string_free ( char * * s )
{
if ( s ) SAFE_FREE ( * s ) ;
}
/**
Set a string value , deallocating any existing space , and allocing the space
for the string
* */
BOOL string_set ( char * * dest , const char * src )
{
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 .
* */
void string_sub ( char * s , const char * pattern , const char * insert , size_t len )
{
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 .
* */
void all_string_sub ( char * s , const char * pattern , const char * insert , size_t len )
{
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 ) ;
}
}
/**
2004-10-08 12:13:00 +04:00
Strchr and strrchr_m are a bit complex on general multi - byte strings .
2003-08-13 05:53:07 +04:00
* */
char * strchr_m ( const char * s , char c )
{
2004-09-24 05:21:21 +04:00
/* characters below 0x3F are guaranteed to not appear in
non - initial position in multi - byte charsets */
if ( ( c & 0xC0 ) = = 0 ) {
return strchr ( s , c ) ;
}
2004-10-08 12:13:00 +04:00
while ( * s ) {
size_t size ;
codepoint_t c2 = next_codepoint ( s , & size ) ;
if ( c2 = = c ) {
return discard_const ( s ) ;
}
s + = size ;
}
return NULL ;
2003-08-13 05:53:07 +04:00
}
char * strrchr_m ( const char * s , char c )
{
2004-10-08 12:13:00 +04:00
char * ret = NULL ;
2003-08-13 05:53:07 +04:00
2004-09-24 05:21:21 +04:00
/* characters below 0x3F are guaranteed to not appear in
non - initial position in multi - byte charsets */
if ( ( c & 0xC0 ) = = 0 ) {
return strrchr ( s , c ) ;
}
2004-10-08 12:13:00 +04:00
while ( * s ) {
size_t size ;
codepoint_t c2 = next_codepoint ( s , & size ) ;
if ( c2 = = c ) {
ret = discard_const ( s ) ;
}
s + = size ;
}
return ret ;
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
/**
Convert a string to lower case , allocated with talloc
* */
char * strlower_talloc ( TALLOC_CTX * ctx , const char * src )
{
2004-10-08 12:13:00 +04:00
size_t size = 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
char * dest ;
2004-10-08 12:13:00 +04:00
/* this takes advantage of the fact that upper/lower can't
change the length of a character by more than 1 byte */
dest = talloc ( ctx , 2 * ( strlen ( src ) ) + 1 ) ;
if ( dest = = NULL ) {
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
return NULL ;
}
2004-10-08 12:13:00 +04:00
while ( * src ) {
size_t c_size ;
codepoint_t c = next_codepoint ( src , & c_size ) ;
src + = c_size ;
c = tolower_w ( c ) ;
c_size = push_codepoint ( dest + size , c ) ;
if ( c_size = = - 1 ) {
talloc_free ( dest ) ;
return NULL ;
}
size + = c_size ;
}
dest [ size ] = 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
return dest ;
}
/**
Convert a string to UPPER case , allocated with talloc
* */
char * strupper_talloc ( TALLOC_CTX * ctx , const char * src )
{
2004-10-08 12:13:00 +04:00
size_t size = 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
char * dest ;
2004-10-08 12:13:00 +04:00
/* this takes advantage of the fact that upper/lower can't
change the length of a character by more than 1 byte */
dest = talloc ( ctx , 2 * ( strlen ( src ) ) + 1 ) ;
if ( dest = = NULL ) {
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
return NULL ;
}
2004-10-08 12:13:00 +04:00
while ( * src ) {
size_t c_size ;
codepoint_t c = next_codepoint ( src , & c_size ) ;
src + = c_size ;
c = toupper_w ( c ) ;
c_size = push_codepoint ( dest + size , c ) ;
if ( c_size = = - 1 ) {
talloc_free ( dest ) ;
return NULL ;
}
size + = c_size ;
}
dest [ size ] = 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
return dest ;
}
2003-08-13 05:53:07 +04:00
/**
Convert a string to lower case .
* */
void strlower_m ( char * s )
{
2004-10-08 12:13:00 +04:00
char * d ;
2003-08-13 05:53:07 +04:00
/* this is quite a common operation, so we want it to be
fast . We optimise for the ascii case , knowing that all our
supported multi - byte character sets are ascii - compatible
( ie . they match for the first 128 chars ) */
2004-05-29 12:11:46 +04:00
while ( * s & & ! ( ( ( uint8_t ) s [ 0 ] ) & 0x7F ) ) {
* s = tolower ( ( uint8_t ) * s ) ;
2003-08-13 05:53:07 +04:00
s + + ;
}
if ( ! * s )
return ;
2004-10-08 12:13:00 +04:00
d = s ;
while ( * s ) {
size_t c_size , c_size2 ;
codepoint_t c = next_codepoint ( s , & c_size ) ;
c_size2 = push_codepoint ( d , tolower_w ( c ) ) ;
if ( c_size2 > c_size ) {
2004-10-12 10:12:24 +04:00
DEBUG ( 0 , ( " FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m \n " ,
c , tolower_w ( c ) , c_size , c_size2 ) ) ;
2004-10-08 12:13:00 +04:00
smb_panic ( " codepoint expansion in strlower_m \n " ) ;
}
s + = c_size ;
d + = c_size2 ;
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
* d = 0 ;
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
Convert a string to UPPER case .
2003-08-13 05:53:07 +04:00
* */
void strupper_m ( char * s )
{
2004-10-08 12:13:00 +04:00
char * d ;
2003-08-13 05:53:07 +04:00
/* this is quite a common operation, so we want it to be
fast . We optimise for the ascii case , knowing that all our
supported multi - byte character sets are ascii - compatible
( ie . they match for the first 128 chars ) */
2004-05-29 12:11:46 +04:00
while ( * s & & ! ( ( ( uint8_t ) s [ 0 ] ) & 0x7F ) ) {
* s = toupper ( ( uint8_t ) * s ) ;
2003-08-13 05:53:07 +04:00
s + + ;
}
if ( ! * s )
return ;
2004-10-08 12:13:00 +04:00
d = s ;
while ( * s ) {
size_t c_size , c_size2 ;
codepoint_t c = next_codepoint ( s , & c_size ) ;
c_size2 = push_codepoint ( d , toupper_w ( c ) ) ;
if ( c_size2 > c_size ) {
2004-10-12 10:12:24 +04:00
DEBUG ( 0 , ( " FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m \n " ,
c , toupper_w ( c ) , c_size , c_size2 ) ) ;
2004-10-08 12:13:00 +04:00
smb_panic ( " codepoint expansion in strupper_m \n " ) ;
}
s + = c_size ;
d + = c_size2 ;
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
* d = 0 ;
2003-08-13 05:53:07 +04:00
}
2003-11-15 10:51:19 +03: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
Count the number of UCS2 characters in a string . Normally this will
be the same as the number of bytes in a string for single byte strings ,
but will be different for multibyte .
2003-11-15 10:51:19 +03:00
* */
size_t strlen_m ( const char * s )
{
size_t count = 0 ;
2003-11-20 13:29:54 +03:00
if ( ! s ) {
return 0 ;
}
2004-05-29 12:11:46 +04:00
while ( * s & & ! ( ( ( uint8_t ) s [ 0 ] ) & 0x7F ) ) {
2003-11-15 10:51:19 +03:00
s + + ;
count + + ;
}
2003-11-20 13:29:54 +03:00
if ( ! * s ) {
return count ;
}
2003-11-15 10:51:19 +03:00
2004-10-08 12:13:00 +04:00
while ( * s ) {
size_t c_size ;
codepoint_t c = next_codepoint ( s , & c_size ) ;
if ( c < 0x10000 ) {
count + = 1 ;
} else {
count + = 2 ;
}
s + = c_size ;
}
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-11-15 10:51:19 +03:00
}
2003-11-23 13:50:52 +03:00
/**
Work out the number of multibyte chars in a string , including the NULL
terminator .
* */
size_t strlen_m_term ( const char * s )
{
if ( ! s ) {
return 0 ;
}
return strlen_m ( s ) + 1 ;
}
2003-08-13 05:53:07 +04:00
/**
Return a RFC2254 binary string representation of a buffer .
Used in LDAP filters .
Caller must free .
* */
char * binary_string ( char * buf , int len )
{
char * s ;
int i , j ;
const char * hex = " 0123456789ABCDEF " ;
s = malloc ( len * 3 + 1 ) ;
if ( ! s )
return NULL ;
for ( j = i = 0 ; i < len ; i + + ) {
s [ j ] = ' \\ ' ;
2004-05-29 12:11:46 +04:00
s [ j + 1 ] = hex [ ( ( uint8_t ) buf [ i ] ) > > 4 ] ;
s [ j + 2 ] = hex [ ( ( uint8_t ) buf [ i ] ) & 0xF ] ;
2003-08-13 05:53:07 +04:00
j + = 3 ;
}
s [ j ] = 0 ;
return s ;
}
/**
Unescape a URL encoded string , in place .
* */
void rfc1738_unescape ( char * buf )
{
char * p = buf ;
while ( ( p = strchr_m ( p , ' + ' ) ) )
* p = ' ' ;
p = buf ;
while ( p & & * p & & ( p = strchr_m ( p , ' % ' ) ) ) {
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 + + ;
}
}
/**
* Decode a base64 string into a DATA_BLOB - simple and slow algorithm
* */
DATA_BLOB base64_decode_data_blob ( const char * s )
{
2004-10-09 11:11:21 +04:00
const char * b64 = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ " ;
2003-08-13 05:53:07 +04:00
int bit_offset , byte_offset , idx , i , n ;
DATA_BLOB decoded = data_blob ( s , strlen ( s ) + 1 ) ;
2004-05-29 12:11:46 +04:00
uint8_t * d = decoded . data ;
2003-08-13 05:53:07 +04:00
char * p ;
n = i = 0 ;
while ( * s & & ( p = strchr_m ( b64 , * s ) ) ) {
idx = ( int ) ( p - b64 ) ;
byte_offset = ( i * 6 ) / 8 ;
bit_offset = ( i * 6 ) % 8 ;
d [ byte_offset ] & = ~ ( ( 1 < < ( 8 - bit_offset ) ) - 1 ) ;
if ( bit_offset < 3 ) {
d [ byte_offset ] | = ( idx < < ( 2 - bit_offset ) ) ;
n = byte_offset + 1 ;
} else {
d [ byte_offset ] | = ( idx > > ( bit_offset - 2 ) ) ;
d [ byte_offset + 1 ] = 0 ;
d [ byte_offset + 1 ] | = ( idx < < ( 8 - ( bit_offset - 2 ) ) ) & 0xFF ;
n = byte_offset + 2 ;
}
s + + ; i + + ;
}
/* fix up length */
decoded . length = n ;
return decoded ;
}
/**
* Decode a base64 string in - place - wrapper for the above
* */
void base64_decode_inplace ( char * s )
{
DATA_BLOB decoded = base64_decode_data_blob ( s ) ;
memcpy ( s , decoded . data , decoded . length ) ;
data_blob_free ( & decoded ) ;
/* null terminate */
s [ decoded . length ] = ' \0 ' ;
}
/**
* Encode a base64 string into a malloc ( ) ed string caller to free .
*
* From SQUID : adopted from http : //ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
* */
char * base64_encode_data_blob ( DATA_BLOB data )
{
2004-10-09 11:11:21 +04:00
const char * b64 = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ " ;
2003-08-13 05:53:07 +04:00
int bits = 0 ;
int char_count = 0 ;
size_t out_cnt = 0 ;
size_t len = data . length ;
size_t output_len = data . length * 2 ;
char * result = malloc ( output_len ) ; /* get us plenty of space */
while ( len - - & & out_cnt < ( data . length * 2 ) - 5 ) {
2004-05-29 12:11:46 +04:00
int c = ( uint8_t ) * ( data . data + + ) ;
2003-08-13 05:53:07 +04:00
bits + = c ;
char_count + + ;
if ( char_count = = 3 ) {
result [ out_cnt + + ] = b64 [ bits > > 18 ] ;
result [ out_cnt + + ] = b64 [ ( bits > > 12 ) & 0x3f ] ;
result [ out_cnt + + ] = b64 [ ( bits > > 6 ) & 0x3f ] ;
result [ out_cnt + + ] = b64 [ bits & 0x3f ] ;
bits = 0 ;
char_count = 0 ;
} else {
bits < < = 8 ;
}
}
if ( char_count ! = 0 ) {
bits < < = 16 - ( 8 * char_count ) ;
result [ out_cnt + + ] = b64 [ bits > > 18 ] ;
result [ out_cnt + + ] = b64 [ ( bits > > 12 ) & 0x3f ] ;
if ( char_count = = 1 ) {
result [ out_cnt + + ] = ' = ' ;
result [ out_cnt + + ] = ' = ' ;
} else {
result [ out_cnt + + ] = b64 [ ( bits > > 6 ) & 0x3f ] ;
result [ out_cnt + + ] = ' = ' ;
}
}
result [ out_cnt ] = ' \0 ' ; /* terminate */
return result ;
}
# 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
/*
format a string into length - prefixed dotted domain format , as used in NBT
and in some ADS structures
*/
const char * str_format_nbt_domain ( TALLOC_CTX * mem_ctx , const char * s )
{
char * ret ;
int i ;
if ( ! s | | ! * s ) {
return talloc_strdup ( mem_ctx , " " ) ;
}
ret = talloc ( mem_ctx , strlen ( s ) + 2 ) ;
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
BOOL add_string_to_array ( TALLOC_CTX * mem_ctx ,
const char * str , const char * * * strings , int * num )
{
char * dup_str = talloc_strdup ( mem_ctx , str ) ;
2004-09-27 05:36:19 +04:00
* strings = talloc_realloc_p ( mem_ctx ,
* 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
/*
varient of strcmp ( ) that handles NULL ptrs
*/
int strcmp_safe ( const char * s1 , const char * s2 )
{
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
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
size_t ascii_len_n ( const char * src , size_t n )
{
size_t len ;
len = strnlen ( src , n ) ;
if ( len + 1 < = n ) {
len + = 1 ;
}
return len ;
}
2004-09-20 11:21:26 +04:00
/*******************************************************************
Return a string representing a CIFS attribute for a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * attrib_string ( TALLOC_CTX * mem_ctx , uint32_t attrib )
{
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 } ,
{ ' 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 ;
ret = talloc ( mem_ctx , ARRAY_SIZE ( attr_strs ) + 1 ) ;
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 ;
}