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-05-13 23:14:12 +04:00
# include "system/locale.h"
2008-10-19 12:45:02 +04:00
# undef strncasecmp
# undef strcasemp
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 .
* */
2006-03-06 03:24:51 +03:00
/**
* Parse a string containing a boolean value .
*
* val will be set to the read value .
*
2007-08-27 21:21:16 +04:00
* @ retval true if a boolean value was parsed , false otherwise .
2006-03-06 03:24:51 +03:00
*/
2007-08-27 21:21:16 +04: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 ' ) {
2007-08-27 21:21:16 +04:00
return false ;
2006-01-31 09:09:18 +03:00
}
lval = strtol ( str , & end , 10 /* base */ ) ;
if ( end = = NULL | | * end ! = ' \0 ' | | end = = str ) {
return set_boolean ( str , val ) ;
}
2007-08-27 21:21:16 +04:00
* val = ( lval ) ? true : false ;
return true ;
2006-01-31 09:09:18 +03:00
}
2006-02-28 16:12:39 +03:00
/**
* Convert a size specification like 16 K into an integral number of bytes .
* */
2011-04-30 07:10:18 +04:00
_PUBLIC_ bool conv_str_size_error ( 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 ' ) {
2007-08-27 21:21:16 +04:00
return false ;
2006-01-31 09:09:18 +03:00
}
lval = strtoull ( str , & end , 10 /* base */ ) ;
if ( end = = NULL | | end = = str ) {
2007-08-27 21:21:16 +04:00
return false ;
2006-01-31 09:09:18 +03:00
}
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 {
2007-08-27 21:21:16 +04:00
return false ;
2006-01-31 09:09:18 +03:00
}
}
* val = ( uint64_t ) lval ;
2007-08-27 21:21:16 +04:00
return true ;
2006-01-31 09:09:18 +03:00
}
2006-03-06 03:24:51 +03:00
/**
* Parse a uint64_t value from a string
*
* val will be set to the value read .
*
2007-08-27 21:21:16 +04:00
* @ retval true if parsing was successful , false otherwise
2006-03-06 03:24:51 +03:00
*/
2007-08-27 21:21:16 +04: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 ' ) {
2007-08-27 21:21:16 +04:00
return false ;
2006-01-31 09:09:18 +03:00
}
lval = strtoull ( str , & end , 10 /* base */ ) ;
if ( end = = NULL | | * end ! = ' \0 ' | | end = = str ) {
2007-08-27 21:21:16 +04:00
return false ;
2006-01-31 09:09:18 +03:00
}
* val = ( uint64_t ) lval ;
2007-08-27 21:21:16 +04:00
return true ;
2006-01-31 09:09:18 +03:00
}
2006-04-27 20:05:05 +04:00
/**
* Compare 2 strings .
*
* @ note The comparison is case - insensitive .
* */
2007-08-27 21:21:16 +04:00
_PUBLIC_ bool strequal ( const char * s1 , const char * s2 )
2006-04-27 20:05:05 +04:00
{
if ( s1 = = s2 )
2007-08-27 21:21:16 +04:00
return true ;
2006-04-27 20:05:05 +04:00
if ( ! s1 | | ! s2 )
2007-08-27 21:21:16 +04:00
return false ;
2006-04-27 20:05:05 +04:00
2011-05-03 06:59:36 +04:00
return strcasecmp_m ( s1 , s2 ) = = 0 ;
2006-04-27 20:05:05 +04:00
}
2008-10-19 14:38:16 +04:00
2014-09-19 07:30:26 +04:00
/**
* @ file
* @ brief String utilities .
* */
static bool next_token_internal_talloc ( TALLOC_CTX * ctx ,
const char * * ptr ,
char * * pp_buff ,
const char * sep ,
bool ltrim )
{
const char * s ;
const char * saved_s ;
char * pbuf ;
bool quoted ;
size_t len = 1 ;
* pp_buff = NULL ;
if ( ! ptr ) {
return ( false ) ;
}
s = * ptr ;
/* default to simple separators */
if ( ! sep ) {
sep = " \t \n \r " ;
}
/* find the first non sep char, if left-trimming is requested */
if ( ltrim ) {
while ( * s & & strchr_m ( sep , * s ) ) {
s + + ;
}
}
/* nothing left? */
if ( ! * s ) {
return false ;
}
/* When restarting we need to go from here. */
saved_s = s ;
/* Work out the length needed. */
for ( quoted = false ; * s & &
( quoted | | ! strchr_m ( sep , * s ) ) ; s + + ) {
if ( * s = = ' \" ' ) {
quoted = ! quoted ;
} else {
len + + ;
}
}
/* We started with len = 1 so we have space for the nul. */
* pp_buff = talloc_array ( ctx , char , len ) ;
if ( ! * pp_buff ) {
return false ;
}
/* copy over the token */
pbuf = * pp_buff ;
s = saved_s ;
for ( quoted = false ; * s & &
( quoted | | ! strchr_m ( sep , * s ) ) ; s + + ) {
if ( * s = = ' \" ' ) {
quoted = ! quoted ;
} else {
* pbuf + + = * s ;
}
}
* ptr = ( * s ) ? s + 1 : s ;
* pbuf = 0 ;
return true ;
}
bool next_token_talloc ( TALLOC_CTX * ctx ,
const char * * ptr ,
char * * pp_buff ,
const char * sep )
{
return next_token_internal_talloc ( ctx , ptr , pp_buff , sep , true ) ;
}
/*
* Get the next token from a string , return false if none found . Handles
* double - quotes . This version does not trim leading separator characters
* before looking for a token .
*/
bool next_token_no_ltrim_talloc ( TALLOC_CTX * ctx ,
const char * * ptr ,
char * * pp_buff ,
const char * sep )
{
return next_token_internal_talloc ( ctx , ptr , pp_buff , sep , false ) ;
}
/**
* 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
* */
_PUBLIC_ 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 ;
}
2014-09-19 07:42:32 +04: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 .
* */
_PUBLIC_ bool set_boolean ( const char * boolean_string , bool * boolean )
{
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 ;
}
/**
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 ;
}
2016-04-01 11:09:45 +03:00
_PUBLIC_ int memcmp_const_time ( const void * s1 , const void * s2 , size_t n )
{
const uint8_t * p1 = s1 , * p2 = s2 ;
size_t i , sum = 0 ;
for ( i = 0 ; i < n ; i + + ) {
sum | = ( p1 [ i ] ^ p2 [ i ] ) ;
}
return sum ! = 0 ;
}