local.h: Removed ununsed SHARE_MODES_XXX defines. Upped SMBD_RELOAD_CHECK
[kai/samba.git] / source3 / lib / util.c
index 889aa0b976baf1b664cb4073f8976c25877d7cb7..9d6229dbf96d373f9f1fb2229e6ef037b4e9c25b 100644 (file)
@@ -800,12 +800,15 @@ char *attrib_string(int mode)
 int StrCaseCmp(const char *s, const char *t)
 {
   /* compare until we run out of string, either t or s, or find a difference */
-  while (*s && *t && tolower(*s) == tolower(*t))
+  /* We *must* use toupper rather than tolower here due to the
+     asynchronous upper to lower mapping.
+   */
+  while (*s && *t && toupper(*s) == toupper(*t))
   {
     s++; t++;
   }
 
-  return(tolower(*s) - tolower(*t));
+  return(toupper(*s) - toupper(*t));
 }
 
 /*******************************************************************
@@ -814,13 +817,16 @@ int StrCaseCmp(const char *s, const char *t)
 int StrnCaseCmp(const char *s, const char *t, int n)
 {
   /* compare until we run out of string, either t or s, or chars */
-  while (n-- && *s && *t && tolower(*s) == tolower(*t))
+  /* We *must* use toupper rather than tolower here due to the
+     asynchronous upper to lower mapping.
+   */
+  while (n-- && *s && *t && toupper(*s) == toupper(*t))
   {
     s++; t++;
   }
 
   /* not run out of chars - strings are different lengths */
-  if (n) return(tolower(*s) - tolower(*t));
+  if (n) return(toupper(*s) - toupper(*t));
 
   /* identical up to where we run out of chars, and strings are same length */
   return(0);
@@ -989,6 +995,7 @@ void dos_format(char *fname)
 void show_msg(char *buf)
 {
   int i;
+  int j;
   int bcc=0;
   if (DEBUGLEVEL < 5)
     return;
@@ -1014,9 +1021,28 @@ void show_msg(char *buf)
   DEBUG(5,("smb_bcc=%d\n",bcc));
   if (DEBUGLEVEL < 10)
     return;
-  for (i=0;i<MIN(bcc,128);i++)
-    DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
-  DEBUG(10,("\n"));  
+  for (i = 0; i < MIN(bcc, 256); i += 16)
+  {
+    for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
+    {
+
+      DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j)));
+      if (j == 7) DEBUG(10, ("  "));
+
+    }
+    DEBUG(10,("  "));  
+
+    for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
+    {
+      unsigned char c = CVAL(smb_buf(buf),i+j);
+      if (c < 32 || c > 128) c = '.';
+      DEBUG(10,("%c",c));
+
+      if (j == 7) DEBUG(10, ("  "));
+    }
+
+    DEBUG(10,("\n"));  
+  }
 }
 
 /*******************************************************************
@@ -3397,13 +3423,6 @@ char *readdirname(void *p)
 
   dname = ptr->d_name;
 
-  {
-    static pstring buf;
-    strcpy(buf, dname);
-    unix_to_dos(buf, True);
-    dname = buf;
-  }
-
 #ifdef NEXT2
   if (telldir(p) < 0) return(NULL);
 #endif
@@ -3419,122 +3438,118 @@ char *readdirname(void *p)
        broken_readdir = True;
       }
     if (broken_readdir)
-      return(dname-2);
+      dname = dname - 2;
   }
 #endif
 
+  {
+    static pstring buf;
+    strcpy(buf, dname);
+    unix_to_dos(buf, True);
+    dname = buf;
+  }
+
   return(dname);
 }
 
+/*
+ * Utility function used by is_hidden_path() and is_vetoed_name()
+ * to decide if the last component of a path matches a (possibly
+ * wildcarded) entry in a namelist.
+ */
 
-BOOL is_vetoed_name(char *name)
+static BOOL is_in_path(char *name, char *namelist)
 {
-  char *namelist = lp_veto_files();
+  pstring last_component;
+  char *p;
   char *nameptr = namelist;
   char *name_end;
 
-  /* if we have no list it's obviously not vetoed */
-  if((nameptr == NULL ) || (*nameptr == '\0')) 
-    return 0;
+  DEBUG(5, ("is_in_path: %s list: %s\n", name, namelist));
 
-  /* if the name doesn't exist in the list, it's obviously ok too */
-  if(strstr(namelist,name) == NULL ) 
-    return 0;
+  /* if we have no list it's obviously not in the path */
+  if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
+  {
+    DEBUG(5,("is_in_path: no name list.  return False\n"));
+    return False;
+  }
+
+  /* Get the last component of the unix name. */
+  p = strrchr(name, '/');
+  strncpy(last_component, p ? p : name, sizeof(last_component)-1);
+  last_component[sizeof(last_component)-1] = '\0'; 
 
   /* now, we need to find the names one by one and check them
      they can contain spaces and all sorts of stuff so we
-     separate them with of all things '/' which can never be in a filename
+     separate them with of all things '\' which can never be in a filename
      I could use "" but then I have to break them all out
      maybe such a routine exists somewhere?
   */
-  while(*nameptr) 
-    {
-      if ( *nameptr == '/' ) 
-        {
-          nameptr++;
-          continue;
-        }
-      if((name_end = strchr(nameptr,'/'))!=NULL) 
-        {
-          *name_end = 0;
-        }
-      /* a match! it's veto'd */
-      if(strcmp(name,nameptr) == 0) 
-        return 1;
-      if(name_end == NULL) 
-        return 0;
-      /* next segment please */
-      nameptr = name_end + 1;
-    }
-  return 0;
-}
+  /* lkcl 03jul97 - the separator character used to be a '/'.
+     i changed it to a '\', after examining the code, and seeing
+     that unix_convert is called before check_path and dos_mode.
+     unix_convert changes, in the path, all dos '\'s to unix '/'s.
 
-static BOOL is_in_path(char *name, char *namelist)
-{
-  char *nameptr = namelist;
-  char *sub;
-  char *name_end;
-  int len;
+     the alternatives are:
 
-  /* if we have no list it's obviously not vetoed */
-  if((nameptr == NULL ) || (*nameptr == '\0')) 
-    return 0;
+     1) move all check_path and dos_mode calls to before the
+        unix_convert calls.
 
+     2) have a corresponding dos_convert call, which can be used
+        in here to reverse '/'s into '\'s and vice-versa.  users
+        would specify the lp_veto_files and lp_hide_files parameters
+        in dos mode path format ('\' for directory separator), with a
+        list separator of '/', and they would be swapped inside this
+        function, before making the search.
 
-  /* now, we need to find the names one by one and check them
-     they can contain spaces and all sorts of stuff so we
-     separate them with of all things '/' which can never be in a filename
-     I could use "" but then I have to break them all out
-     maybe such a routine exists somewhere?
-  */
-  while(*nameptr) 
+   */
+
+  while (*nameptr) 
     {
       if ( *nameptr == '/' ) 
-        {
+      {
+          /* cope with multiple (useless) /s) */
           nameptr++;
           continue;
-        }
-      if((name_end = strchr(nameptr,'/'))!=NULL) 
-        {
+      }
+      /* find the next / */
+      if ((name_end = strchr(nameptr,'/')) != NULL) 
+      {
           *name_end = 0;
-        }
-
-      len = strlen(nameptr);
-      sub = name;
-      /* If the name doesn't exist in the path, try the next name.. */
-      while( sub && ((sub = strstr(sub,nameptr)) != NULL)) 
-        {
-           /* Is it a whole component? */
-           if(((sub == name) || (sub[-1] == '/'))
-                && ((sub[len] == '\0') || (sub[len] == '/'))) 
-             {
-               return 1;
-             }
-           /* skip to the next component of the path */
-              sub =strchr(sub,'/');
-         }
-      if(name_end == NULL) 
-        return 0;
+      }
+
+      /* look for a match. */
+      if (mask_match(last_component, nameptr, case_sensitive, False))
+      {
+         DEBUG(5,("is_in_path: mask match succeeded\n"));
+         return True;
+      }
+
+      /* oops - the last check for a / didn't find one. */
+      if (name_end == NULL)
+      {
+         DEBUG(5,("is_in_path: last name.  failed\n"));
+         return False;
+      }
+
       /* next segment please */
       nameptr = name_end + 1;
     }
-  return 0;
+  
+  DEBUG(5,("is_in_path: not found\n"));
+
+  return False;
 }
 
-/****************************************************************************
-used to make files hidden, but still accessible
-****************************************************************************/
-BOOL is_hidden_path(char *path)
+BOOL is_hidden_path(int snum, char *name)
 {
-  return is_in_path(path, lp_hide_files());
+   return is_in_path(name, lp_hide_files(snum));
 }
 
-/****************************************************************************
-used to make files _completely_ inaccessible
-****************************************************************************/
-BOOL is_vetoed_path(char *path)
+BOOL is_vetoed_name(int snum, char *name)
 {
-  return is_in_path(path, lp_veto_files());
+   return is_in_path(name, lp_veto_files(snum));
 }
 
 /****************************************************************************