00001 /* 00002 Unix SMB/CIFS implementation. 00003 Name mapping code 00004 Copyright (C) Jeremy Allison 1998 00005 Copyright (C) Andrew Tridgell 2002 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 */ 00021 00022 #include "includes.h" 00023 00024 00025 /* ************************************************************************** ** 00026 * Used only in do_fwd_mangled_map(), below. 00027 * ************************************************************************** ** 00028 */ 00029 static char *map_filename( char *s, /* This is null terminated */ 00030 const char *pattern, /* This isn't. */ 00031 int len ) /* This is the length of pattern. */ 00032 { 00033 static pstring matching_bit; /* The bit of the string which matches */ 00034 /* a * in pattern if indeed there is a * */ 00035 char *sp; /* Pointer into s. */ 00036 char *pp; /* Pointer into p. */ 00037 char *match_start; /* Where the matching bit starts. */ 00038 pstring pat; 00039 00040 StrnCpy( pat, pattern, len ); /* Get pattern into a proper string! */ 00041 pstrcpy( matching_bit, "" ); /* Match but no star gets this. */ 00042 pp = pat; /* Initialize the pointers. */ 00043 sp = s; 00044 00045 if( strequal(s, ".") || strequal(s, "..")) 00046 { 00047 return NULL; /* Do not map '.' and '..' */ 00048 } 00049 00050 if( (len == 1) && (*pattern == '*') ) 00051 { 00052 return NULL; /* Impossible, too ambiguous for */ 00053 } /* words! */ 00054 00055 while( (*sp) /* Not the end of the string. */ 00056 && (*pp) /* Not the end of the pattern. */ 00057 && (*sp == *pp) /* The two match. */ 00058 && (*pp != '*') ) /* No wildcard. */ 00059 { 00060 sp++; /* Keep looking. */ 00061 pp++; 00062 } 00063 00064 if( !*sp && !*pp ) /* End of pattern. */ 00065 return( matching_bit ); /* Simple match. Return empty string. */ 00066 00067 if( *pp == '*' ) 00068 { 00069 pp++; /* Always interrested in the chacter */ 00070 /* after the '*' */ 00071 if( !*pp ) /* It is at the end of the pattern. */ 00072 { 00073 StrnCpy( matching_bit, s, sp-s ); 00074 return( matching_bit ); 00075 } 00076 else 00077 { 00078 /* The next character in pattern must match a character further */ 00079 /* along s than sp so look for that character. */ 00080 match_start = sp; 00081 while( (*sp) /* Not the end of s. */ 00082 && (*sp != *pp) ) /* Not the same */ 00083 sp++; /* Keep looking. */ 00084 if( !*sp ) /* Got to the end without a match. */ 00085 { 00086 return( NULL ); 00087 } /* Still hope for a match. */ 00088 else 00089 { 00090 /* Now sp should point to a matching character. */ 00091 StrnCpy(matching_bit, match_start, sp-match_start); 00092 /* Back to needing a stright match again. */ 00093 while( (*sp) /* Not the end of the string. */ 00094 && (*pp) /* Not the end of the pattern. */ 00095 && (*sp == *pp) ) /* The two match. */ 00096 { 00097 sp++; /* Keep looking. */ 00098 pp++; 00099 } 00100 if( !*sp && !*pp ) /* Both at end so it matched */ 00101 return( matching_bit ); 00102 else 00103 return( NULL ); 00104 } 00105 } 00106 } 00107 return( NULL ); /* No match. */ 00108 } /* map_filename */ 00109 00110 00111 /* ************************************************************************** ** 00112 * MangledMap is a series of name pairs in () separated by spaces. 00113 * If s matches the first of the pair then the name given is the 00114 * second of the pair. A * means any number of any character and if 00115 * present in the second of the pair as well as the first the 00116 * matching part of the first string takes the place of the * in the 00117 * second. 00118 * 00119 * I wanted this so that we could have RCS files which can be used 00120 * by UNIX and DOS programs. My mapping string is (RCS rcs) which 00121 * converts the UNIX RCS file subdirectory to lowercase thus 00122 * preventing mangling. 00123 * 00124 * See 'mangled map' in smb.conf(5). 00125 * 00126 * ************************************************************************** ** 00127 */ 00128 static void mangled_map(char *s, const char *MangledMap) 00129 { 00130 const char *start=MangledMap; /* Use this to search for mappings. */ 00131 const char *end; /* Used to find the end of strings. */ 00132 char *match_string; 00133 pstring new_string; /* Make up the result here. */ 00134 char *np; /* Points into new_string. */ 00135 00136 DEBUG( 5, ("Mangled Mapping '%s' map '%s'\n", s, MangledMap) ); 00137 while( *start ) { 00138 while( (*start) && (*start != '(') ) 00139 start++; 00140 if( !*start ) 00141 continue; /* Always check for the end. */ 00142 start++; /* Skip the ( */ 00143 end = start; /* Search for the ' ' or a ')' */ 00144 DEBUG( 5, ("Start of first in pair '%s'\n", start) ); 00145 while( (*end) && !((*end == ' ') || (*end == ')')) ) 00146 end++; 00147 if( !*end ) { 00148 start = end; 00149 continue; /* Always check for the end. */ 00150 } 00151 DEBUG( 5, ("End of first in pair '%s'\n", end) ); 00152 if( (match_string = map_filename( s, start, end-start )) ) { 00153 int size_left = sizeof(new_string) - 1; 00154 DEBUG( 5, ("Found a match\n") ); 00155 /* Found a match. */ 00156 start = end + 1; /* Point to start of what it is to become. */ 00157 DEBUG( 5, ("Start of second in pair '%s'\n", start) ); 00158 end = start; 00159 np = new_string; 00160 while( (*end && size_left > 0) /* Not the end of string. */ 00161 && (*end != ')') /* Not the end of the pattern. */ 00162 && (*end != '*') ) { /* Not a wildcard. */ 00163 *np++ = *end++; 00164 size_left--; 00165 } 00166 00167 if( !*end ) { 00168 start = end; 00169 continue; /* Always check for the end. */ 00170 } 00171 if( *end == '*' ) { 00172 if (size_left > 0 ) 00173 safe_strcpy( np, match_string, size_left ); 00174 np += strlen( match_string ); 00175 size_left -= strlen( match_string ); 00176 end++; /* Skip the '*' */ 00177 while ((*end && size_left > 0) /* Not the end of string. */ 00178 && (*end != ')') /* Not the end of the pattern. */ 00179 && (*end != '*')) { /* Not a wildcard. */ 00180 *np++ = *end++; 00181 size_left--; 00182 } 00183 } 00184 if (!*end) { 00185 start = end; 00186 continue; /* Always check for the end. */ 00187 } 00188 if (size_left > 0) 00189 *np++ = '\0'; /* NULL terminate it. */ 00190 DEBUG(5,("End of second in pair '%s'\n", end)); 00191 new_string[sizeof(new_string)-1] = '\0'; 00192 pstrcpy( s, new_string ); /* Substitute with the new name. */ 00193 DEBUG( 5, ("s is now '%s'\n", s) ); 00194 } 00195 start = end; /* Skip a bit which cannot be wanted anymore. */ 00196 start++; 00197 } 00198 } 00199 00200 /* 00201 front end routine to the mangled map code 00202 personally I think that the whole idea of "mangled map" is completely bogus 00203 */ 00204 void mangle_map_filename(fstring fname, const struct share_params *p) 00205 { 00206 char *map; 00207 00208 map = lp_mangled_map(p); 00209 if (!map || !*map) return; 00210 00211 mangled_map(fname, map); 00212 }