1998-11-05 16:48:35 +00:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
1998-11-05 16:48:35 +00:00
Samba utility functions
2001-07-04 07:15:53 +00:00
Copyright ( C ) Andrew Tridgell 1992 - 2001
2001-11-18 16:12:11 +00:00
Copyright ( C ) Simo Sorce 2001
2005-07-26 00:10:45 +00:00
Copyright ( C ) Jeremy Allison 2005
1998-11-05 16:48:35 +00: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-09 19:25:36 +00:00
the Free Software Foundation ; either version 3 of the License , or
1998-11-05 16:48:35 +00: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 00:52:41 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1998-11-05 16:48:35 +00:00
*/
# include "includes.h"
1999-12-13 13:27:58 +00:00
# ifndef MAXUNI
# define MAXUNI 1024
# endif
1999-02-10 22:30:47 +00:00
2001-10-03 12:18:20 +00:00
/* these 3 tables define the unicode case handling. They are loaded
at startup either via mmap ( ) or read ( ) from the lib directory */
static smb_ucs2_t * upcase_table ;
static smb_ucs2_t * lowcase_table ;
static uint8 * valid_table ;
2007-10-18 17:40:25 -07:00
static bool upcase_table_use_unmap ;
static bool lowcase_table_use_unmap ;
static bool valid_table_use_unmap ;
2008-08-12 13:35:15 -07:00
static bool initialized ;
2001-10-03 12:18:20 +00:00
2006-04-08 17:25:31 +00:00
/**
* Destroy global objects allocated by load_case_tables ( )
* */
void gfree_case_tables ( void )
{
if ( upcase_table ) {
if ( upcase_table_use_unmap )
unmap_file ( upcase_table , 0x20000 ) ;
else
SAFE_FREE ( upcase_table ) ;
}
if ( lowcase_table ) {
if ( lowcase_table_use_unmap )
unmap_file ( lowcase_table , 0x20000 ) ;
else
SAFE_FREE ( lowcase_table ) ;
}
if ( valid_table ) {
if ( valid_table_use_unmap )
unmap_file ( valid_table , 0x10000 ) ;
else
SAFE_FREE ( valid_table ) ;
}
2008-08-12 13:35:15 -07:00
initialized = false ;
2006-04-08 17:25:31 +00:00
}
2003-04-04 08:16:14 +00:00
/**
* Load or generate the case handling tables .
*
* The case tables are defined in UCS2 and don ' t depend on any
* configured parameters , so they never need to be reloaded .
* */
2005-07-26 00:10:45 +00:00
2001-10-03 12:18:20 +00:00
void load_case_tables ( void )
{
2005-12-27 20:52:36 +00:00
char * old_locale = NULL , * saved_locale = NULL ;
2001-10-03 12:18:20 +00:00
int i ;
2007-11-15 14:19:52 -08:00
TALLOC_CTX * frame = NULL ;
2001-10-03 12:18:20 +00:00
2008-08-12 13:35:15 -07:00
if ( initialized ) {
2005-07-26 00:10:45 +00:00
return ;
}
2008-08-12 13:35:15 -07:00
initialized = true ;
2001-10-03 12:18:20 +00:00
2007-11-15 14:19:52 -08:00
frame = talloc_stackframe ( ) ;
2007-11-01 15:53:44 -04:00
upcase_table = ( smb_ucs2_t * ) map_file ( data_path ( " upcase.dat " ) ,
2006-07-30 16:36:56 +00:00
0x20000 ) ;
2006-04-08 17:25:31 +00:00
upcase_table_use_unmap = ( upcase_table ! = NULL ) ;
2007-11-01 15:53:44 -04:00
lowcase_table = ( smb_ucs2_t * ) map_file ( data_path ( " lowcase.dat " ) ,
2006-07-30 16:36:56 +00:00
0x20000 ) ;
2006-04-08 17:25:31 +00:00
lowcase_table_use_unmap = ( lowcase_table ! = NULL ) ;
2001-10-03 12:18:20 +00:00
2005-12-27 20:52:36 +00:00
# ifdef HAVE_SETLOCALE
/* Get the name of the current locale. */
old_locale = setlocale ( LC_ALL , NULL ) ;
2006-06-20 18:14:33 +00:00
if ( old_locale ) {
/* Save it as it is in static storage. */
saved_locale = SMB_STRDUP ( old_locale ) ;
}
2005-12-27 20:52:36 +00:00
/* We set back the locale to C to get ASCII-compatible toupper/lower functions. */
setlocale ( LC_ALL , " C " ) ;
# endif
2001-10-03 12:18:20 +00:00
/* we would like Samba to limp along even if these tables are
not available */
if ( ! upcase_table ) {
DEBUG ( 1 , ( " creating lame upcase table \n " ) ) ;
2006-07-30 16:36:56 +00:00
upcase_table = ( smb_ucs2_t * ) SMB_MALLOC ( 0x20000 ) ;
2002-03-06 20:38:51 +00:00
for ( i = 0 ; i < 0x10000 ; i + + ) {
smb_ucs2_t v ;
SSVAL ( & v , 0 , i ) ;
upcase_table [ v ] = i ;
}
for ( i = 0 ; i < 256 ; i + + ) {
smb_ucs2_t v ;
SSVAL ( & v , 0 , UCS2_CHAR ( i ) ) ;
upcase_table [ v ] = UCS2_CHAR ( islower ( i ) ? toupper ( i ) : i ) ;
}
2001-10-03 12:18:20 +00:00
}
if ( ! lowcase_table ) {
DEBUG ( 1 , ( " creating lame lowcase table \n " ) ) ;
2006-07-30 16:36:56 +00:00
lowcase_table = ( smb_ucs2_t * ) SMB_MALLOC ( 0x20000 ) ;
2002-03-06 20:38:51 +00:00
for ( i = 0 ; i < 0x10000 ; i + + ) {
smb_ucs2_t v ;
SSVAL ( & v , 0 , i ) ;
lowcase_table [ v ] = i ;
}
for ( i = 0 ; i < 256 ; i + + ) {
smb_ucs2_t v ;
SSVAL ( & v , 0 , UCS2_CHAR ( i ) ) ;
lowcase_table [ v ] = UCS2_CHAR ( isupper ( i ) ? tolower ( i ) : i ) ;
}
2001-10-03 12:18:20 +00:00
}
2005-12-27 20:52:36 +00:00
# ifdef HAVE_SETLOCALE
/* Restore the old locale. */
2006-06-20 18:14:33 +00:00
if ( saved_locale ) {
setlocale ( LC_ALL , saved_locale ) ;
SAFE_FREE ( saved_locale ) ;
}
2005-12-27 20:52:36 +00:00
# endif
2007-11-15 14:19:52 -08:00
TALLOC_FREE ( frame ) ;
2001-12-20 06:18:52 +00:00
}
2003-04-04 08:16:14 +00:00
static int check_dos_char_slowly ( smb_ucs2_t c )
2001-12-20 06:18:52 +00:00
{
char buf [ 10 ] ;
smb_ucs2_t c2 = 0 ;
int len1 , len2 ;
2005-07-26 00:10:45 +00:00
2006-09-21 18:37:09 +00:00
len1 = convert_string ( CH_UTF16LE , CH_DOS , & c , 2 , buf , sizeof ( buf ) , False ) ;
2005-07-26 00:10:45 +00:00
if ( len1 = = 0 ) {
return 0 ;
}
2006-09-21 18:37:09 +00:00
len2 = convert_string ( CH_DOS , CH_UTF16LE , buf , len1 , & c2 , 2 , False ) ;
2005-07-26 00:10:45 +00:00
if ( len2 ! = 2 ) {
return 0 ;
}
2005-04-07 03:24:02 +00:00
return ( c = = c2 ) ;
2001-12-20 06:18:52 +00:00
}
2003-02-24 03:09:08 +00:00
/**
* Load the valid character map table from < tt > valid . dat < / tt > or
* create from the configured codepage .
*
* This function is called whenever the configuration is reloaded .
* However , the valid character table is not changed if it ' s loaded
* from a file , because we can ' t unmap files .
* */
2005-07-26 00:10:45 +00:00
2001-12-20 06:18:52 +00:00
void init_valid_table ( void )
{
static int mapped_file ;
int i ;
const char * allowed = " .!#$%&'()_-@^`~ " ;
2003-02-27 05:20:23 +00:00
uint8 * valid_file ;
2001-10-03 12:18:20 +00:00
2003-02-27 05:20:23 +00:00
if ( mapped_file ) {
/* Can't unmap files, so stick with what we have */
return ;
}
2001-12-20 06:18:52 +00:00
2007-11-01 15:53:44 -04:00
valid_file = ( uint8 * ) map_file ( data_path ( " valid.dat " ) , 0x10000 ) ;
2003-02-27 05:20:23 +00:00
if ( valid_file ) {
valid_table = valid_file ;
2001-12-20 06:18:52 +00:00
mapped_file = 1 ;
2006-04-08 17:25:31 +00:00
valid_table_use_unmap = True ;
2001-12-20 06:18:52 +00:00
return ;
2001-10-03 12:18:20 +00:00
}
2001-12-20 06:18:52 +00:00
2003-02-27 05:20:23 +00:00
/* Otherwise, we're using a dynamically created valid_table.
* It might need to be regenerated if the code page changed .
* We know that we ' re not using a mapped file , so we can
* free ( ) the old one . */
2007-12-16 00:19:42 +01:00
SAFE_FREE ( valid_table ) ;
2006-04-08 17:25:31 +00:00
/* use free rather than unmap */
valid_table_use_unmap = False ;
2001-12-20 06:18:52 +00:00
DEBUG ( 2 , ( " creating default valid table \n " ) ) ;
2006-07-30 16:36:56 +00:00
valid_table = ( uint8 * ) SMB_MALLOC ( 0x10000 ) ;
2007-12-16 00:19:42 +01:00
SMB_ASSERT ( valid_table ! = NULL ) ;
2005-07-26 00:10:45 +00:00
for ( i = 0 ; i < 128 ; i + + ) {
2003-02-27 05:20:23 +00:00
valid_table [ i ] = isalnum ( i ) | | strchr ( allowed , i ) ;
2005-07-26 00:10:45 +00:00
}
2007-12-16 00:25:49 +01:00
lazy_initialize_conv ( ) ;
2001-12-20 10:02:30 +00:00
for ( ; i < 0x10000 ; i + + ) {
smb_ucs2_t c ;
SSVAL ( & c , 0 , i ) ;
2007-12-16 00:25:49 +01:00
valid_table [ i ] = check_dos_char_slowly ( c ) ;
2001-12-20 10:02:30 +00:00
}
2001-10-03 12:18:20 +00:00
}
1998-11-05 16:48:35 +00:00
/*******************************************************************
1999-12-13 13:27:58 +00:00
Write a string in ( little - endian ) unicode format . src is in
the current DOS codepage . len is the length in bytes of the
string pointed to by dst .
1999-10-25 19:03:27 +00:00
2000-03-27 12:38:45 +00:00
if null_terminate is True then null terminate the packet ( adds 2 bytes )
2000-06-22 01:39:17 +00:00
the return value is the length in bytes consumed by the string , including the
2000-03-27 12:38:45 +00:00
null termination if applied
1999-12-13 13:27:58 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-02-15 05:31:52 +00:00
2007-10-18 17:40:25 -07:00
size_t dos_PutUniCode ( char * dst , const char * src , size_t len , bool null_terminate )
1999-12-13 13:27:58 +00:00
{
2005-08-30 06:41:32 +00:00
int flags = null_terminate ? STR_UNICODE | STR_NOALIGN | STR_TERMINATE
: STR_UNICODE | STR_NOALIGN ;
return push_ucs2 ( NULL , dst , src , len , flags ) ;
1999-12-13 13:27:58 +00:00
}
1999-02-15 05:31:52 +00:00
2000-02-07 16:22:16 +00:00
1999-12-13 13:27:58 +00:00
/*******************************************************************
2000-04-22 00:33:16 +00:00
Skip past a unicode string , but not more than len . Always move
past a terminating zero if found .
1999-12-13 13:27:58 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-10-07 22:10:29 +00:00
2000-04-22 00:33:16 +00:00
char * skip_unibuf ( char * src , size_t len )
1999-12-13 13:27:58 +00:00
{
2005-07-26 00:10:45 +00:00
char * srcend = src + len ;
2000-04-22 00:33:16 +00:00
2005-07-26 00:10:45 +00:00
while ( src < srcend & & SVAL ( src , 0 ) ) {
src + = 2 ;
}
2000-04-22 00:33:16 +00:00
2005-07-26 00:10:45 +00:00
if ( ! SVAL ( src , 0 ) ) {
src + = 2 ;
}
2000-04-22 00:33:16 +00:00
2005-07-26 00:10:45 +00:00
return src ;
1998-11-05 16:48:35 +00:00
}
2001-07-04 07:15:53 +00:00
/* Copy a string from little-endian or big-endian unicode source (depending
* on flags ) to internal samba format destination
*/
2005-07-26 00:10:45 +00:00
2001-07-04 07:15:53 +00:00
int rpcstr_pull ( char * dest , void * src , int dest_len , int src_len , int flags )
1998-11-10 19:05:00 +00:00
{
2003-04-23 14:07:33 +00:00
if ( ! src ) {
dest [ 0 ] = 0 ;
return 0 ;
}
2005-07-26 00:10:45 +00:00
if ( dest_len = = - 1 ) {
dest_len = MAXUNI - 3 ;
}
2001-07-04 07:15:53 +00:00
return pull_ucs2 ( NULL , dest , src , dest_len , src_len , flags | STR_UNICODE | STR_NOALIGN ) ;
1998-11-10 19:05:00 +00:00
}
2007-11-20 15:31:37 -08:00
/* Copy a string from little-endian or big-endian unicode source (depending
* on flags ) to internal samba format destination . Allocates on talloc ctx .
*/
int rpcstr_pull_talloc ( TALLOC_CTX * ctx ,
char * * dest ,
void * src ,
int src_len ,
int flags )
{
return pull_ucs2_base_talloc ( ctx ,
NULL ,
dest ,
src ,
src_len ,
flags | STR_UNICODE | STR_NOALIGN ) ;
}
2001-07-20 01:32:56 +00:00
/* Copy a string from a unistr2 source to internal samba format
destination . Use this instead of direct calls to rpcstr_pull ( ) to avoid
having to determine whether the source string is null terminated . */
int rpcstr_pull_unistr2_fstring ( char * dest , UNISTR2 * src )
{
return pull_ucs2 ( NULL , dest , src - > buffer , sizeof ( fstring ) ,
src - > uni_str_len * 2 , 0 ) ;
}
2005-11-13 11:38:17 +00:00
/* Helper function to return a talloc'ed string. I have implemented it with a
* copy because I don ' t really know how pull_ucs2 and friends calculate the
* target size . If this turns out to be a major bottleneck someone with deeper
* multi - byte knowledge needs to revisit this .
2007-11-15 14:19:52 -08:00
* I just did ( JRA : - ) . No longer uses copy .
2005-11-13 11:38:17 +00:00
* My ( VL ) use is dsr_getdcname , which returns 6 strings , the alternative would
* have been to manually talloc_strdup them in rpc_client / cli_netlogon . c .
*/
2007-11-15 14:19:52 -08:00
char * rpcstr_pull_unistr2_talloc ( TALLOC_CTX * ctx , const UNISTR2 * src )
2005-11-13 11:38:17 +00:00
{
2007-11-15 14:19:52 -08:00
char * dest = NULL ;
2008-04-29 14:36:24 -07:00
size_t dest_len ;
if ( ! convert_string_talloc ( ctx , CH_UTF16LE , CH_UNIX , src - > buffer ,
src - > uni_str_len * 2 , ( void * ) & dest ,
& dest_len , true ) )
{
2006-02-03 22:19:41 +00:00
return NULL ;
2005-11-13 11:38:17 +00:00
}
2007-11-15 14:19:52 -08:00
/* Ensure we're returning a null terminated string. */
if ( dest_len ) {
/* Did we already process the terminating zero ? */
if ( dest [ dest_len - 1 ] ! = 0 ) {
size_t size = talloc_get_size ( dest ) ;
/* Have we got space to append the '\0' ? */
if ( size < = dest_len ) {
/* No, realloc. */
dest = TALLOC_REALLOC_ARRAY ( ctx , dest , char ,
dest_len + 1 ) ;
if ( ! dest ) {
/* talloc fail. */
dest_len = ( size_t ) - 1 ;
return NULL ;
}
}
/* Yay - space ! */
dest [ dest_len ] = ' \0 ' ;
dest_len + + ;
}
} else if ( dest ) {
dest [ 0 ] = 0 ;
}
return dest ;
2005-11-13 11:38:17 +00:00
}
2001-07-04 07:15:53 +00:00
/* Converts a string from internal samba format to unicode
2007-11-15 14:19:52 -08:00
*/
2005-07-26 00:10:45 +00:00
2007-11-10 22:31:34 -08:00
int rpcstr_push ( void * dest , const char * src , size_t dest_len , int flags )
2000-07-07 06:20:46 +00:00
{
2001-07-04 07:15:53 +00:00
return push_ucs2 ( NULL , dest , src , dest_len , flags | STR_UNICODE | STR_NOALIGN ) ;
1999-12-13 13:27:58 +00:00
}
1998-11-05 16:48:35 +00:00
2007-11-10 22:31:34 -08:00
/* Converts a string from internal samba format to unicode. Always terminates.
* Actually just a wrapper round push_ucs2_talloc ( ) .
2007-11-27 14:35:30 -08:00
*/
2007-11-10 22:31:34 -08:00
int rpcstr_push_talloc ( TALLOC_CTX * ctx , smb_ucs2_t * * dest , const char * src )
{
2008-04-29 14:36:24 -07:00
size_t size ;
if ( push_ucs2_talloc ( ctx , dest , src , & size ) )
return size ;
else
return - 1 ;
2007-11-10 22:31:34 -08:00
}
1999-12-22 00:17:35 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Convert a ( little - endian ) UNISTR2 structure to an ASCII string .
1999-12-22 00:17:35 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2001-07-04 07:15:53 +00:00
void unistr2_to_ascii ( char * dest , const UNISTR2 * str , size_t maxlen )
1999-12-22 00:17:35 +00:00
{
2007-09-21 10:23:35 +00:00
if ( ( str = = NULL ) | | ( str - > uni_str_len = = 0 ) ) {
2001-07-04 07:15:53 +00:00
* dest = ' \0 ' ;
return ;
1999-12-22 00:17:35 +00:00
}
2001-07-04 18:57:16 +00:00
pull_ucs2 ( NULL , dest , str - > buffer , maxlen , str - > uni_str_len * 2 , STR_NOALIGN ) ;
1999-12-22 00:17:35 +00:00
}
1999-12-22 18:46:05 +00:00
2007-11-27 14:35:30 -08:00
#if 0
2005-03-23 23:26:33 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Convert a ( little - endian ) UNISTR3 structure to an ASCII string .
2005-03-23 23:26:33 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2005-03-23 23:26:33 +00:00
void unistr3_to_ascii ( char * dest , const UNISTR3 * str , size_t maxlen )
{
2007-09-21 10:23:35 +00:00
if ( ( str = = NULL ) | | ( str - > uni_str_len = = 0 ) ) {
2005-03-23 23:26:33 +00:00
* dest = ' \0 ' ;
return ;
}
pull_ucs2 ( NULL , dest , str - > str . buffer , maxlen , str - > uni_str_len * 2 ,
STR_NOALIGN ) ;
}
2007-11-27 14:35:30 -08:00
# endif
2007-11-19 17:51:21 -08:00
2002-09-25 15:19:00 +00:00
/*******************************************************************
2007-11-27 14:35:30 -08:00
Duplicate a UNISTR2 string into a null terminated char *
using a talloc context .
2002-09-25 15:19:00 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2007-11-27 14:35:30 -08:00
char * unistr2_to_ascii_talloc ( TALLOC_CTX * ctx , const UNISTR2 * str )
2002-09-25 15:19:00 +00:00
{
2007-11-27 14:35:30 -08:00
char * s = NULL ;
2007-11-19 17:51:21 -08:00
2007-11-27 14:35:30 -08:00
if ( ! str | | ! str - > buffer ) {
return NULL ;
2007-11-19 17:51:21 -08:00
}
2007-11-27 14:35:30 -08:00
if ( pull_ucs2_base_talloc ( ctx ,
2007-11-19 17:51:21 -08:00
NULL ,
2007-11-27 14:35:30 -08:00
& s ,
2007-11-19 17:51:21 -08:00
str - > buffer ,
str - > uni_str_len * 2 ,
2007-11-27 14:35:30 -08:00
STR_NOALIGN ) = = ( size_t ) - 1 ) {
return NULL ;
2007-11-19 17:51:21 -08:00
}
2007-11-27 14:35:30 -08:00
return s ;
2002-09-25 15:19:00 +00:00
}
2001-12-01 12:31:43 +00:00
/*******************************************************************
2007-11-27 14:35:30 -08:00
Return a string for displaying a UNISTR2 . Guarentees to return a
valid string - " " if nothing else .
Changed to use talloc_tos ( ) under the covers . . . . JRA .
2001-12-01 12:31:43 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2007-11-27 14:35:30 -08:00
const char * unistr2_static ( const UNISTR2 * str )
2001-12-01 12:31:43 +00:00
{
2007-11-27 14:35:30 -08:00
char * dest = NULL ;
if ( ( str = = NULL ) | | ( str - > uni_str_len = = 0 ) ) {
return " " ;
2005-07-26 00:10:45 +00:00
}
2007-11-27 14:35:30 -08:00
dest = unistr2_to_ascii_talloc ( talloc_tos ( ) , str ) ;
if ( ! dest ) {
return " " ;
2005-07-26 00:10:45 +00:00
}
2007-11-27 14:35:30 -08:00
return dest ;
2001-12-01 12:31:43 +00:00
}
1999-12-23 01:57:43 +00:00
/*******************************************************************
2001-10-03 12:18:20 +00:00
Convert a wchar to upper case .
1999-12-23 01:57:43 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-03 12:18:20 +00:00
smb_ucs2_t toupper_w ( smb_ucs2_t val )
2000-04-15 07:14:40 +00:00
{
2002-03-06 20:38:51 +00:00
return upcase_table [ SVAL ( & val , 0 ) ] ;
2000-04-15 07:14:40 +00:00
}
1999-12-23 01:57:43 +00:00
/*******************************************************************
2001-10-03 12:18:20 +00:00
Convert a wchar to lower case .
1999-12-23 01:57:43 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-03 12:18:20 +00:00
smb_ucs2_t tolower_w ( smb_ucs2_t val )
1999-12-23 01:57:43 +00:00
{
2002-03-06 20:38:51 +00:00
return lowcase_table [ SVAL ( & val , 0 ) ] ;
1999-12-23 01:57:43 +00:00
}
1999-12-23 18:58:44 +00:00
1999-12-23 01:57:43 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Determine if a character is lowercase .
1999-12-23 01:57:43 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2007-10-18 17:40:25 -07:00
bool islower_w ( smb_ucs2_t c )
1999-12-23 01:57:43 +00:00
{
2002-03-06 20:38:51 +00:00
return upcase_table [ SVAL ( & c , 0 ) ] ! = c ;
1999-12-23 01:57:43 +00:00
}
1999-12-23 18:58:44 +00:00
1999-12-23 02:01:37 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Determine if a character is uppercase .
1999-12-23 02:01:37 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2007-10-18 17:40:25 -07:00
bool isupper_w ( smb_ucs2_t c )
1999-12-23 02:01:37 +00:00
{
2002-03-06 20:38:51 +00:00
return lowcase_table [ SVAL ( & c , 0 ) ] ! = c ;
1999-12-23 02:01:37 +00:00
}
/*******************************************************************
2005-07-26 00:10:45 +00:00
Determine if a character is valid in a 8.3 name .
1999-12-23 02:01:37 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2007-10-18 17:40:25 -07:00
bool isvalid83_w ( smb_ucs2_t c )
1999-12-23 02:01:37 +00:00
{
2002-03-06 20:38:51 +00:00
return valid_table [ SVAL ( & c , 0 ) ] ! = 0 ;
1999-12-23 02:01:37 +00:00
}
1999-12-29 02:00:38 +00:00
/*******************************************************************
2001-07-04 07:15:53 +00:00
Count the number of characters in a smb_ucs2_t string .
1999-12-29 02:00:38 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2001-07-04 07:15:53 +00:00
size_t strlen_w ( const smb_ucs2_t * src )
1999-12-29 02:00:38 +00:00
{
2001-07-04 07:15:53 +00:00
size_t len ;
2005-07-26 00:10:45 +00:00
smb_ucs2_t c ;
1999-12-29 02:00:38 +00:00
2005-07-26 00:10:45 +00:00
for ( len = 0 ; * ( COPY_UCS2_CHAR ( & c , src ) ) ; src + + , len + + ) {
;
}
1999-12-29 02:00:38 +00:00
2001-07-04 07:15:53 +00:00
return len ;
1999-12-29 02:00:38 +00:00
}
2001-11-12 00:53:34 +00:00
/*******************************************************************
Count up to max number of characters in a smb_ucs2_t string .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2001-11-12 00:53:34 +00:00
size_t strnlen_w ( const smb_ucs2_t * src , size_t max )
{
size_t len ;
2005-07-26 00:10:45 +00:00
smb_ucs2_t c ;
2001-11-12 00:53:34 +00:00
2006-12-27 18:36:00 +00:00
for ( len = 0 ; ( len < max ) & & * ( COPY_UCS2_CHAR ( & c , src ) ) ; src + + , len + + ) {
2005-07-26 00:10:45 +00:00
;
}
2001-11-12 00:53:34 +00:00
return len ;
}
1999-12-29 02:00:38 +00:00
/*******************************************************************
2003-07-02 20:01:51 +00:00
Wide strchr ( ) .
1999-12-29 02:00:38 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-07-02 20:01:51 +00:00
2001-07-04 07:15:53 +00:00
smb_ucs2_t * strchr_w ( const smb_ucs2_t * s , smb_ucs2_t c )
1999-12-29 02:00:38 +00:00
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp ;
while ( * ( COPY_UCS2_CHAR ( & cp , s ) ) ) {
if ( c = = cp ) {
return ( smb_ucs2_t * ) s ;
}
1999-12-29 02:00:38 +00:00
s + + ;
}
2005-07-26 00:10:45 +00:00
if ( c = = cp ) {
return ( smb_ucs2_t * ) s ;
}
2002-11-08 18:45:38 +00:00
2001-07-04 07:15:53 +00:00
return NULL ;
1999-12-29 02:00:38 +00:00
}
2001-11-04 21:10:17 +00:00
smb_ucs2_t * strchr_wa ( const smb_ucs2_t * s , char c )
{
return strchr_w ( s , UCS2_CHAR ( c ) ) ;
}
2003-07-02 20:01:51 +00:00
/*******************************************************************
Wide strrchr ( ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-04 18:26:53 +00:00
smb_ucs2_t * strrchr_w ( const smb_ucs2_t * s , smb_ucs2_t c )
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp ;
2001-11-04 18:26:53 +00:00
const smb_ucs2_t * p = s ;
int len = strlen_w ( s ) ;
2005-07-26 00:10:45 +00:00
if ( len = = 0 ) {
return NULL ;
}
2001-11-04 18:26:53 +00:00
p + = ( len - 1 ) ;
do {
2005-07-26 00:10:45 +00:00
if ( c = = * ( COPY_UCS2_CHAR ( & cp , p ) ) ) {
return ( smb_ucs2_t * ) p ;
}
2001-11-04 18:26:53 +00:00
} while ( p - - ! = s ) ;
return NULL ;
}
/*******************************************************************
2003-07-02 20:01:51 +00:00
Wide version of strrchr that returns after doing strrchr ' n ' times .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
smb_ucs2_t * strnrchr_w ( const smb_ucs2_t * s , smb_ucs2_t c , unsigned int n )
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp ;
2003-07-02 20:01:51 +00:00
const smb_ucs2_t * p = s ;
int len = strlen_w ( s ) ;
2005-07-26 00:10:45 +00:00
if ( len = = 0 | | ! n ) {
2003-07-02 20:01:51 +00:00
return NULL ;
2005-07-26 00:10:45 +00:00
}
2003-07-02 20:01:51 +00:00
p + = ( len - 1 ) ;
do {
2005-07-26 00:10:45 +00:00
if ( c = = * ( COPY_UCS2_CHAR ( & cp , p ) ) ) {
2003-07-02 20:01:51 +00:00
n - - ;
2005-07-26 00:10:45 +00:00
}
2003-07-02 20:01:51 +00:00
2005-07-26 00:10:45 +00:00
if ( ! n ) {
2005-05-31 13:46:45 +00:00
return ( smb_ucs2_t * ) p ;
2005-07-26 00:10:45 +00:00
}
2003-07-02 20:01:51 +00:00
} while ( p - - ! = s ) ;
return NULL ;
}
/*******************************************************************
Wide strstr ( ) .
2001-11-04 18:26:53 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-07-02 20:01:51 +00:00
2001-11-04 18:26:53 +00:00
smb_ucs2_t * strstr_w ( const smb_ucs2_t * s , const smb_ucs2_t * ins )
{
smb_ucs2_t * r ;
2005-02-17 15:17:16 +00:00
size_t inslen ;
2005-07-26 00:10:45 +00:00
if ( ! s | | ! * s | | ! ins | | ! * ins ) {
2005-02-17 15:17:16 +00:00
return NULL ;
2005-07-26 00:10:45 +00:00
}
2001-11-04 18:26:53 +00:00
inslen = strlen_w ( ins ) ;
2005-05-31 13:46:45 +00:00
r = ( smb_ucs2_t * ) s ;
2005-02-17 15:17:16 +00:00
2001-11-10 15:21:54 +00:00
while ( ( r = strchr_w ( r , * ins ) ) ) {
2005-07-26 00:10:45 +00:00
if ( strncmp_w ( r , ins , inslen ) = = 0 ) {
2005-02-17 15:17:16 +00:00
return r ;
2005-07-26 00:10:45 +00:00
}
2001-11-04 18:26:53 +00:00
r + + ;
}
2005-02-17 15:17:16 +00:00
2001-11-04 18:26:53 +00:00
return NULL ;
}
1999-12-29 02:00:38 +00:00
/*******************************************************************
Convert a string to lower case .
2001-09-30 13:30:52 +00:00
return True if any char is converted
1999-12-29 02:00:38 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2007-10-18 17:40:25 -07:00
bool strlower_w ( smb_ucs2_t * s )
1999-12-29 02:00:38 +00:00
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp ;
2007-10-18 17:40:25 -07:00
bool ret = False ;
2005-07-26 00:10:45 +00:00
while ( * ( COPY_UCS2_CHAR ( & cp , s ) ) ) {
smb_ucs2_t v = tolower_w ( cp ) ;
if ( v ! = cp ) {
COPY_UCS2_CHAR ( s , & v ) ;
2001-09-30 13:30:52 +00:00
ret = True ;
}
1999-12-29 02:00:38 +00:00
s + + ;
}
2001-09-30 13:30:52 +00:00
return ret ;
1999-12-29 02:00:38 +00:00
}
/*******************************************************************
Convert a string to upper case .
2001-09-30 13:30:52 +00:00
return True if any char is converted
1999-12-29 02:00:38 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2007-10-18 17:40:25 -07:00
bool strupper_w ( smb_ucs2_t * s )
1999-12-29 02:00:38 +00:00
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp ;
2007-10-18 17:40:25 -07:00
bool ret = False ;
2005-07-26 00:10:45 +00:00
while ( * ( COPY_UCS2_CHAR ( & cp , s ) ) ) {
smb_ucs2_t v = toupper_w ( cp ) ;
if ( v ! = cp ) {
COPY_UCS2_CHAR ( s , & v ) ;
2001-09-30 13:30:52 +00:00
ret = True ;
}
1999-12-29 02:00:38 +00:00
s + + ;
}
2001-09-30 13:30:52 +00:00
return ret ;
1999-12-29 02:00:38 +00:00
}
2001-11-04 18:26:53 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Convert a string to " normal " form .
2001-11-04 18:26:53 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-05-07 18:37:47 +00:00
void strnorm_w ( smb_ucs2_t * s , int case_default )
2001-11-04 18:26:53 +00:00
{
2005-07-26 00:10:45 +00:00
if ( case_default = = CASE_UPPER ) {
2004-05-07 18:37:47 +00:00
strupper_w ( s ) ;
2005-07-26 00:10:45 +00:00
} else {
2004-05-07 18:37:47 +00:00
strlower_w ( s ) ;
2005-07-26 00:10:45 +00:00
}
2001-11-04 18:26:53 +00:00
}
2001-11-10 15:21:54 +00:00
int strcmp_w ( const smb_ucs2_t * a , const smb_ucs2_t * b )
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cpa , cpb ;
while ( ( * ( COPY_UCS2_CHAR ( & cpb , b ) ) ) & & ( * ( COPY_UCS2_CHAR ( & cpa , a ) ) = = cpb ) ) {
a + + ;
b + + ;
}
2005-08-12 20:12:31 +00:00
return ( * ( COPY_UCS2_CHAR ( & cpa , a ) ) - * ( COPY_UCS2_CHAR ( & cpb , b ) ) ) ;
2005-07-26 00:10:45 +00:00
/* warning: if *a != *b and both are not 0 we return a random
2001-11-10 15:21:54 +00:00
greater or lesser than 0 number not realted to which
string is longer */
}
int strncmp_w ( const smb_ucs2_t * a , const smb_ucs2_t * b , size_t len )
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cpa , cpb ;
2001-11-10 15:21:54 +00:00
size_t n = 0 ;
2005-07-26 00:10:45 +00:00
while ( ( n < len ) & & ( * ( COPY_UCS2_CHAR ( & cpb , b ) ) ) & & ( * ( COPY_UCS2_CHAR ( & cpa , a ) ) = = cpb ) ) {
a + + ;
b + + ;
n + + ;
}
2005-08-12 20:12:31 +00:00
return ( len - n ) ? ( * ( COPY_UCS2_CHAR ( & cpa , a ) ) - * ( COPY_UCS2_CHAR ( & cpb , b ) ) ) : 0 ;
2001-11-10 15:21:54 +00:00
}
1999-12-29 02:00:38 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Case insensitive string comparison .
1999-12-29 02:00:38 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2001-07-04 07:15:53 +00:00
int strcasecmp_w ( const smb_ucs2_t * a , const smb_ucs2_t * b )
1999-12-29 02:00:38 +00:00
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cpa , cpb ;
while ( ( * COPY_UCS2_CHAR ( & cpb , b ) ) & & toupper_w ( * ( COPY_UCS2_CHAR ( & cpa , a ) ) ) = = toupper_w ( cpb ) ) {
a + + ;
b + + ;
}
2005-08-12 20:12:31 +00:00
return ( tolower_w ( * ( COPY_UCS2_CHAR ( & cpa , a ) ) ) - tolower_w ( * ( COPY_UCS2_CHAR ( & cpb , b ) ) ) ) ;
1999-12-29 02:00:38 +00:00
}
2001-11-04 18:26:53 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Case insensitive string comparison , length limited .
2001-11-04 18:26:53 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2001-11-04 18:26:53 +00:00
int strncasecmp_w ( const smb_ucs2_t * a , const smb_ucs2_t * b , size_t len )
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cpa , cpb ;
2001-11-04 18:26:53 +00:00
size_t n = 0 ;
2005-07-26 00:10:45 +00:00
while ( ( n < len ) & & * COPY_UCS2_CHAR ( & cpb , b ) & & ( toupper_w ( * ( COPY_UCS2_CHAR ( & cpa , a ) ) ) = = toupper_w ( cpb ) ) ) {
a + + ;
b + + ;
n + + ;
}
2005-08-12 20:12:31 +00:00
return ( len - n ) ? ( tolower_w ( * ( COPY_UCS2_CHAR ( & cpa , a ) ) ) - tolower_w ( * ( COPY_UCS2_CHAR ( & cpb , b ) ) ) ) : 0 ;
2001-11-04 18:26:53 +00:00
}
/*******************************************************************
2005-07-26 00:10:45 +00:00
Compare 2 strings .
2001-11-04 18:26:53 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2007-10-18 17:40:25 -07:00
bool strequal_w ( const smb_ucs2_t * s1 , const smb_ucs2_t * s2 )
2001-11-04 18:26:53 +00:00
{
2005-07-26 00:10:45 +00:00
if ( s1 = = s2 ) {
return ( True ) ;
}
if ( ! s1 | | ! s2 ) {
return ( False ) ;
}
2001-11-04 18:26:53 +00:00
return ( strcasecmp_w ( s1 , s2 ) = = 0 ) ;
}
/*******************************************************************
2005-07-26 00:10:45 +00:00
Compare 2 strings up to and including the nth char .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-18 17:40:25 -07:00
bool strnequal_w ( const smb_ucs2_t * s1 , const smb_ucs2_t * s2 , size_t n )
2001-11-04 18:26:53 +00:00
{
2005-07-26 00:10:45 +00:00
if ( s1 = = s2 ) {
return ( True ) ;
}
if ( ! s1 | | ! s2 | | ! n ) {
return ( False ) ;
}
2001-11-04 18:26:53 +00:00
2005-07-26 00:10:45 +00:00
return ( strncasecmp_w ( s1 , s2 , n ) = = 0 ) ;
2001-11-04 18:26:53 +00:00
}
1999-12-29 02:00:38 +00:00
2001-09-25 09:57:06 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Duplicate string .
2001-09-25 09:57:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-26 00:10:45 +00:00
2001-09-25 09:57:06 +00:00
smb_ucs2_t * strdup_w ( const smb_ucs2_t * src )
2001-11-04 18:26:53 +00:00
{
return strndup_w ( src , 0 ) ;
}
/* if len == 0 then duplicate the whole string */
2005-07-26 00:10:45 +00:00
2001-11-04 18:26:53 +00:00
smb_ucs2_t * strndup_w ( const smb_ucs2_t * src , size_t len )
2001-09-25 09:57:06 +00:00
{
smb_ucs2_t * dest ;
2005-07-26 00:10:45 +00:00
if ( ! len ) {
len = strlen_w ( src ) ;
}
2004-12-07 18:25:53 +00:00
dest = SMB_MALLOC_ARRAY ( smb_ucs2_t , len + 1 ) ;
2001-09-25 09:57:06 +00:00
if ( ! dest ) {
DEBUG ( 0 , ( " strdup_w: out of memory! \n " ) ) ;
return NULL ;
}
2001-11-04 18:26:53 +00:00
memcpy ( dest , src , len * sizeof ( smb_ucs2_t ) ) ;
dest [ len ] = 0 ;
2001-09-25 09:57:06 +00:00
return dest ;
}
/*******************************************************************
2005-07-26 00:10:45 +00:00
Copy a string with max len .
2001-09-25 09:57:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
smb_ucs2_t * strncpy_w ( smb_ucs2_t * dest , const smb_ucs2_t * src , const size_t max )
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp ;
2001-09-25 09:57:06 +00:00
size_t len ;
2005-07-26 00:10:45 +00:00
if ( ! dest | | ! src ) {
return NULL ;
}
2001-09-25 09:57:06 +00:00
2005-07-26 00:10:45 +00:00
for ( len = 0 ; ( * COPY_UCS2_CHAR ( & cp , ( src + len ) ) ) & & ( len < max ) ; len + + ) {
cp = * COPY_UCS2_CHAR ( dest + len , src + len ) ;
}
cp = 0 ;
2005-07-27 14:21:27 +00:00
for ( /*nothing*/ ; len < max ; len + + ) {
2005-07-26 00:10:45 +00:00
cp = * COPY_UCS2_CHAR ( dest + len , & cp ) ;
}
2001-09-25 09:57:06 +00:00
return dest ;
}
/*******************************************************************
2005-07-26 00:10:45 +00:00
Append a string of len bytes and add a terminator .
2001-09-25 09:57:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
smb_ucs2_t * strncat_w ( smb_ucs2_t * dest , const smb_ucs2_t * src , const size_t max )
{
size_t start ;
size_t len ;
2005-07-26 00:10:45 +00:00
smb_ucs2_t z = 0 ;
if ( ! dest | | ! src ) {
return NULL ;
}
2001-09-25 09:57:06 +00:00
start = strlen_w ( dest ) ;
2001-11-12 00:53:34 +00:00
len = strnlen_w ( src , max ) ;
2001-09-25 09:57:06 +00:00
2001-10-09 19:12:48 +00:00
memcpy ( & dest [ start ] , src , len * sizeof ( smb_ucs2_t ) ) ;
2005-07-26 00:10:45 +00:00
z = * COPY_UCS2_CHAR ( dest + start + len , & z ) ;
2001-09-25 09:57:06 +00:00
return dest ;
}
2001-11-10 15:21:54 +00:00
smb_ucs2_t * strcat_w ( smb_ucs2_t * dest , const smb_ucs2_t * src )
{
size_t start ;
size_t len ;
2005-07-26 00:10:45 +00:00
smb_ucs2_t z = 0 ;
2001-11-10 15:21:54 +00:00
2005-07-26 00:10:45 +00:00
if ( ! dest | | ! src ) {
return NULL ;
}
2001-11-10 15:21:54 +00:00
start = strlen_w ( dest ) ;
len = strlen_w ( src ) ;
memcpy ( & dest [ start ] , src , len * sizeof ( smb_ucs2_t ) ) ;
2005-07-26 00:10:45 +00:00
z = * COPY_UCS2_CHAR ( dest + start + len , & z ) ;
2001-11-10 15:21:54 +00:00
return dest ;
}
2001-11-18 16:12:11 +00:00
2001-11-10 15:21:54 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Replace any occurence of oldc with newc in unicode string .
2001-11-10 15:21:54 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void string_replace_w ( smb_ucs2_t * s , smb_ucs2_t oldc , smb_ucs2_t newc )
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp ;
for ( ; * ( COPY_UCS2_CHAR ( & cp , s ) ) ; s + + ) {
if ( cp = = oldc ) {
COPY_UCS2_CHAR ( s , & newc ) ;
}
2001-11-10 15:21:54 +00:00
}
}
/*******************************************************************
2005-07-26 00:10:45 +00:00
Trim unicode string .
2001-11-10 15:21:54 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-18 17:40:25 -07:00
bool trim_string_w ( smb_ucs2_t * s , const smb_ucs2_t * front ,
2001-11-10 15:21:54 +00:00
const smb_ucs2_t * back )
{
2007-10-18 17:40:25 -07:00
bool ret = False ;
2001-11-18 16:12:11 +00:00
size_t len , front_len , back_len ;
2001-11-10 15:21:54 +00:00
2005-07-26 00:10:45 +00:00
if ( ! s ) {
return False ;
}
2001-11-10 15:21:54 +00:00
len = strlen_w ( s ) ;
if ( front & & * front ) {
front_len = strlen_w ( front ) ;
while ( len & & strncmp_w ( s , front , front_len ) = = 0 ) {
2001-11-18 16:12:11 +00:00
memmove ( s , ( s + front_len ) , ( len - front_len + 1 ) * sizeof ( smb_ucs2_t ) ) ;
2001-11-10 15:21:54 +00:00
len - = front_len ;
ret = True ;
}
}
if ( back & & * back ) {
back_len = strlen_w ( back ) ;
2001-11-18 16:12:11 +00:00
while ( len & & strncmp_w ( ( s + ( len - back_len ) ) , back , back_len ) = = 0 ) {
2001-11-10 15:21:54 +00:00
s [ len - back_len ] = 0 ;
len - = back_len ;
ret = True ;
}
}
return ret ;
}
2001-09-25 09:57:06 +00:00
2001-07-04 07:15:53 +00:00
/*
The * _wa ( ) functions take a combination of 7 bit ascii
and wide characters They are used so that you can use string
functions combining C string constants with ucs2 strings
1999-12-29 02:00:38 +00:00
2001-07-04 07:15:53 +00:00
The char * arguments must NOT be multibyte - to be completely sure
of this only pass string constants */
1999-12-29 02:00:38 +00:00
2001-11-04 18:26:53 +00:00
int strcmp_wa ( const smb_ucs2_t * a , const char * b )
1999-12-29 02:00:38 +00:00
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp = 0 ;
while ( * b & & * ( COPY_UCS2_CHAR ( & cp , a ) ) = = UCS2_CHAR ( * b ) ) {
a + + ;
b + + ;
}
2005-08-02 17:52:44 +00:00
return ( * ( COPY_UCS2_CHAR ( & cp , a ) ) - UCS2_CHAR ( * b ) ) ;
1999-12-29 02:00:38 +00:00
}
2001-11-04 18:26:53 +00:00
int strncmp_wa ( const smb_ucs2_t * a , const char * b , size_t len )
1999-12-29 02:00:38 +00:00
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp = 0 ;
2001-11-04 18:26:53 +00:00
size_t n = 0 ;
2005-07-26 00:10:45 +00:00
while ( ( n < len ) & & * b & & * ( COPY_UCS2_CHAR ( & cp , a ) ) = = UCS2_CHAR ( * b ) ) {
a + + ;
b + + ;
n + + ;
}
2005-08-02 17:52:44 +00:00
return ( len - n ) ? ( * ( COPY_UCS2_CHAR ( & cp , a ) ) - UCS2_CHAR ( * b ) ) : 0 ;
1999-12-29 02:00:38 +00:00
}
2001-07-04 07:15:53 +00:00
smb_ucs2_t * strpbrk_wa ( const smb_ucs2_t * s , const char * p )
1999-12-29 02:00:38 +00:00
{
2005-07-26 00:10:45 +00:00
smb_ucs2_t cp ;
while ( * ( COPY_UCS2_CHAR ( & cp , s ) ) ) {
2001-07-04 07:15:53 +00:00
int i ;
2005-07-26 00:10:45 +00:00
for ( i = 0 ; p [ i ] & & cp ! = UCS2_CHAR ( p [ i ] ) ; i + + )
2001-07-04 07:15:53 +00:00
;
2005-07-26 00:10:45 +00:00
if ( p [ i ] ) {
return ( smb_ucs2_t * ) s ;
}
1999-12-29 02:00:38 +00:00
s + + ;
}
2001-07-04 07:15:53 +00:00
return NULL ;
2000-10-03 02:12:14 +00:00
}
2001-11-10 15:21:54 +00:00
smb_ucs2_t * strstr_wa ( const smb_ucs2_t * s , const char * ins )
{
smb_ucs2_t * r ;
2005-02-17 15:17:16 +00:00
size_t inslen ;
2005-07-26 00:10:45 +00:00
if ( ! s | | ! ins ) {
2005-02-17 15:17:16 +00:00
return NULL ;
2005-07-26 00:10:45 +00:00
}
2001-11-10 15:21:54 +00:00
inslen = strlen ( ins ) ;
2005-05-31 13:46:45 +00:00
r = ( smb_ucs2_t * ) s ;
2005-02-17 15:17:16 +00:00
2001-11-10 15:21:54 +00:00
while ( ( r = strchr_w ( r , UCS2_CHAR ( * ins ) ) ) ) {
2005-02-17 15:17:16 +00:00
if ( strncmp_wa ( r , ins , inslen ) = = 0 )
return r ;
2001-11-10 15:21:54 +00:00
r + + ;
}
2005-02-17 15:17:16 +00:00
2001-11-10 15:21:54 +00:00
return NULL ;
}
2001-09-25 09:57:06 +00:00
2002-03-26 03:15:30 +00:00
/*******************************************************************
2005-07-26 00:10:45 +00:00
Returns the length in number of wide characters .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-26 03:15:30 +00:00
int unistrlen ( uint16 * s )
{
int len ;
2005-07-26 00:10:45 +00:00
if ( ! s ) {
2002-03-26 03:15:30 +00:00
return - 1 ;
2005-07-26 00:10:45 +00:00
}
2002-03-26 03:15:30 +00:00
2005-07-26 00:10:45 +00:00
for ( len = 0 ; SVAL ( s , 0 ) ; s + + , len + + ) {
;
}
2002-03-26 03:15:30 +00:00
return len ;
}
/*******************************************************************
2005-07-26 00:10:45 +00:00
Strcpy for unicode strings . Returns length ( in num of wide chars ) .
Not odd align safe .
2002-03-26 03:15:30 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int unistrcpy ( uint16 * dst , uint16 * src )
{
int num_wchars = 0 ;
2005-07-26 00:10:45 +00:00
while ( SVAL ( src , 0 ) ) {
2002-03-26 03:15:30 +00:00
* dst + + = * src + + ;
num_wchars + + ;
}
* dst = 0 ;
return num_wchars ;
}
2002-07-15 10:35:28 +00:00
/**
* Samba ucs2 type to UNISTR2 conversion
*
* @ param ctx Talloc context to create the dst strcture ( if null ) and the
* contents of the unicode string .
* @ param dst UNISTR2 destination . If equals null , then it ' s allocated .
* @ param src smb_ucs2_t source .
* @ param max_len maximum number of unicode characters to copy . If equals
* null , then null - termination of src is taken
*
* @ return copied UNISTR2 destination
* */
2005-07-26 00:10:45 +00:00
2002-07-15 10:35:28 +00:00
UNISTR2 * ucs2_to_unistr2 ( TALLOC_CTX * ctx , UNISTR2 * dst , smb_ucs2_t * src )
{
size_t len ;
2005-07-26 00:10:45 +00:00
if ( ! src ) {
2003-09-25 21:26:16 +00:00
return NULL ;
2005-07-26 00:10:45 +00:00
}
2002-07-15 10:35:28 +00:00
len = strlen_w ( src ) ;
/* allocate UNISTR2 destination if not given */
if ( ! dst ) {
2004-12-07 18:25:53 +00:00
dst = TALLOC_P ( ctx , UNISTR2 ) ;
2003-09-25 21:26:16 +00:00
if ( ! dst )
return NULL ;
2002-07-15 10:35:28 +00:00
}
if ( ! dst - > buffer ) {
2004-12-07 18:25:53 +00:00
dst - > buffer = TALLOC_ARRAY ( ctx , uint16 , len + 1 ) ;
2003-09-25 21:26:16 +00:00
if ( ! dst - > buffer )
return NULL ;
2002-07-15 10:35:28 +00:00
}
/* set UNISTR2 parameters */
dst - > uni_max_len = len + 1 ;
2003-09-25 21:26:16 +00:00
dst - > offset = 0 ;
2002-07-15 10:35:28 +00:00
dst - > uni_str_len = len ;
/* copy the actual unicode string */
strncpy_w ( dst - > buffer , src , dst - > uni_max_len ) ;
return dst ;
2003-09-22 17:53:59 +00:00
}
2005-12-27 20:52:36 +00:00
/*************************************************************
ascii only toupper - saves the need for smbd to be in C locale .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int toupper_ascii ( int c )
{
smb_ucs2_t uc = toupper_w ( UCS2_CHAR ( c ) ) ;
return UCS2_TO_CHAR ( uc ) ;
}
/*************************************************************
ascii only tolower - saves the need for smbd to be in C locale .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int tolower_ascii ( int c )
{
smb_ucs2_t uc = tolower_w ( UCS2_CHAR ( c ) ) ;
return UCS2_TO_CHAR ( uc ) ;
}
/*************************************************************
ascii only isupper - saves the need for smbd to be in C locale .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int isupper_ascii ( int c )
{
return isupper_w ( UCS2_CHAR ( c ) ) ;
}
/*************************************************************
ascii only islower - saves the need for smbd to be in C locale .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int islower_ascii ( int c )
{
return islower_w ( UCS2_CHAR ( c ) ) ;
}