2002-04-11 06:20:56 +04:00
/*
Unix SMB / CIFS implementation .
Name mapping code
Copyright ( C ) Jeremy Allison 1998
Copyright ( C ) Andrew Tridgell 2002
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"
/* ************************************************************************** **
* Used only in do_fwd_mangled_map ( ) , below .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
static char * map_filename ( char * s , /* This is null terminated */
const char * pattern , /* This isn't. */
int len ) /* This is the length of pattern. */
{
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! */
pstrcpy ( matching_bit , " " ) ; /* Match but no star gets this. */
pp = pat ; /* Initialize the pointers. */
sp = s ;
if ( strequal ( s , " . " ) | | strequal ( s , " .. " ) )
{
return NULL ; /* Do not map '.' and '..' */
}
if ( ( len = = 1 ) & & ( * pattern = = ' * ' ) )
{
return NULL ; /* Impossible, too ambiguous for */
} /* words! */
while ( ( * sp ) /* Not the end of the string. */
& & ( * pp ) /* Not the end of the pattern. */
& & ( * sp = = * pp ) /* The two match. */
& & ( * pp ! = ' * ' ) ) /* No wildcard. */
{
sp + + ; /* Keep looking. */
pp + + ;
}
if ( ! * sp & & ! * pp ) /* End of pattern. */
return ( matching_bit ) ; /* Simple match. Return empty string. */
if ( * pp = = ' * ' )
{
pp + + ; /* Always interrested in the chacter */
/* after the '*' */
if ( ! * pp ) /* It is at the end of the pattern. */
{
StrnCpy ( matching_bit , s , sp - s ) ;
return ( matching_bit ) ;
}
else
{
/* The next character in pattern must match a character further */
/* along s than sp so look for that character. */
match_start = sp ;
while ( ( * sp ) /* Not the end of s. */
& & ( * sp ! = * pp ) ) /* Not the same */
sp + + ; /* Keep looking. */
if ( ! * sp ) /* Got to the end without a match. */
{
return ( NULL ) ;
} /* Still hope for a match. */
else
{
/* Now sp should point to a matching character. */
StrnCpy ( matching_bit , match_start , sp - match_start ) ;
/* Back to needing a stright match again. */
while ( ( * sp ) /* Not the end of the string. */
& & ( * pp ) /* Not the end of the pattern. */
& & ( * sp = = * pp ) ) /* The two match. */
{
sp + + ; /* Keep looking. */
pp + + ;
}
if ( ! * sp & & ! * pp ) /* Both at end so it matched */
return ( matching_bit ) ;
else
return ( NULL ) ;
}
}
}
return ( NULL ) ; /* No match. */
} /* map_filename */
/* ************************************************************************** **
* 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 .
*
* See ' mangled map ' in smb . conf ( 5 ) .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
static void mangled_map ( char * s , const char * MangledMap )
{
2002-07-15 14:35:28 +04:00
const char * start = MangledMap ; /* Use this to search for mappings. */
const char * end ; /* Used to find the end of strings. */
2002-04-11 06:20:56 +04:00
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 ) ) ;
while ( * start ) {
while ( ( * start ) & & ( * start ! = ' ( ' ) )
start + + ;
if ( ! * start )
continue ; /* Always check for the end. */
start + + ; /* Skip the ( */
end = start ; /* Search for the ' ' or a ')' */
DEBUG ( 5 , ( " Start of first in pair '%s' \n " , start ) ) ;
while ( ( * end ) & & ! ( ( * end = = ' ' ) | | ( * end = = ' ) ' ) ) )
end + + ;
if ( ! * end ) {
start = end ;
continue ; /* Always check for the end. */
}
DEBUG ( 5 , ( " End of first in pair '%s' \n " , end ) ) ;
if ( ( match_string = map_filename ( s , start , end - start ) ) ) {
2003-03-12 22:07:49 +03:00
int size_left = sizeof ( new_string ) - 1 ;
2002-04-11 06:20:56 +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 ;
2003-03-12 22:07:49 +03:00
while ( ( * end & & size_left > 0 ) /* Not the end of string. */
2002-04-11 06:20:56 +04:00
& & ( * end ! = ' ) ' ) /* Not the end of the pattern. */
2003-03-12 22:07:49 +03:00
& & ( * end ! = ' * ' ) ) { /* Not a wildcard. */
2002-04-11 06:20:56 +04:00
* np + + = * end + + ;
2003-03-12 22:07:49 +03:00
size_left - - ;
}
2002-04-11 06:20:56 +04:00
if ( ! * end ) {
start = end ;
continue ; /* Always check for the end. */
}
if ( * end = = ' * ' ) {
2003-03-12 22:07:49 +03:00
if ( size_left > 0 )
safe_strcpy ( np , match_string , size_left ) ;
2002-04-11 06:20:56 +04:00
np + = strlen ( match_string ) ;
2003-03-12 22:07:49 +03:00
size_left - = strlen ( match_string ) ;
2002-04-11 06:20:56 +04:00
end + + ; /* Skip the '*' */
2003-03-12 22:07:49 +03:00
while ( ( * end & & size_left > 0 ) /* Not the end of string. */
2002-04-11 06:20:56 +04:00
& & ( * end ! = ' ) ' ) /* Not the end of the pattern. */
2003-03-12 22:07:49 +03:00
& & ( * end ! = ' * ' ) ) { /* Not a wildcard. */
2002-04-11 06:20:56 +04:00
* np + + = * end + + ;
2003-03-12 22:07:49 +03:00
size_left - - ;
}
2002-04-11 06:20:56 +04:00
}
if ( ! * end ) {
start = end ;
continue ; /* Always check for the end. */
}
2003-03-12 22:07:49 +03:00
if ( size_left > 0 )
* np + + = ' \0 ' ; /* NULL terminate it. */
2002-04-11 06:20:56 +04:00
DEBUG ( 5 , ( " End of second in pair '%s' \n " , end ) ) ;
2003-03-12 22:07:49 +03:00
new_string [ sizeof ( new_string ) - 1 ] = ' \0 ' ;
2002-04-11 06:20:56 +04:00
pstrcpy ( s , new_string ) ; /* Substitute with the new name. */
DEBUG ( 5 , ( " s is now '%s' \n " , s ) ) ;
}
start = end ; /* Skip a bit which cannot be wanted anymore. */
start + + ;
}
}
/*
front end routine to the mangled map code
personally I think that the whole idea of " mangled map " is completely bogus
*/
2003-03-18 01:56:13 +03:00
void mangle_map_filename ( fstring fname , int snum )
2002-04-11 06:20:56 +04:00
{
char * map ;
map = lp_mangled_map ( snum ) ;
if ( ! map | | ! * map ) return ;
mangled_map ( fname , map ) ;
}