1996-05-04 11:50:46 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
Name mangling
1997-05-08 05:14:17 +04:00
Copyright ( C ) Andrew Tridgell 1992 - 1997
1996-05-04 11:50:46 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
extern int DEBUGLEVEL ;
extern int case_default ;
extern BOOL case_mangle ;
/****************************************************************************
1997-11-07 06:06:24 +03:00
* Provide a checksum on a string
*
* Input : s - the nul - terminated character string for which the checksum
* will be calculated .
* Output : The checksum value calculated for s .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-05-04 11:50:46 +04:00
int str_checksum ( char * s )
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
int res = 0 ;
int c ;
int i = 0 ;
1997-11-07 06:06:24 +03:00
while ( * s )
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
c = * s ;
res ^ = ( c < < ( i % 15 ) ) ^ ( c > > ( 15 - ( i % 15 ) ) ) ;
s + + ; i + + ;
1996-05-04 11:50:46 +04:00
}
return ( res ) ;
1997-11-07 06:06:24 +03:00
} /* str_checksum */
1996-05-04 11:50:46 +04:00
/****************************************************************************
return True if a name is a special msdos reserved name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL is_reserved_msdos ( char * fname )
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
char upperFname [ 13 ] ;
char * p ;
StrnCpy ( upperFname , fname , 12 ) ;
/* lpt1.txt and con.txt etc are also illegal */
p = strchr ( upperFname , ' . ' ) ;
if ( p )
* p = ' \0 ' ;
strupper ( upperFname ) ;
if ( ( strcmp ( upperFname , " CLOCK$ " ) = = 0 ) | |
( strcmp ( upperFname , " CON " ) = = 0 ) | |
( strcmp ( upperFname , " AUX " ) = = 0 ) | |
( strcmp ( upperFname , " COM1 " ) = = 0 ) | |
( strcmp ( upperFname , " COM2 " ) = = 0 ) | |
( strcmp ( upperFname , " COM3 " ) = = 0 ) | |
( strcmp ( upperFname , " COM4 " ) = = 0 ) | |
( strcmp ( upperFname , " LPT1 " ) = = 0 ) | |
( strcmp ( upperFname , " LPT2 " ) = = 0 ) | |
( strcmp ( upperFname , " LPT3 " ) = = 0 ) | |
( strcmp ( upperFname , " NUL " ) = = 0 ) | |
( strcmp ( upperFname , " PRN " ) = = 0 ) )
return ( True ) ;
return ( False ) ;
1997-11-07 06:06:24 +03:00
} /* is_reserved_msdos */
1996-05-04 11:50:46 +04:00
/****************************************************************************
return True if a name is in 8.3 dos format
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-02-12 01:53:29 +03:00
BOOL is_8_3 ( char * fname , BOOL check_case )
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
int len ;
char * dot_pos ;
char * slash_pos = strrchr ( fname , ' / ' ) ;
int l ;
1997-11-07 06:06:24 +03:00
if ( slash_pos )
fname = slash_pos + 1 ;
1996-05-04 11:50:46 +04:00
len = strlen ( fname ) ;
DEBUG ( 5 , ( " checking %s for 8.3 \n " , fname ) ) ;
1997-11-07 06:06:24 +03:00
if ( check_case & & case_mangle )
{
1996-05-04 11:50:46 +04:00
switch ( case_default )
{
case CASE_LOWER :
1997-11-07 06:06:24 +03:00
if ( strhasupper ( fname ) ) return ( False ) ;
break ;
1996-05-04 11:50:46 +04:00
case CASE_UPPER :
1997-11-07 06:06:24 +03:00
if ( strhaslower ( fname ) ) return ( False ) ;
break ;
1996-05-04 11:50:46 +04:00
}
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
/* can't be longer than 12 chars */
1997-11-07 06:06:24 +03:00
if ( len = = 0 | | len > 12 )
1996-05-04 11:50:46 +04:00
return ( False ) ;
/* can't be an MS-DOS Special file such as lpt1 or even lpt1.txt */
1997-11-07 06:06:24 +03:00
if ( is_reserved_msdos ( fname ) )
1996-05-04 11:50:46 +04:00
return ( False ) ;
/* can't contain invalid dos chars */
/* Windows use the ANSI charset.
But filenames are translated in the PC charset .
This Translation may be more or less relaxed depending
the Windows application . */
/* %%% A nice improvment to name mangling would be to translate
filename to ANSI charset on the smb server host */
1996-05-04 14:44:49 +04:00
dot_pos = strchr ( fname , ' . ' ) ;
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
char * p = fname ;
1997-11-07 06:06:24 +03:00
1997-09-12 00:17:32 +04:00
if ( lp_client_code_page ( ) = = KANJI_CODEPAGE )
1997-11-07 06:06:24 +03:00
{
1997-09-12 00:17:32 +04:00
dot_pos = 0 ;
while ( * p )
1997-11-07 06:06:24 +03:00
{
1997-09-12 00:17:32 +04:00
if ( is_shift_jis ( * p ) )
p + = 2 ;
else if ( is_kana ( * p ) )
p + + ;
else
1997-11-07 06:06:24 +03:00
{
1997-09-12 00:17:32 +04:00
if ( * p = = ' . ' & & ! dot_pos )
dot_pos = ( char * ) p ;
if ( ! isdoschar ( * p ) )
return ( False ) ;
p + + ;
1997-11-07 06:06:24 +03:00
}
1997-09-12 00:17:32 +04:00
}
1997-11-07 06:06:24 +03:00
}
1997-09-12 00:17:32 +04:00
else
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
while ( * p )
{
1997-09-12 00:17:32 +04:00
if ( ! isdoschar ( * p ) )
return ( False ) ;
p + + ;
1997-11-07 06:06:24 +03:00
}
}
1997-09-12 00:17:32 +04:00
}
1996-05-04 11:50:46 +04:00
/* no dot and less than 9 means OK */
if ( ! dot_pos )
return ( len < = 8 ) ;
1997-11-07 06:06:24 +03:00
1996-05-04 11:50:46 +04:00
l = PTR_DIFF ( dot_pos , fname ) ;
/* base must be at least 1 char except special cases . and .. */
1997-11-07 06:06:24 +03:00
if ( l = = 0 )
1996-05-04 11:50:46 +04:00
return ( strcmp ( fname , " . " ) = = 0 | | strcmp ( fname , " .. " ) = = 0 ) ;
/* base can't be greater than 8 */
1997-11-07 06:06:24 +03:00
if ( l > 8 )
1996-05-04 11:50:46 +04:00
return ( False ) ;
1997-11-07 06:06:24 +03:00
if ( lp_strip_dot ( ) & &
1996-05-04 11:50:46 +04:00
len - l = = 1 & &
1997-11-07 06:06:24 +03:00
! strchr ( dot_pos + 1 , ' . ' ) )
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
* dot_pos = 0 ;
return ( True ) ;
1996-05-04 11:50:46 +04:00
}
/* extension must be between 1 and 3 */
1997-11-07 06:06:24 +03:00
if ( ( len - l < 2 ) | | ( len - l > 4 ) )
1996-05-04 11:50:46 +04:00
return ( False ) ;
/* extension can't have a dot */
1997-11-07 06:06:24 +03:00
if ( strchr ( dot_pos + 1 , ' . ' ) )
1996-05-04 11:50:46 +04:00
return ( False ) ;
/* must be in 8.3 format */
return ( True ) ;
1997-11-07 06:06:24 +03:00
} /* is_8_3 */
/* -------------------------------------------------------------------------- **
* This section creates and maintains a stack of name mangling results .
* The original comments read : " keep a stack of name mangling results - just
* so file moves and copies have a chance of working " (whatever that means).
*
* There are three functions to manage the stack :
* reset_mangled_stack ( ) -
* push_mangled_name ( ) -
* check_mangled_stack ( ) -
*/
1996-05-04 11:50:46 +04:00
fstring * mangled_stack = NULL ;
int mangled_stack_size = 0 ;
int mangled_stack_len = 0 ;
/****************************************************************************
1997-11-07 06:06:24 +03:00
* create the mangled stack CRH
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void reset_mangled_stack ( int size )
{
if ( mangled_stack )
{
free ( mangled_stack ) ;
mangled_stack_size = 0 ;
mangled_stack_len = 0 ;
}
if ( size > 0 )
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
mangled_stack = ( fstring * ) malloc ( sizeof ( fstring ) * size ) ;
if ( mangled_stack )
mangled_stack_size = size ;
1996-05-04 11:50:46 +04:00
}
1997-11-07 06:06:24 +03:00
else
mangled_stack = NULL ;
} /* create_mangled_stack */
1996-05-04 11:50:46 +04:00
/****************************************************************************
1997-11-07 06:06:24 +03:00
* push a mangled name onto the stack CRH
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-05-04 11:50:46 +04:00
static void push_mangled_name ( char * s )
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
int i ;
char * p ;
1997-11-07 06:06:24 +03:00
/* If the stack doesn't exist... Fail. */
if ( ! mangled_stack )
1996-05-04 11:50:46 +04:00
return ;
1997-11-07 06:06:24 +03:00
/* If name <s> is already on the stack, move it to the top. */
for ( i = 0 ; i < mangled_stack_len ; i + + )
{
if ( strcmp ( s , mangled_stack [ i ] ) = = 0 )
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
array_promote ( mangled_stack [ 0 ] , sizeof ( fstring ) , i ) ;
return ;
1996-05-04 11:50:46 +04:00
}
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
1997-11-07 06:06:24 +03:00
/* If name <s> wasn't already there, add it to the top of the stack. */
memmove ( mangled_stack [ 1 ] , mangled_stack [ 0 ] ,
sizeof ( fstring ) * MIN ( mangled_stack_len , mangled_stack_size - 1 ) ) ;
strcpy ( mangled_stack [ 0 ] , s ) ;
mangled_stack_len = MIN ( mangled_stack_size , mangled_stack_len + 1 ) ;
/* Hmmm...
* Find the last dot ' . ' in the name ,
* if there are any upper case characters past the last dot
* and there are no more than three characters past the last dot
* then terminate the name * at * the last dot .
*/
p = strrchr ( mangled_stack [ 0 ] , ' . ' ) ;
if ( p & & ( ! strhasupper ( p + 1 ) ) & & ( strlen ( p + 1 ) < ( size_t ) 4 ) )
1996-05-04 11:50:46 +04:00
* p = 0 ;
1997-11-07 06:06:24 +03:00
} /* push_mangled_name */
1996-05-04 11:50:46 +04:00
/****************************************************************************
1997-11-07 06:06:24 +03:00
* check for a name on the mangled name stack CRH
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-05-04 11:50:46 +04:00
BOOL check_mangled_stack ( char * s )
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
int i ;
pstring tmpname ;
char extension [ 5 ] ;
1997-11-07 06:06:24 +03:00
char * p = strrchr ( s , ' . ' ) ;
1996-05-04 11:50:46 +04:00
BOOL check_extension = False ;
extension [ 0 ] = 0 ;
1997-11-07 06:06:24 +03:00
/* If the stack doesn't exist, fail. */
if ( ! mangled_stack )
return ( False ) ;
1996-05-04 11:50:46 +04:00
1997-11-07 06:06:24 +03:00
/* If there is a file extension, then we need to play with it, too. */
if ( p )
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
check_extension = True ;
StrnCpy ( extension , p , 4 ) ;
strlower ( extension ) ; /* XXXXXXX */
1996-05-04 11:50:46 +04:00
}
1997-11-07 06:06:24 +03:00
for ( i = 0 ; i < mangled_stack_len ; i + + )
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
strcpy ( tmpname , mangled_stack [ i ] ) ;
mangle_name_83 ( tmpname ) ;
if ( strequal ( tmpname , s ) )
{
strcpy ( s , mangled_stack [ i ] ) ;
break ;
}
if ( check_extension & & ! strchr ( mangled_stack [ i ] , ' . ' ) )
{
pstrcpy ( tmpname , mangled_stack [ i ] ) ;
strcat ( tmpname , extension ) ;
1996-05-04 11:50:46 +04:00
mangle_name_83 ( tmpname ) ;
1997-11-07 06:06:24 +03:00
if ( strequal ( tmpname , s ) )
{
strcpy ( s , mangled_stack [ i ] ) ;
strcat ( s , extension ) ;
break ;
}
}
1996-05-04 11:50:46 +04:00
}
1997-11-07 06:06:24 +03:00
if ( i < mangled_stack_len )
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
DEBUG ( 3 , ( " Found %s on mangled stack as %s \n " , s , mangled_stack [ i ] ) ) ;
array_promote ( mangled_stack [ 0 ] , sizeof ( fstring ) , i ) ;
return ( True ) ;
1996-05-04 11:50:46 +04:00
}
return ( False ) ;
1997-11-07 06:06:24 +03:00
} /* check_mangled_stack */
/* End of the mangled stack section.
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
*/
1996-05-04 11:50:46 +04:00
1997-11-07 06:06:24 +03:00
static char * map_filename ( char * s , /* This is null terminated */
char * pattern , /* This isn't. */
int len ) /* This is the length of pattern. */
{
1996-05-04 11:50:46 +04:00
static pstring matching_bit ; /* The bit of the string which matches */
/* a * in pattern if indeed there is a * */
char * sp ; /* Pointer into s. */
char * pp ; /* Pointer into p. */
char * match_start ; /* Where the matching bit starts. */
pstring pat ;
StrnCpy ( pat , pattern , len ) ; /* Get pattern into a proper string! */
1997-11-07 06:06:24 +03:00
pstrcpy ( matching_bit , " " ) ; /* Match but no star gets this. */
1996-05-04 11:50:46 +04:00
pp = pat ; /* Initialise the pointers. */
sp = s ;
1997-11-07 06:06:24 +03:00
if ( ( len = = 1 ) & & ( * pattern = = ' * ' ) )
{
1996-05-04 11:50:46 +04:00
return NULL ; /* Impossible, too ambiguous for */
1997-11-07 06:06:24 +03:00
} /* words! */
1996-05-04 11:50:46 +04:00
while ( ( * sp ) /* Not the end of the string. */
& & ( * pp ) /* Not the end of the pattern. */
& & ( * sp = = * pp ) /* The two match. */
1997-11-07 06:06:24 +03:00
& & ( * pp ! = ' * ' ) ) /* No wildcard. */
{
1996-05-04 11:50:46 +04:00
sp + + ; /* Keep looking. */
pp + + ;
1997-11-07 06:06:24 +03:00
}
if ( ! * sp & & ! * pp ) /* End of pattern. */
return ( matching_bit ) ; /* Simple match. Return empty string. */
if ( * pp = = ' * ' )
{
1996-05-04 11:50:46 +04:00
pp + + ; /* Always interrested in the chacter */
/* after the '*' */
1997-11-07 06:06:24 +03:00
if ( ! * pp ) /* It is at the end of the pattern. */
{
1996-05-04 11:50:46 +04:00
StrnCpy ( matching_bit , s , sp - s ) ;
return matching_bit ;
1997-11-07 06:06:24 +03:00
}
else
{
1996-05-04 11:50:46 +04:00
/* The next character in pattern must match a character further */
/* along s than sp so look for that character. */
match_start = sp ;
1997-11-07 06:06:24 +03:00
while ( ( * sp ) /* Not the end of s. */
1996-05-04 11:50:46 +04:00
& & ( * sp ! = * pp ) ) /* Not the same */
sp + + ; /* Keep looking. */
1997-11-07 06:06:24 +03:00
if ( ! * sp ) /* Got to the end without a match. */
{
1996-05-04 11:50:46 +04:00
return NULL ;
1997-11-07 06:06:24 +03:00
} /* Still hope for a match. */
else
{
1996-05-04 11:50:46 +04:00
/* Now sp should point to a matching character. */
StrnCpy ( matching_bit , match_start , sp - match_start ) ;
/* Back to needing a stright match again. */
1997-11-07 06:06:24 +03:00
while ( ( * sp ) /* Not the end of the string. */
1996-05-04 11:50:46 +04:00
& & ( * pp ) /* Not the end of the pattern. */
1997-11-07 06:06:24 +03:00
& & ( * sp = = * pp ) ) /* The two match. */
{
1996-05-04 11:50:46 +04:00
sp + + ; /* Keep looking. */
pp + + ;
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
if ( ! * sp & & ! * pp ) /* Both at end so it matched */
return matching_bit ;
else
return NULL ;
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
}
}
return NULL ; /* No match. */
1997-11-07 06:06:24 +03:00
} /* map_filename */
1996-05-04 11:50:46 +04:00
/* this is the magic char used for mangling */
char magic_char = ' ~ ' ;
/****************************************************************************
1997-11-07 06:06:24 +03:00
return True if the name could be a mangled name
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-11-07 06:06:24 +03:00
BOOL is_mangled ( char * s )
{
1996-05-04 11:50:46 +04:00
char * m = strchr ( s , magic_char ) ;
1997-11-07 06:06:24 +03:00
if ( ! m )
return ( False ) ;
/* we use two base 36 chars before the extension */
if ( m [ 1 ] = = ' . ' | | m [ 1 ] = = 0 | |
1996-05-04 11:50:46 +04:00
m [ 2 ] = = ' . ' | | m [ 2 ] = = 0 | |
1997-11-07 06:06:24 +03:00
( m [ 3 ] ! = ' . ' & & m [ 3 ] ! = 0 ) )
return ( is_mangled ( m + 1 ) ) ;
1996-05-04 11:50:46 +04:00
/* it could be */
return ( True ) ;
1997-11-07 06:06:24 +03:00
} /* is_mangled */
1996-05-04 11:50:46 +04:00
/****************************************************************************
return a base 36 character . v must be from 0 to 35.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-05 17:13:31 +04:00
static char base36 ( unsigned int v )
1997-11-07 06:06:24 +03:00
{
1996-10-05 17:13:31 +04:00
static char basechars [ ] = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " ;
return basechars [ v % 36 ] ;
1997-11-07 06:06:24 +03:00
} /* base36 */
1996-05-04 11:50:46 +04:00
static void do_fwd_mangled_map ( char * s , char * MangledMap )
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
/* MangledMap is a series of name pairs in () separated by spaces.
* If s matches the first of the pair then the name given is the
* second of the pair . A * means any number of any character and if
* present in the second of the pair as well as the first the
* matching part of the first string takes the place of the * in the
* second .
*
* I wanted this so that we could have RCS files which can be used
* by UNIX and DOS programs . My mapping string is ( RCS rcs ) which
* converts the UNIX RCS file subdirectory to lowercase thus
* preventing mangling .
*/
char * start = MangledMap ; /* Use this to search for mappings. */
char * end ; /* Used to find the end of strings. */
char * match_string ;
pstring new_string ; /* Make up the result here. */
char * np ; /* Points into new_string. */
DEBUG ( 5 , ( " Mangled Mapping '%s' map '%s' \n " , s , MangledMap ) ) ;
1997-11-07 06:06:24 +03:00
while ( * start )
{
1996-05-04 11:50:46 +04:00
while ( ( * start ) & & ( * start ! = ' ( ' ) )
start + + ;
if ( ! * start )
continue ; /* Always check for the end. */
1997-08-28 22:59:52 +04:00
start + + ; /* Skip the ( */
1996-05-04 11:50:46 +04:00
end = start ; /* Search for the ' ' or a ')' */
DEBUG ( 5 , ( " Start of first in pair '%s' \n " , start ) ) ;
while ( ( * end ) & & ! ( ( * end = = ' ' ) | | ( * end = = ' ) ' ) ) )
end + + ;
1997-11-07 06:06:24 +03:00
if ( ! * end )
{
1996-05-04 11:50:46 +04:00
start = end ;
continue ; /* Always check for the end. */
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
DEBUG ( 5 , ( " End of first in pair '%s' \n " , end ) ) ;
1997-11-07 06:06:24 +03:00
if ( ( match_string = map_filename ( s , start , end - start ) ) )
{
1996-05-04 11:50:46 +04:00
DEBUG ( 5 , ( " Found a match \n " ) ) ;
/* Found a match. */
start = end + 1 ; /* Point to start of what it is to become. */
DEBUG ( 5 , ( " Start of second in pair '%s' \n " , start ) ) ;
end = start ;
np = new_string ;
while ( ( * end ) /* Not the end of string. */
& & ( * end ! = ' ) ' ) /* Not the end of the pattern. */
& & ( * end ! = ' * ' ) ) /* Not a wildcard. */
* np + + = * end + + ;
1997-11-07 06:06:24 +03:00
if ( ! * end )
{
1996-05-04 11:50:46 +04:00
start = end ;
continue ; /* Always check for the end. */
1997-11-07 06:06:24 +03:00
}
if ( * end = = ' * ' )
{
1997-09-26 22:55:29 +04:00
pstrcpy ( np , match_string ) ;
1996-05-04 11:50:46 +04:00
np + = strlen ( match_string ) ;
end + + ; /* Skip the '*' */
while ( ( * end ) /* Not the end of string. */
& & ( * end ! = ' ) ' ) /* Not the end of the pattern. */
& & ( * end ! = ' * ' ) ) /* Not a wildcard. */
* np + + = * end + + ;
1997-11-07 06:06:24 +03:00
}
if ( ! * end )
{
1996-05-04 11:50:46 +04:00
start = end ;
continue ; /* Always check for the end. */
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
* np + + = ' \0 ' ; /* NULL terminate it. */
DEBUG ( 5 , ( " End of second in pair '%s' \n " , end ) ) ;
1997-09-26 22:55:29 +04:00
pstrcpy ( s , new_string ) ; /* Substitute with the new name. */
1996-05-04 11:50:46 +04:00
DEBUG ( 5 , ( " s is now '%s' \n " , s ) ) ;
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
start = end ; /* Skip a bit which cannot be wanted */
/* anymore. */
start + + ;
1997-11-07 06:06:24 +03:00
}
} /* do_fwd_mangled_map */
1996-05-04 11:50:46 +04:00
/****************************************************************************
do the actual mangling to 8.3 format
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void mangle_name_83 ( char * s )
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
int csum = str_checksum ( s ) ;
char * p ;
char extension [ 4 ] ;
char base [ 9 ] ;
int baselen = 0 ;
int extlen = 0 ;
extension [ 0 ] = 0 ;
base [ 0 ] = 0 ;
p = strrchr ( s , ' . ' ) ;
1997-11-07 06:06:24 +03:00
if ( p & & ( strlen ( p + 1 ) < ( size_t ) 4 ) )
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
BOOL all_normal = ( strisnormal ( p + 1 ) ) ; /* XXXXXXXXX */
if ( all_normal & & p [ 1 ] ! = 0 )
{
* p = 0 ;
csum = str_checksum ( s ) ;
* p = ' . ' ;
}
1996-05-04 11:50:46 +04:00
}
strupper ( s ) ;
DEBUG ( 5 , ( " Mangling name %s to " , s ) ) ;
1997-11-07 06:06:24 +03:00
if ( p )
{
1997-09-12 00:17:32 +04:00
if ( p = = s )
strcpy ( extension , " ___ " ) ;
else
1997-11-07 06:06:24 +03:00
{
* p + + = 0 ;
while ( * p & & extlen < 3 )
1997-09-12 00:17:32 +04:00
{
1997-11-07 06:06:24 +03:00
if ( lp_client_code_page ( ) = = KANJI_CODEPAGE )
1997-09-12 00:17:32 +04:00
{
1997-11-07 06:06:24 +03:00
if ( is_shift_jis ( * p ) )
1997-09-12 00:17:32 +04:00
{
1997-11-07 06:06:24 +03:00
if ( extlen < 2 )
{
1997-09-12 00:17:32 +04:00
extension [ extlen + + ] = p [ 0 ] ;
extension [ extlen + + ] = p [ 1 ] ;
1997-11-07 06:06:24 +03:00
}
1997-09-12 00:17:32 +04:00
else
1997-11-07 06:06:24 +03:00
{
1997-09-12 00:17:32 +04:00
extension [ extlen + + ] = base36 ( ( ( unsigned char ) * p ) % 36 ) ;
1997-11-07 06:06:24 +03:00
}
1997-09-12 00:17:32 +04:00
p + = 2 ;
1997-11-07 06:06:24 +03:00
}
else
{
if ( is_kana ( * p ) )
{
1997-09-12 00:17:32 +04:00
extension [ extlen + + ] = p [ 0 ] ;
1997-11-07 06:06:24 +03:00
p + + ;
}
else
{
if ( isdoschar ( * p ) & & * p ! = ' . ' )
extension [ extlen + + ] = p [ 0 ] ;
p + + ;
}
}
1997-09-12 00:17:32 +04:00
}
else
1997-11-07 06:06:24 +03:00
{
1997-09-12 00:17:32 +04:00
if ( isdoschar ( * p ) & & * p ! = ' . ' )
extension [ extlen + + ] = * p ;
p + + ;
1997-11-07 06:06:24 +03:00
}
1997-09-12 00:17:32 +04:00
}
1997-11-07 06:06:24 +03:00
extension [ extlen ] = 0 ;
1997-09-12 00:17:32 +04:00
}
1996-05-04 11:50:46 +04:00
}
p = s ;
while ( * p & & baselen < 5 )
{
1997-11-07 06:06:24 +03:00
if ( lp_client_code_page ( ) = = KANJI_CODEPAGE )
1997-09-12 00:17:32 +04:00
{
1997-11-07 06:06:24 +03:00
if ( is_shift_jis ( * p ) )
1997-09-12 00:17:32 +04:00
{
1997-11-07 06:06:24 +03:00
if ( baselen < 4 )
{
1997-09-12 00:17:32 +04:00
base [ baselen + + ] = p [ 0 ] ;
base [ baselen + + ] = p [ 1 ] ;
1997-11-07 06:06:24 +03:00
}
1997-09-12 00:17:32 +04:00
else
1997-11-07 06:06:24 +03:00
{
base [ baselen + + ] = base36 ( ( ( unsigned char ) * p ) % 36 ) ;
}
1997-09-12 00:17:32 +04:00
p + = 2 ;
1997-11-07 06:06:24 +03:00
}
else
{
if ( is_kana ( * p ) )
{
1997-09-12 00:17:32 +04:00
base [ baselen + + ] = p [ 0 ] ;
1997-11-07 06:06:24 +03:00
p + + ;
}
else
{
if ( isdoschar ( * p ) & & * p ! = ' . ' )
base [ baselen + + ] = p [ 0 ] ;
p + + ;
}
}
1997-09-12 00:17:32 +04:00
}
else
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
if ( isdoschar ( * p ) & & * p ! = ' . ' )
1997-09-12 00:17:32 +04:00
base [ baselen + + ] = * p ;
1996-05-04 11:50:46 +04:00
p + + ;
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
}
base [ baselen ] = 0 ;
csum = csum % ( 36 * 36 ) ;
1997-11-07 06:06:24 +03:00
sprintf ( s , " %s%c%c%c " , base , magic_char , base36 ( csum / 36 ) , base36 ( csum % 36 ) ) ;
1996-05-04 11:50:46 +04:00
1997-11-07 06:06:24 +03:00
if ( * extension )
1996-05-04 11:50:46 +04:00
{
1997-11-07 06:06:24 +03:00
strcat ( s , " . " ) ;
strcat ( s , extension ) ;
1996-05-04 11:50:46 +04:00
}
DEBUG ( 5 , ( " %s \n " , s ) ) ;
1997-11-07 06:06:24 +03:00
} /* mangle_name_83 */
1996-05-04 11:50:46 +04:00
/*******************************************************************
work out if a name is illegal , even for long names
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL illegal_name ( char * name )
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
static unsigned char illegal [ 256 ] ;
static BOOL initialised = False ;
unsigned char * s ;
1997-11-07 06:06:24 +03:00
if ( ! initialised )
{
1997-10-12 07:48:47 +04:00
char * ill = " * \\ /?<>| \" : " ;
1996-05-04 11:50:46 +04:00
initialised = True ;
bzero ( ( char * ) illegal , 256 ) ;
1997-11-07 06:06:24 +03:00
for ( s = ( unsigned char * ) ill ; * s ; s + + )
1996-05-04 11:50:46 +04:00
illegal [ * s ] = True ;
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
1997-09-12 00:17:32 +04:00
if ( lp_client_code_page ( ) = = KANJI_CODEPAGE )
1997-11-07 06:06:24 +03:00
{
for ( s = ( unsigned char * ) name ; * s ; )
{
if ( is_shift_jis ( * s ) )
1997-09-12 00:17:32 +04:00
s + = 2 ;
1997-11-07 06:06:24 +03:00
else
{
if ( illegal [ * s ] )
return ( True ) ;
else
s + + ;
}
1997-09-12 00:17:32 +04:00
}
1996-05-04 11:50:46 +04:00
}
1997-09-12 00:17:32 +04:00
else
1997-11-07 06:06:24 +03:00
{
1997-09-12 00:17:32 +04:00
for ( s = ( unsigned char * ) name ; * s ; s + + )
if ( illegal [ * s ] ) return ( True ) ;
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
return ( False ) ;
1997-11-07 06:06:24 +03:00
} /* illegal_name */
1996-05-04 11:50:46 +04:00
/****************************************************************************
convert a filename to DOS format . return True if successful .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL name_map_mangle ( char * OutName , BOOL need83 , int snum )
1997-11-07 06:06:24 +03:00
{
1996-05-04 11:50:46 +04:00
# ifdef MANGLE_LONG_FILENAMES
1997-11-07 06:06:24 +03:00
if ( ! need83 & & illegal_name ( OutName ) )
need83 = True ;
1996-05-04 11:50:46 +04:00
# endif
/* apply any name mappings */
{
1997-11-07 06:06:24 +03:00
char * map = lp_mangled_map ( snum ) ;
if ( map & & * map )
do_fwd_mangled_map ( OutName , map ) ;
1996-05-04 11:50:46 +04:00
}
/* check if it's already in 8.3 format */
1997-11-07 06:06:24 +03:00
if ( need83 & & ! is_8_3 ( OutName , True ) )
{
if ( ! lp_manglednames ( snum ) )
return ( False ) ;
1996-05-04 11:50:46 +04:00
/* mangle it into 8.3 */
push_mangled_name ( OutName ) ;
mangle_name_83 ( OutName ) ;
1997-11-07 06:06:24 +03:00
}
1996-05-04 11:50:46 +04:00
return ( True ) ;
1997-11-07 06:06:24 +03:00
} /* name_map_mangle */