0001-01-01 02:30:17 +02:30
/*
0001-01-01 02:30:17 +02:30
Unix SMB / CIFS implementation .
0001-01-01 02:30:17 +02:30
Character set conversion Extensions
0001-01-01 02:30:17 +02:30
Copyright ( C ) Igor Vergeichik < iverg @ mail . ru > 2001
Copyright ( C ) Andrew Tridgell 2001
0001-01-01 02:30:17 +02:30
Copyright ( C ) Simo Sorce 2001
0001-01-01 02:30:17 +02:30
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"
0001-01-01 02:30:17 +02:30
static pstring cvtbuf ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
static smb_iconv_t conv_handles [ NUM_CHARSETS ] [ NUM_CHARSETS ] ;
/****************************************************************************
0001-01-01 02:30:17 +02:30
Return the name of a charset to give to iconv ( ) .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
static char * charset_name ( charset_t ch )
{
char * ret = NULL ;
if ( ch = = CH_UCS2 ) ret = " UCS-2LE " ;
else if ( ch = = CH_UNIX ) ret = lp_unix_charset ( ) ;
else if ( ch = = CH_DOS ) ret = lp_dos_charset ( ) ;
else if ( ch = = CH_DISPLAY ) ret = lp_display_charset ( ) ;
0001-01-01 02:30:17 +02:30
else if ( ch = = CH_UTF8 ) ret = " UTF8 " ;
0001-01-01 02:30:17 +02:30
if ( ! ret | | ! * ret ) ret = " ASCII " ;
return ret ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
static void lazy_initialize_conv ( void )
{
static int initialized = False ;
if ( ! initialized ) {
initialized = True ;
load_case_tables ( ) ;
init_iconv ( ) ;
init_valid_table ( ) ;
}
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Initialize iconv conversion descriptors .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
void init_iconv ( void )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
int c1 , c2 ;
0001-01-01 02:30:17 +02:30
BOOL did_reload = False ;
0001-01-01 02:30:17 +02:30
/* so that charset_name() works we need to get the UNIX<->UCS2 going
first */
0001-01-01 02:30:17 +02:30
if ( ! conv_handles [ CH_UNIX ] [ CH_UCS2 ] )
0001-01-01 02:30:17 +02:30
conv_handles [ CH_UNIX ] [ CH_UCS2 ] = smb_iconv_open ( " UCS-2LE " , " ASCII " ) ;
0001-01-01 02:30:17 +02:30
if ( ! conv_handles [ CH_UCS2 ] [ CH_UNIX ] )
0001-01-01 02:30:17 +02:30
conv_handles [ CH_UCS2 ] [ CH_UNIX ] = smb_iconv_open ( " ASCII " , " UCS-2LE " ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
for ( c1 = 0 ; c1 < NUM_CHARSETS ; c1 + + ) {
for ( c2 = 0 ; c2 < NUM_CHARSETS ; c2 + + ) {
0001-01-01 02:30:17 +02:30
char * n1 = charset_name ( ( charset_t ) c1 ) ;
char * n2 = charset_name ( ( charset_t ) c2 ) ;
0001-01-01 02:30:17 +02:30
if ( conv_handles [ c1 ] [ c2 ] & &
strcmp ( n1 , conv_handles [ c1 ] [ c2 ] - > from_name ) = = 0 & &
0001-01-01 02:30:17 +02:30
strcmp ( n2 , conv_handles [ c1 ] [ c2 ] - > to_name ) = = 0 )
continue ;
0001-01-01 02:30:17 +02:30
did_reload = True ;
0001-01-01 02:30:17 +02:30
if ( conv_handles [ c1 ] [ c2 ] )
0001-01-01 02:30:17 +02:30
smb_iconv_close ( conv_handles [ c1 ] [ c2 ] ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
conv_handles [ c1 ] [ c2 ] = smb_iconv_open ( n2 , n1 ) ;
if ( conv_handles [ c1 ] [ c2 ] = = ( smb_iconv_t ) - 1 ) {
DEBUG ( 0 , ( " Conversion from %s to %s not supported \n " ,
0001-01-01 02:30:17 +02:30
charset_name ( ( charset_t ) c1 ) , charset_name ( ( charset_t ) c2 ) ) ) ;
0001-01-01 02:30:17 +02:30
conv_handles [ c1 ] [ c2 ] = NULL ;
}
}
}
0001-01-01 02:30:17 +02:30
if ( did_reload ) {
init_valid_table ( ) ;
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/**
* Convert string from one encoding to another , making error checking etc
*
* @ param descriptor conversion descriptor , created in init_iconv ( )
* @ param src pointer to source string ( multibyte or singlebyte )
* @ param srclen length of the source string in bytes
* @ param dest pointer to destination string ( multibyte or singlebyte )
* @ param destlen maximal length allowed for string
* @ retval the number of bytes occupied in the destination
* */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
size_t convert_string ( charset_t from , charset_t to ,
void const * src , size_t srclen ,
void * dest , size_t destlen )
0001-01-01 02:30:17 +02:30
{
size_t i_len , o_len ;
size_t retval ;
0001-01-01 02:30:17 +02:30
const char * inbuf = ( const char * ) src ;
0001-01-01 02:30:17 +02:30
char * outbuf = ( char * ) dest ;
0001-01-01 02:30:17 +02:30
smb_iconv_t descriptor ;
0001-01-01 02:30:17 +02:30
if ( srclen = = ( size_t ) - 1 )
srclen = strlen ( src ) + 1 ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
lazy_initialize_conv ( ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
descriptor = conv_handles [ from ] [ to ] ;
if ( descriptor = = ( smb_iconv_t ) - 1 | | descriptor = = ( smb_iconv_t ) 0 ) {
0001-01-01 02:30:17 +02:30
/* conversion not supported, use as is */
0001-01-01 02:30:17 +02:30
size_t len = MIN ( srclen , destlen ) ;
0001-01-01 02:30:17 +02:30
memcpy ( dest , src , len ) ;
return len ;
}
i_len = srclen ;
o_len = destlen ;
0001-01-01 02:30:17 +02:30
retval = smb_iconv ( descriptor , & inbuf , & i_len , & outbuf , & o_len ) ;
0001-01-01 02:30:17 +02:30
if ( retval = = - 1 ) {
0001-01-01 02:30:17 +02:30
char * reason = " unknown error " ;
0001-01-01 02:30:17 +02:30
switch ( errno ) {
case EINVAL :
reason = " Incomplete multibyte sequence " ;
break ;
case E2BIG :
reason = " No more room " ;
DEBUG ( 0 , ( " convert_string: Required %d, available %d \n " ,
srclen , destlen ) ) ;
/* we are not sure we need srclen bytes,
0001-01-01 02:30:17 +02:30
may be more , may be less .
We only know we need more than destlen
bytes - - - simo */
0001-01-01 02:30:17 +02:30
break ;
0001-01-01 02:30:17 +02:30
case EILSEQ :
reason = " Illegal multibyte sequence " ;
break ;
0001-01-01 02:30:17 +02:30
}
/* smb_panic(reason); */
}
return destlen - o_len ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/**
* Convert between character sets , allocating a new buffer for the result .
*
* @ param srclen length of source buffer .
0001-01-01 02:30:17 +02:30
* @ param dest always set at least to NULL
0001-01-01 02:30:17 +02:30
* @ note - 1 is not accepted for srclen .
*
* @ retval Size in bytes of the converted string ; or - 1 in case of error .
* */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
size_t convert_string_allocate ( charset_t from , charset_t to ,
void const * src , size_t srclen , void * * dest )
{
size_t i_len , o_len , destlen ;
size_t retval ;
0001-01-01 02:30:17 +02:30
const char * inbuf = ( const char * ) src ;
0001-01-01 02:30:17 +02:30
char * outbuf , * ob ;
smb_iconv_t descriptor ;
* dest = NULL ;
0001-01-01 02:30:17 +02:30
if ( src = = NULL | | srclen = = ( size_t ) - 1 )
return ( size_t ) - 1 ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
lazy_initialize_conv ( ) ;
0001-01-01 02:30:17 +02:30
descriptor = conv_handles [ from ] [ to ] ;
if ( descriptor = = ( smb_iconv_t ) - 1 | | descriptor = = ( smb_iconv_t ) 0 ) {
/* conversion not supported, return -1*/
0001-01-01 02:30:17 +02:30
DEBUG ( 3 , ( " convert_string_allocate: conversion not supported! \n " ) ) ;
0001-01-01 02:30:17 +02:30
return - 1 ;
}
0001-01-01 02:30:17 +02:30
destlen = MAX ( srclen , 512 ) ;
0001-01-01 02:30:17 +02:30
outbuf = NULL ;
convert :
destlen = destlen * 2 ;
ob = ( char * ) realloc ( outbuf , destlen ) ;
if ( ! ob ) {
DEBUG ( 0 , ( " convert_string_allocate: realloc failed! \n " ) ) ;
0001-01-01 02:30:17 +02:30
SAFE_FREE ( outbuf ) ;
0001-01-01 02:30:17 +02:30
return ( size_t ) - 1 ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
else
outbuf = ob ;
0001-01-01 02:30:17 +02:30
i_len = srclen ;
o_len = destlen ;
retval = smb_iconv ( descriptor ,
0001-01-01 02:30:17 +02:30
& inbuf , & i_len ,
0001-01-01 02:30:17 +02:30
& outbuf , & o_len ) ;
0001-01-01 02:30:17 +02:30
if ( retval = = - 1 ) {
0001-01-01 02:30:17 +02:30
char * reason = " unknown error " ;
0001-01-01 02:30:17 +02:30
switch ( errno ) {
case EINVAL :
reason = " Incomplete multibyte sequence " ;
break ;
case E2BIG :
goto convert ;
case EILSEQ :
reason = " Illegal multibyte sequence " ;
break ;
0001-01-01 02:30:17 +02:30
}
DEBUG ( 0 , ( " Conversion error: %s(%s) \n " , reason , inbuf ) ) ;
/* smb_panic(reason); */
0001-01-01 02:30:17 +02:30
return ( size_t ) - 1 ;
0001-01-01 02:30:17 +02:30
}
destlen = destlen - o_len ;
0001-01-01 02:30:17 +02:30
* dest = ( char * ) Realloc ( ob , destlen ) ;
0001-01-01 02:30:17 +02:30
if ( ! * dest ) {
DEBUG ( 0 , ( " convert_string_allocate: out of memory! \n " ) ) ;
0001-01-01 02:30:17 +02:30
SAFE_FREE ( ob ) ;
0001-01-01 02:30:17 +02:30
return ( size_t ) - 1 ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
return destlen ;
}
0001-01-01 02:30:17 +02:30
/**
* Convert between character sets , allocating a new buffer using talloc for the result .
*
* @ param srclen length of source buffer .
* @ param dest always set at least to NULL
* @ note - 1 is not accepted for srclen .
*
* @ retval Size in bytes of the converted string ; or - 1 in case of error .
* */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
size_t convert_string_talloc ( TALLOC_CTX * ctx , charset_t from , charset_t to ,
void const * src , size_t srclen , void * * dest )
{
0001-01-01 02:30:17 +02:30
void * alloced_string ;
0001-01-01 02:30:17 +02:30
size_t dest_len ;
* dest = NULL ;
0001-01-01 02:30:17 +02:30
dest_len = convert_string_allocate ( from , to , src , srclen , & alloced_string ) ;
0001-01-01 02:30:17 +02:30
if ( dest_len = = ( size_t ) - 1 )
return ( size_t ) - 1 ;
0001-01-01 02:30:17 +02:30
* dest = talloc_memdup ( ctx , alloced_string , dest_len ) ;
SAFE_FREE ( alloced_string ) ;
0001-01-01 02:30:17 +02:30
if ( * dest = = NULL )
0001-01-01 02:30:17 +02:30
return ( size_t ) - 1 ;
0001-01-01 02:30:17 +02:30
return dest_len ;
}
0001-01-01 02:30:17 +02:30
size_t unix_strupper ( const char * src , size_t srclen , char * dest , size_t destlen )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t size ;
0001-01-01 02:30:17 +02:30
smb_ucs2_t * buffer = ( smb_ucs2_t * ) cvtbuf ;
0001-01-01 02:30:17 +02:30
size = convert_string ( CH_UNIX , CH_UCS2 , src , srclen , buffer , sizeof ( cvtbuf ) ) ;
0001-01-01 02:30:17 +02:30
if ( ! strupper_w ( buffer ) & & ( dest = = src ) )
return srclen ;
0001-01-01 02:30:17 +02:30
return convert_string ( CH_UCS2 , CH_UNIX , buffer , size , dest , destlen ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
size_t unix_strlower ( const char * src , size_t srclen , char * dest , size_t destlen )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t size ;
0001-01-01 02:30:17 +02:30
smb_ucs2_t * buffer = ( smb_ucs2_t * ) cvtbuf ;
0001-01-01 02:30:17 +02:30
size = convert_string ( CH_UNIX , CH_UCS2 , src , srclen , buffer , sizeof ( cvtbuf ) ) ;
0001-01-01 02:30:17 +02:30
if ( ! strlower_w ( buffer ) & & ( dest = = src ) )
return srclen ;
0001-01-01 02:30:17 +02:30
return convert_string ( CH_UCS2 , CH_UNIX , buffer , size , dest , destlen ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
size_t ucs2_align ( const void * base_ptr , const void * p , int flags )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( flags & ( STR_NOALIGN | STR_ASCII ) )
return 0 ;
0001-01-01 02:30:17 +02:30
return PTR_DIFF ( p , base_ptr ) & 1 ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
copy a string from a char * unix src to a dos codepage string destination
return the number of bytes occupied by the string in the destination
flags can have :
STR_TERMINATE means include the null termination
STR_UPPER means uppercase in the destination
0001-01-01 02:30:17 +02:30
dest_len is the maximum length in bytes allowed in the destination . If dest_len
0001-01-01 02:30:17 +02:30
is - 1 then no maxiumum is used
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
size_t push_ascii ( void * dest , const char * src , size_t dest_len , int flags )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = strlen ( src ) ;
0001-01-01 02:30:17 +02:30
pstring tmpbuf ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/* treat a pstring as "unlimited" length */
0001-01-01 02:30:17 +02:30
if ( dest_len = = ( size_t ) - 1 )
0001-01-01 02:30:17 +02:30
dest_len = sizeof ( pstring ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( flags & STR_UPPER ) {
pstrcpy ( tmpbuf , src ) ;
strupper ( tmpbuf ) ;
src = tmpbuf ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( flags & STR_TERMINATE )
0001-01-01 02:30:17 +02:30
src_len + + ;
0001-01-01 02:30:17 +02:30
return convert_string ( CH_UNIX , CH_DOS , src , src_len , dest , dest_len ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
size_t push_ascii_fstring ( void * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
return push_ascii ( dest , src , sizeof ( fstring ) , STR_TERMINATE ) ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
size_t push_ascii_pstring ( void * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
return push_ascii ( dest , src , sizeof ( pstring ) , STR_TERMINATE ) ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
size_t push_pstring ( void * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
return push_ascii ( dest , src , sizeof ( pstring ) , STR_TERMINATE ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Copy a string from a dos codepage source to a unix char * destination .
Flags can have :
STR_TERMINATE means the string in src is null terminated .
if STR_TERMINATE is set then src_len is ignored .
src_len is the length of the source area in bytes .
Return the number of bytes occupied by the string in src .
The resulting string in " dest " is always null terminated .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
size_t pull_ascii ( char * dest , const void * src , size_t dest_len , size_t src_len , int flags )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t ret ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( dest_len = = ( size_t ) - 1 )
0001-01-01 02:30:17 +02:30
dest_len = sizeof ( pstring ) ;
0001-01-01 02:30:17 +02:30
if ( flags & STR_TERMINATE ) {
0001-01-01 02:30:17 +02:30
if ( src_len = = ( size_t ) - 1 ) {
0001-01-01 02:30:17 +02:30
src_len = strlen ( src ) + 1 ;
} else {
0001-01-01 02:30:17 +02:30
size_t len = strnlen ( src , src_len ) ;
if ( len < src_len )
len + + ;
0001-01-01 02:30:17 +02:30
src_len = len ;
}
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
ret = convert_string ( CH_DOS , CH_UNIX , src , src_len , dest , dest_len ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( dest_len )
dest [ MIN ( ret , dest_len - 1 ) ] = 0 ;
0001-01-01 02:30:17 +02:30
return src_len ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
size_t pull_ascii_pstring ( char * dest , const void * src )
0001-01-01 02:30:17 +02:30
{
return pull_ascii ( dest , src , sizeof ( pstring ) , - 1 , STR_TERMINATE ) ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
size_t pull_ascii_fstring ( char * dest , const void * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
return pull_ascii ( dest , src , sizeof ( fstring ) , - 1 , STR_TERMINATE ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Copy a string from a char * src to a unicode destination .
Return the number of bytes occupied by the string in the destination .
Flags can have :
STR_TERMINATE means include the null termination .
STR_UPPER means uppercase in the destination .
STR_NOALIGN means don ' t do alignment .
dest_len is the maximum length allowed in the destination . If dest_len
is - 1 then no maxiumum is used .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
size_t push_ucs2 ( const void * base_ptr , void * dest , const char * src , size_t dest_len , int flags )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t len = 0 ;
size_t src_len = strlen ( src ) ;
0001-01-01 02:30:17 +02:30
pstring tmpbuf ;
/* treat a pstring as "unlimited" length */
0001-01-01 02:30:17 +02:30
if ( dest_len = = ( size_t ) - 1 )
0001-01-01 02:30:17 +02:30
dest_len = sizeof ( pstring ) ;
if ( flags & STR_UPPER ) {
pstrcpy ( tmpbuf , src ) ;
strupper ( tmpbuf ) ;
src = tmpbuf ;
}
0001-01-01 02:30:17 +02:30
if ( flags & STR_TERMINATE )
0001-01-01 02:30:17 +02:30
src_len + + ;
if ( ucs2_align ( base_ptr , dest , flags ) ) {
* ( char * ) dest = 0 ;
dest = ( void * ) ( ( char * ) dest + 1 ) ;
if ( dest_len ) dest_len - - ;
len + + ;
}
0001-01-01 02:30:17 +02:30
/* ucs2 is always a multiple of 2 bytes */
dest_len & = ~ 1 ;
0001-01-01 02:30:17 +02:30
len + = convert_string ( CH_UNIX , CH_UCS2 , src , src_len , dest , dest_len ) ;
0001-01-01 02:30:17 +02:30
return len ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/**
* Copy a string from a unix char * src to a UCS2 destination , allocating a buffer using talloc
*
* @ param dest always set at least to NULL
*
* @ retval The number of bytes occupied by the string in the destination
0001-01-01 02:30:17 +02:30
* or - 1 in case of error .
0001-01-01 02:30:17 +02:30
* */
0001-01-01 02:30:17 +02:30
size_t push_ucs2_talloc ( TALLOC_CTX * ctx , smb_ucs2_t * * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = strlen ( src ) + 1 ;
0001-01-01 02:30:17 +02:30
* dest = NULL ;
0001-01-01 02:30:17 +02:30
return convert_string_talloc ( ctx , CH_UNIX , CH_UCS2 , src , src_len , ( void * * ) dest ) ;
0001-01-01 02:30:17 +02:30
}
/**
* Copy a string from a unix char * src to a UCS2 destination , allocating a buffer
*
* @ param dest always set at least to NULL
*
* @ retval The number of bytes occupied by the string in the destination
0001-01-01 02:30:17 +02:30
* or - 1 in case of error .
0001-01-01 02:30:17 +02:30
* */
0001-01-01 02:30:17 +02:30
size_t push_ucs2_allocate ( smb_ucs2_t * * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = strlen ( src ) + 1 ;
0001-01-01 02:30:17 +02:30
* dest = NULL ;
0001-01-01 02:30:17 +02:30
return convert_string_allocate ( CH_UNIX , CH_UCS2 , src , src_len , ( void * * ) dest ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Copy a string from a char * src to a UTF - 8 destination .
Return the number of bytes occupied by the string in the destination
Flags can have :
0001-01-01 02:30:17 +02:30
STR_TERMINATE means include the null termination
STR_UPPER means uppercase in the destination
0001-01-01 02:30:17 +02:30
dest_len is the maximum length allowed in the destination . If dest_len
is - 1 then no maxiumum is used .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
size_t push_utf8 ( void * dest , const char * src , size_t dest_len , int flags )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = strlen ( src ) ;
0001-01-01 02:30:17 +02:30
pstring tmpbuf ;
/* treat a pstring as "unlimited" length */
0001-01-01 02:30:17 +02:30
if ( dest_len = = ( size_t ) - 1 )
0001-01-01 02:30:17 +02:30
dest_len = sizeof ( pstring ) ;
if ( flags & STR_UPPER ) {
pstrcpy ( tmpbuf , src ) ;
strupper ( tmpbuf ) ;
src = tmpbuf ;
}
0001-01-01 02:30:17 +02:30
if ( flags & STR_TERMINATE )
0001-01-01 02:30:17 +02:30
src_len + + ;
return convert_string ( CH_UNIX , CH_UTF8 , src , src_len , dest , dest_len ) ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
size_t push_utf8_fstring ( void * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
return push_utf8 ( dest , src , sizeof ( fstring ) , STR_TERMINATE ) ;
}
0001-01-01 02:30:17 +02:30
size_t push_utf8_pstring ( void * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
return push_utf8 ( dest , src , sizeof ( pstring ) , STR_TERMINATE ) ;
}
0001-01-01 02:30:17 +02:30
/**
* Copy a string from a unix char * src to a UTF - 8 destination , allocating a buffer using talloc
*
* @ param dest always set at least to NULL
*
* @ retval The number of bytes occupied by the string in the destination
* */
0001-01-01 02:30:17 +02:30
size_t push_utf8_talloc ( TALLOC_CTX * ctx , char * * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = strlen ( src ) + 1 ;
0001-01-01 02:30:17 +02:30
* dest = NULL ;
0001-01-01 02:30:17 +02:30
return convert_string_talloc ( ctx , CH_UNIX , CH_UTF8 , src , src_len , ( void * * ) dest ) ;
0001-01-01 02:30:17 +02:30
}
/**
* Copy a string from a unix char * src to a UTF - 8 destination , allocating a buffer
*
* @ param dest always set at least to NULL
*
* @ retval The number of bytes occupied by the string in the destination
* */
0001-01-01 02:30:17 +02:30
size_t push_utf8_allocate ( char * * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = strlen ( src ) + 1 ;
0001-01-01 02:30:17 +02:30
* dest = NULL ;
0001-01-01 02:30:17 +02:30
return convert_string_allocate ( CH_UNIX , CH_UTF8 , src , src_len , ( void * * ) dest ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Copy a string from a ucs2 source to a unix char * destination .
Flags can have :
STR_TERMINATE means the string in src is null terminated .
STR_NOALIGN means don ' t try to align .
if STR_TERMINATE is set then src_len is ignored if it is - 1.
src_len is the length of the source area in bytes
Return the number of bytes occupied by the string in src .
The resulting string in " dest " is always null terminated .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
size_t pull_ucs2 ( const void * base_ptr , char * dest , const void * src , size_t dest_len , size_t src_len , int flags )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t ret ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( dest_len = = ( size_t ) - 1 )
0001-01-01 02:30:17 +02:30
dest_len = sizeof ( pstring ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ucs2_align ( base_ptr , src , flags ) ) {
src = ( const void * ) ( ( const char * ) src + 1 ) ;
0001-01-01 02:30:17 +02:30
if ( src_len > 0 )
src_len - - ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( flags & STR_TERMINATE ) {
0001-01-01 02:30:17 +02:30
if ( src_len = = ( size_t ) - 1 ) {
0001-01-01 02:30:17 +02:30
src_len = strlen_w ( src ) * 2 + 2 ;
} else {
0001-01-01 02:30:17 +02:30
size_t len = strnlen_w ( src , src_len / 2 ) ;
if ( len < src_len / 2 )
len + + ;
0001-01-01 02:30:17 +02:30
src_len = len * 2 ;
}
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/* ucs2 is always a multiple of 2 bytes */
0001-01-01 02:30:17 +02:30
if ( src_len ! = ( size_t ) - 1 )
0001-01-01 02:30:17 +02:30
src_len & = ~ 1 ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
ret = convert_string ( CH_UCS2 , CH_UNIX , src , src_len , dest , dest_len ) ;
0001-01-01 02:30:17 +02:30
if ( dest_len )
dest [ MIN ( ret , dest_len - 1 ) ] = 0 ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
return src_len ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
size_t pull_ucs2_pstring ( char * dest , const void * src )
0001-01-01 02:30:17 +02:30
{
return pull_ucs2 ( NULL , dest , src , sizeof ( pstring ) , - 1 , STR_TERMINATE ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
size_t pull_ucs2_fstring ( char * dest , const void * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
return pull_ucs2 ( NULL , dest , src , sizeof ( fstring ) , - 1 , STR_TERMINATE ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/**
* Copy a string from a UCS2 src to a unix char * destination , allocating a buffer using talloc
*
* @ param dest always set at least to NULL
*
* @ retval The number of bytes occupied by the string in the destination
* */
0001-01-01 02:30:17 +02:30
size_t pull_ucs2_talloc ( TALLOC_CTX * ctx , void * * dest , const smb_ucs2_t * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = ( strlen_w ( src ) + 1 ) * sizeof ( smb_ucs2_t ) ;
0001-01-01 02:30:17 +02:30
* dest = NULL ;
return convert_string_talloc ( ctx , CH_UCS2 , CH_UNIX , src , src_len , dest ) ;
}
/**
* Copy a string from a UCS2 src to a unix char * destination , allocating a buffer
*
* @ param dest always set at least to NULL
*
* @ retval The number of bytes occupied by the string in the destination
* */
0001-01-01 02:30:17 +02:30
size_t pull_ucs2_allocate ( void * * dest , const smb_ucs2_t * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = ( strlen_w ( src ) + 1 ) * sizeof ( smb_ucs2_t ) ;
0001-01-01 02:30:17 +02:30
* dest = NULL ;
return convert_string_allocate ( CH_UCS2 , CH_UNIX , src , src_len , dest ) ;
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Copy a string from a utf - 8 source to a unix char * destination .
Flags can have :
STR_TERMINATE means the string in src is null terminated .
if STR_TERMINATE is set then src_len is ignored .
src_len is the length of the source area in bytes
Return the number of bytes occupied by the string in src .
The resulting string in " dest " is always null terminated .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
size_t pull_utf8 ( char * dest , const void * src , size_t dest_len , size_t src_len , int flags )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t ret ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( dest_len = = ( size_t ) - 1 )
0001-01-01 02:30:17 +02:30
dest_len = sizeof ( pstring ) ;
0001-01-01 02:30:17 +02:30
if ( flags & STR_TERMINATE ) {
0001-01-01 02:30:17 +02:30
if ( src_len = = ( size_t ) - 1 ) {
0001-01-01 02:30:17 +02:30
src_len = strlen ( src ) + 1 ;
} else {
0001-01-01 02:30:17 +02:30
size_t len = strnlen ( src , src_len ) ;
if ( len < src_len )
len + + ;
0001-01-01 02:30:17 +02:30
src_len = len ;
}
}
0001-01-01 02:30:17 +02:30
ret = convert_string ( CH_UTF8 , CH_UNIX , src , src_len , dest , dest_len ) ;
0001-01-01 02:30:17 +02:30
if ( dest_len )
dest [ MIN ( ret , dest_len - 1 ) ] = 0 ;
0001-01-01 02:30:17 +02:30
return src_len ;
}
0001-01-01 02:30:17 +02:30
size_t pull_utf8_pstring ( char * dest , const void * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
return pull_utf8 ( dest , src , sizeof ( pstring ) , - 1 , STR_TERMINATE ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
size_t pull_utf8_fstring ( char * dest , const void * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
return pull_utf8 ( dest , src , sizeof ( fstring ) , - 1 , STR_TERMINATE ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/**
* Copy a string from a UTF - 8 src to a unix char * destination , allocating a buffer using talloc
*
* @ param dest always set at least to NULL
*
* @ retval The number of bytes occupied by the string in the destination
* */
0001-01-01 02:30:17 +02:30
size_t pull_utf8_talloc ( TALLOC_CTX * ctx , char * * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = strlen ( src ) + 1 ;
0001-01-01 02:30:17 +02:30
* dest = NULL ;
0001-01-01 02:30:17 +02:30
return convert_string_talloc ( ctx , CH_UTF8 , CH_UNIX , src , src_len , ( void * * ) dest ) ;
0001-01-01 02:30:17 +02:30
}
/**
* Copy a string from a UTF - 8 src to a unix char * destination , allocating a buffer
*
* @ param dest always set at least to NULL
*
* @ retval The number of bytes occupied by the string in the destination
* */
0001-01-01 02:30:17 +02:30
size_t pull_utf8_allocate ( void * * dest , const char * src )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
size_t src_len = strlen ( src ) + 1 ;
0001-01-01 02:30:17 +02:30
* dest = NULL ;
return convert_string_allocate ( CH_UTF8 , CH_UNIX , src , src_len , dest ) ;
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Copy a string from a char * src to a unicode or ascii
dos codepage destination choosing unicode or ascii based on the
flags in the SMB buffer starting at base_ptr .
Return the number of bytes occupied by the string in the destination .
flags can have :
STR_TERMINATE means include the null termination .
STR_UPPER means uppercase in the destination .
STR_ASCII use ascii even with unicode packet .
STR_NOALIGN means don ' t do alignment .
dest_len is the maximum length allowed in the destination . If dest_len
is - 1 then no maxiumum is used .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
size_t push_string ( const void * base_ptr , void * dest , const char * src , size_t dest_len , int flags )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( ! ( flags & STR_ASCII ) & & \
( ( flags & STR_UNICODE | | \
( SVAL ( base_ptr , smb_flg2 ) & FLAGS2_UNICODE_STRINGS ) ) ) ) {
return push_ucs2 ( base_ptr , dest , src , dest_len , flags ) ;
}
return push_ascii ( dest , src , dest_len , flags ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Copy a string from a unicode or ascii source ( depending on
the packet flags ) to a char * destination .
Flags can have :
STR_TERMINATE means the string in src is null terminated .
STR_UNICODE means to force as unicode .
STR_ASCII use ascii even with unicode packet .
STR_NOALIGN means don ' t do alignment .
if STR_TERMINATE is set then src_len is ignored is it is - 1
src_len is the length of the source area in bytes .
Return the number of bytes occupied by the string in src .
The resulting string in " dest " is always null terminated .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
size_t pull_string ( const void * base_ptr , char * dest , const void * src , size_t dest_len , size_t src_len , int flags )
0001-01-01 02:30:17 +02:30
{
if ( ! ( flags & STR_ASCII ) & & \
( ( flags & STR_UNICODE | | \
( SVAL ( base_ptr , smb_flg2 ) & FLAGS2_UNICODE_STRINGS ) ) ) ) {
return pull_ucs2 ( base_ptr , dest , src , dest_len , src_len , flags ) ;
}
return pull_ascii ( dest , src , dest_len , src_len , flags ) ;
}
0001-01-01 02:30:17 +02:30
size_t align_string ( const void * base_ptr , const char * p , int flags )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( ! ( flags & STR_ASCII ) & & \
( ( flags & STR_UNICODE | | \
( SVAL ( base_ptr , smb_flg2 ) & FLAGS2_UNICODE_STRINGS ) ) ) ) {
return ucs2_align ( base_ptr , p , flags ) ;
}
return 0 ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Convert from ucs2 to unix charset and return the
allocated and converted string or NULL if an error occurred .
You must provide a zero terminated string .
The returning string will be zero terminated .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
char * acnv_u2ux ( const smb_ucs2_t * src )
{
size_t slen ;
size_t dlen ;
void * dest ;
0001-01-01 02:30:17 +02:30
slen = ( strlen_w ( src ) + 1 ) * sizeof ( smb_ucs2_t ) ;
0001-01-01 02:30:17 +02:30
dlen = convert_string_allocate ( CH_UCS2 , CH_UNIX , src , slen , & dest ) ;
0001-01-01 02:30:17 +02:30
if ( dlen = = ( size_t ) - 1 )
return NULL ;
else
return dest ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
0001-01-01 02:30:17 +02:30
Convert from unix to ucs2 charset and return the
allocated and converted string or NULL if an error occurred .
You must provide a zero terminated string .
The returning string will be zero terminated .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
smb_ucs2_t * acnv_uxu2 ( const char * src )
{
size_t slen ;
size_t dlen ;
void * dest ;
slen = strlen ( src ) + 1 ;
dlen = convert_string_allocate ( CH_UNIX , CH_UCS2 , src , slen , & dest ) ;
0001-01-01 02:30:17 +02:30
if ( dlen = = ( size_t ) - 1 )
return NULL ;
else
return dest ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
Convert from ucs2 to dos charset and return the
allocated and converted string or NULL if an error occurred .
You must provide a zero terminated string .
The returning string will be zero terminated .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
char * acnv_u2dos ( const smb_ucs2_t * src )
{
size_t slen ;
size_t dlen ;
void * dest ;
slen = ( strlen_w ( src ) + 1 ) * sizeof ( smb_ucs2_t ) ;
dlen = convert_string_allocate ( CH_UCS2 , CH_DOS , src , slen , & dest ) ;
0001-01-01 02:30:17 +02:30
if ( dlen = = ( size_t ) - 1 )
return NULL ;
else
return dest ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
0001-01-01 02:30:17 +02:30
Convert from dos to ucs2 charset and return the
allocated and converted string or NULL if an error occurred .
You must provide a zero terminated string .
The returning string will be zero terminated .
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
smb_ucs2_t * acnv_dosu2 ( const char * src )
{
size_t slen ;
size_t dlen ;
void * dest ;
slen = strlen ( src ) + 1 ;
dlen = convert_string_allocate ( CH_DOS , CH_UCS2 , src , slen , & dest ) ;
0001-01-01 02:30:17 +02:30
if ( dlen = = ( size_t ) - 1 )
return NULL ;
else
return dest ;
0001-01-01 02:30:17 +02:30
}