extern fstring remote_machine;
extern BOOL use_mangled_map;
+static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache);
+
/****************************************************************************
Check if two filenames are equal.
This needs to be careful about whether we are case sensitive.
****************************************************************************/
-
-BOOL fname_equal(char *name1, char *name2)
+static BOOL fname_equal(char *name1, char *name2)
{
int l1 = strlen(name1);
int l2 = strlen(name2);
/****************************************************************************
Mangle the 2nd name and check if it is then equal to the first name.
****************************************************************************/
-
-BOOL mangled_equal(char *name1, char *name2)
+static BOOL mangled_equal(char *name1, char *name2)
{
pstring tmpname;
return(False);
pstrcpy(tmpname,name2);
- mangle_name_83(tmpname,sizeof(tmpname));
+ mangle_name_83(tmpname);
return(strequal(name1,tmpname));
}
static ubi_dlList stat_cache = { NULL, (ubi_dlNodePtr)&stat_cache, 0};
-/****************************************************************************
- Compare two names in the stat cache - to check if we already have such an
- entry.
-*****************************************************************************/
-
-static BOOL stat_name_equal( char *s1, char *s2)
-{
- return (case_sensitive ? (strcmp( s1, s2) == 0) : (StrCaseCmp(s1, s2) == 0));
-}
-
/****************************************************************************
Compare a pathname to a name in the stat cache - of a given length.
Note - this code always checks that the next character in the pathname
is either a '/' character, or a '\0' character - to ensure we only
- match *full* pathname components.
+ match *full* pathname components. Note we don't need to handle case
+ here, if we're case insensitive the stat cache orig names are all upper
+ case.
*****************************************************************************/
static BOOL stat_name_equal_len( char *stat_name, char *orig_name, int len)
{
- BOOL matched = (case_sensitive ? (strncmp( stat_name, orig_name, len) == 0) :
- (StrnCaseCmp(stat_name, orig_name, len) == 0));
+ BOOL matched = (memcmp( stat_name, orig_name, len) == 0);
if(orig_name[len] != '/' && orig_name[len] != '\0')
return False;
stat_cache_entry *scp;
pstring orig_name;
pstring translated_path;
- int namelen = strlen(orig_translated_path);
+ int namelen;
+
+ if (!lp_stat_cache()) return;
+
+ namelen = strlen(orig_translated_path);
/*
* Don't cache trivial valid directory entries.
*/
- if(strequal(full_orig_name, ".") || strequal(full_orig_name, ".."))
+ if((*full_orig_name == '\0') || (strcmp(full_orig_name, ".") == 0) ||
+ (strcmp(full_orig_name, "..") == 0))
return;
/*
*/
StrnCpy(orig_name, full_orig_name, namelen);
+ if(!case_sensitive)
+ strupper( orig_name );
/*
* Check this name doesn't exist in the cache before we
for( scp = (stat_cache_entry *)ubi_dlFirst( &stat_cache); scp;
scp = (stat_cache_entry *)ubi_dlNext( scp )) {
- if(stat_name_equal( scp->orig_name, orig_name) &&
+ if((strcmp( scp->orig_name, orig_name) == 0) &&
(strcmp( scp->translated_name, translated_path) == 0)) {
/*
* Name does exist - promote it.
Return True if we translated (and did a scuccessful stat on) the entire name.
*****************************************************************************/
-static BOOL stat_cache_lookup( char *name, char *dirpath, char **start, struct stat *pst)
+static BOOL stat_cache_lookup( char *name, char *dirpath, char **start, SMB_STRUCT_STAT *pst)
{
stat_cache_entry *scp;
stat_cache_entry *longest_hit = NULL;
- int namelen = strlen(name);
+ pstring chk_name;
+ int namelen;
+
+ if (!lp_stat_cache()) return False;
+ namelen = strlen(name);
+
*start = name;
global_stat_cache_lookups++;
/*
* Don't lookup trivial valid directory entries.
*/
- if(strequal(name, ".") || strequal(name, "..")) {
+ if((*name == '\0') || (strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) {
global_stat_cache_misses++;
return False;
}
+ pstrcpy(chk_name, name);
+ if(!case_sensitive)
+ strupper( chk_name );
+
for( scp = (stat_cache_entry *)ubi_dlFirst( &stat_cache); scp;
scp = (stat_cache_entry *)ubi_dlNext( scp )) {
if(scp->name_len <= namelen) {
- if(stat_name_equal_len(scp->orig_name, name, scp->name_len)) {
+ if(stat_name_equal_len(scp->orig_name, chk_name, scp->name_len)) {
if((longest_hit == NULL) || (longest_hit->name_len <= scp->name_len))
longest_hit = scp;
}
* and then promote it to the top.
*/
- if(sys_stat( longest_hit->translated_name, pst) != 0) {
+ if(dos_stat( longest_hit->translated_name, pst) != 0) {
/*
* Discard this entry.
*/
****************************************************************************/
BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
- BOOL *bad_path, struct stat *pst)
+ BOOL *bad_path, SMB_STRUCT_STAT *pst)
{
- struct stat st;
+ SMB_STRUCT_STAT st;
char *start, *end, *orig_start;
pstring dirpath;
pstring orig_path;
int saved_errno;
BOOL component_was_mangled = False;
BOOL name_has_wildcard = False;
+#if 0
+ /* Andrew's conservative code... JRA. */
+ extern char magic_char;
+#endif
*dirpath = 0;
*bad_path = False;
- if(pst)
- memset( (char *)pst, '\0', sizeof(struct stat));
+ if(pst) {
+ ZERO_STRUCTP(pst);
+ }
if(saved_last_component)
*saved_last_component = 0;
trim_string(name,"/","/");
+ /*
+ * If we trimmed down to a single '\0' character
+ * then we should use the "." directory to avoid
+ * searching the cache.
+ */
+
+ if(!*name) {
+ name[0] = '.';
+ name[1] = '\0';
+ }
+
/*
* Ensure saved_last_component is valid even if file exists.
*/
* stat the name - if it exists then we are all done!
*/
- if (sys_stat(name,&st) == 0) {
+ if (dos_stat(name,&st) == 0) {
stat_cache_add(orig_path, name);
DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
if(pst)
if(strchr(start,'?') || strchr(start,'*'))
name_has_wildcard = True;
+ /*
+ * is_mangled() was changed to look at an entire pathname, not
+ * just a component. JRA.
+ */
+
+ if(is_mangled(start))
+ component_was_mangled = True;
+
+#if 0
+ /* Keep Andrew's conservative code around, just in case. JRA. */
+ /* this is an extremely conservative test for mangled names. */
+ if (strchr(start,magic_char))
+ component_was_mangled = True;
+#endif
+
/*
* Now we need to recursively match the name against the real
* directory structure.
/*
* Check if the name exists up to this point.
*/
- if (sys_stat(name, &st) == 0) {
+ if (dos_stat(name, &st) == 0) {
/*
* It exists. it must either be a directory or this must be
* the last part of the path for it to be OK.
*/
if (is_mangled(start)) {
- component_was_mangled = True;
check_mangled_cache( start );
}
#ifdef S_ISLNK
if (!lp_symlinks(SNUM(conn)))
{
- struct stat statbuf;
- if ( (sys_lstat(name,&statbuf) != -1) &&
+ SMB_STRUCT_STAT statbuf;
+ if ( (dos_lstat(name,&statbuf) != -1) &&
(S_ISLNK(statbuf.st_mode)) )
{
DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
If the name looks like a mangled name then try via the mangling functions
****************************************************************************/
-BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache)
+static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache)
{
void *cur_dir;
char *dname;