2005-04-17 02:20:36 +04:00
/*
* linux / fs / isofs / joliet . c
*
* ( C ) 1996 Gordon Chaffee
*
* Joliet : Microsoft ' s Unicode extensions to iso9660
*/
2005-04-26 05:32:12 +04:00
# include <linux/types.h>
2005-04-17 02:20:36 +04:00
# include <linux/nls.h>
2005-04-26 05:32:12 +04:00
# include "isofs.h"
2005-04-17 02:20:36 +04:00
/*
2006-03-22 02:13:35 +03:00
* Convert Unicode 16 to UTF - 8 or ASCII .
2005-04-17 02:20:36 +04:00
*/
static int
2005-12-24 22:33:09 +03:00
uni16_to_x8 ( unsigned char * ascii , __be16 * uni , int len , struct nls_table * nls )
2005-04-17 02:20:36 +04:00
{
2005-12-24 22:33:09 +03:00
__be16 * ip , ch ;
2005-04-17 02:20:36 +04:00
unsigned char * op ;
ip = uni ;
op = ascii ;
while ( ( ch = get_unaligned ( ip ) ) & & len ) {
int llen ;
2005-12-24 22:33:09 +03:00
llen = nls - > uni2char ( be16_to_cpu ( ch ) , op , NLS_MAX_CHARSET_SIZE ) ;
if ( llen > 0 )
2005-04-17 02:20:36 +04:00
op + = llen ;
else
* op + + = ' ? ' ;
ip + + ;
len - - ;
}
* op = 0 ;
return ( op - ascii ) ;
}
/* Convert big endian wide character string to utf8 */
static int
wcsntombs_be ( __u8 * s , const __u8 * pwcs , int inlen , int maxlen )
{
const __u8 * ip ;
__u8 * op ;
int size ;
__u16 c ;
op = s ;
ip = pwcs ;
while ( ( * ip | | ip [ 1 ] ) & & ( maxlen > 0 ) & & ( inlen > 0 ) ) {
c = ( * ip < < 8 ) | ip [ 1 ] ;
if ( c > 0x7f ) {
size = utf8_wctomb ( op , c , maxlen ) ;
if ( size = = - 1 ) {
/* Ignore character and move on */
maxlen - - ;
} else {
op + = size ;
maxlen - = size ;
}
} else {
* op + + = ( __u8 ) c ;
}
ip + = 2 ;
inlen - - ;
}
return ( op - s ) ;
}
int
get_joliet_filename ( struct iso_directory_record * de , unsigned char * outname , struct inode * inode )
{
unsigned char utf8 ;
struct nls_table * nls ;
unsigned char len = 0 ;
utf8 = ISOFS_SB ( inode - > i_sb ) - > s_utf8 ;
nls = ISOFS_SB ( inode - > i_sb ) - > s_nls_iocharset ;
if ( utf8 ) {
len = wcsntombs_be ( outname , de - > name ,
de - > name_len [ 0 ] > > 1 , PAGE_SIZE ) ;
} else {
2005-12-24 22:33:09 +03:00
len = uni16_to_x8 ( outname , ( __be16 * ) de - > name ,
2005-04-17 02:20:36 +04:00
de - > name_len [ 0 ] > > 1 , nls ) ;
}
if ( ( len > 2 ) & & ( outname [ len - 2 ] = = ' ; ' ) & & ( outname [ len - 1 ] = = ' 1 ' ) ) {
len - = 2 ;
}
/*
* Windows doesn ' t like periods at the end of a name ,
* so neither do we
*/
while ( len > = 2 & & ( outname [ len - 1 ] = = ' . ' ) ) {
len - - ;
}
return len ;
}