Fix for deleting directories that contain only veto files.
authorSamba Release Account <samba-bugs@samba.org>
Thu, 3 Jul 1997 19:44:06 +0000 (19:44 +0000)
committerSamba Release Account <samba-bugs@samba.org>
Thu, 3 Jul 1997 19:44:06 +0000 (19:44 +0000)
Needed for interoperability with netatalk volumes.
Jeremy (jallison@whistle.com)
(This used to be commit e72a8513bccf77177f6fb6002057fee608947a32)

source3/include/proto.h
source3/smbd/chgpasswd.c
source3/smbd/dir.c
source3/smbd/reply.c
source3/smbd/server.c

index 3929348da6dcf8381cc5ff2bbccd7dc05edfff17..ef9382279e3a5d25344ca6732828389a425c32df 100644 (file)
@@ -79,7 +79,7 @@ void *dptr_fetch(char *buf,int *num);
 void *dptr_fetch_lanman2(char *params,int dptr_num);
 BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype);
 BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend);
-void *OpenDir(char *name);
+void *OpenDir(char *name, BOOL use_veto);
 void CloseDir(void *p);
 char *ReadDirName(void *p);
 BOOL SeekDir(void *p,int pos);
index 883ad5214a8c64a4090f91c8a2b16130fa976993..e0dd7fc0aeaebf8b98e1e4fa0fe34a7c071fe2d2 100644 (file)
@@ -56,7 +56,7 @@ static int findpty(char **slave)
 #else
   strcpy( line, "/dev/ptyXX" );
 
-  dirp = OpenDir("/dev");
+  dirp = OpenDir("/dev", True);
   if (!dirp) return(-1);
   while ((dpname = ReadDirName(dirp)) != NULL) {
     if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
index bc099dd1e8f3c95246448c7df963696371fa2d72..1d0228864cc2c71fc0eb8bab049bf4b81c023ff3 100644 (file)
@@ -116,7 +116,7 @@ static void *dptr_get(int key,uint32 lastused)
       if (dptrs_open >= MAXDIR)
        dptr_idleoldest();
       DEBUG(4,("Reopening dptr key %d\n",key));
-      if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path)))
+      if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path, True)))
        dptrs_open++;
     }
     return(dirptrs[key].ptr);
@@ -259,7 +259,7 @@ static BOOL start_dir(int cnum,char *directory)
   if (! *directory)
     directory = ".";
 
-  Connections[cnum].dirptr = OpenDir(directory);
+  Connections[cnum].dirptr = OpenDir(directory, True);
   if (Connections[cnum].dirptr) {    
     dptrs_open++;
     string_set(&Connections[cnum].dirpath,directory);
@@ -520,7 +520,7 @@ typedef struct
 /*******************************************************************
 open a directory
 ********************************************************************/
-void *OpenDir(char *name)
+void *OpenDir(char *name, BOOL use_veto)
 {
   Dir *dirp;
   char *n;
@@ -539,7 +539,7 @@ void *OpenDir(char *name)
   while ((n = readdirname(p))) {
     int l = strlen(n)+1;
     /* If it's a vetoed file, pretend it doesn't even exist */
-    if(is_vetoed_name(n))
+    if(use_veto && is_vetoed_name(n))
       continue;
     if (used + l > dirp->mallocsize) {
       int s = MAX(used+l,used+2000);
index 8af4536c1959ccbc67d9809d8bde5535a78a1f77..5f030d537241a6250f769709787400a031138b13 100644 (file)
@@ -1326,7 +1326,7 @@ int reply_unlink(char *inbuf,char *outbuf)
     char *dname;
 
     if (check_name(directory,cnum))
-      dirptr = OpenDir(directory);
+      dirptr = OpenDir(directory, True);
 
     /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
        the pattern matches against the long name, otherwise the short name 
@@ -2449,10 +2449,76 @@ int reply_rmdir(char *inbuf,char *outbuf)
   
   if (check_name(directory,cnum))
     {
+
       dptr_closepath(directory,SVAL(inbuf,smb_pid));
       ok = (sys_rmdir(directory) == 0);
+      if(!ok && (errno == ENOTEMPTY) && lp_veto_files())
+        {
+          /* Check to see if the only thing in this directory are
+             vetoed files/directories. If so then delete them and
+             retry. If we fail to delete any of them (and we *don't*
+             do a recursive delete) then fail the rmdir. */
+          BOOL all_veto_files = True;
+          char *dname;
+          void *dirptr = OpenDir(directory, False);
+
+          if(dirptr != NULL)
+            {
+              int dirpos = TellDir(dirptr);
+                 while ((dname = ReadDirName(dirptr)))
+                   {
+                  if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+                    continue;
+                  if(!is_vetoed_name(dname))
+                    {
+                      all_veto_files = False;
+                      break;
+                    }
+                }
+              if(all_veto_files)
+                {
+                  SeekDir(dirptr,dirpos);
+                  while ((dname = ReadDirName(dirptr)))
+                    {
+                      pstring fullname;
+                      struct stat st;
+
+                      if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+                        continue;
+
+                      /* Construct the full name. */
+                      if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
+                        {
+                          errno = ENOMEM;
+                          break;
+                        }
+                      strcpy(fullname, directory);
+                      strcat(fullname, "/");
+                      strcat(fullname, dname);
+                      
+                      if(sys_lstat(fullname, &st) != 0)
+                        break;
+                      if(st.st_mode & S_IFDIR)
+                        {
+                          if(sys_rmdir(fullname) != 0)
+                            break;
+                        }
+                      else if(sys_unlink(fullname) != 0)
+                        break;
+                    }
+                  CloseDir(dirptr);
+                  /* Retry the rmdir */
+                  ok = (sys_rmdir(directory) == 0);
+                }
+              else
+                CloseDir(dirptr);
+            }
+          else
+            errno = ENOTEMPTY;
+         }
+          
       if (!ok)
-       DEBUG(3,("couldn't remove directory %s : %s\n",
+        DEBUG(3,("couldn't remove directory %s : %s\n",
                 directory,strerror(errno)));
     }
   
@@ -2670,7 +2736,7 @@ int reply_mv(char *inbuf,char *outbuf)
     pstring destname;
 
     if (check_name(directory,cnum))
-      dirptr = OpenDir(directory);
+      dirptr = OpenDir(directory, True);
 
     if (dirptr)
       {
@@ -2861,7 +2927,7 @@ int reply_copy(char *inbuf,char *outbuf)
     pstring destname;
 
     if (check_name(directory,cnum))
-      dirptr = OpenDir(directory);
+      dirptr = OpenDir(directory, True);
 
     if (dirptr)
       {
index 8c40734ce42e264c260d63eceb48651defa70995..30d8ce3d2a3caa255842f1ddace5351ab50f0ee8 100644 (file)
@@ -361,7 +361,7 @@ static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
     check_mangled_stack(name);
 
   /* open the directory */
-  if (!(cur_dir = OpenDir(path))) 
+  if (!(cur_dir = OpenDir(path, True))) 
     {
       DEBUG(3,("scan dir didn't open dir [%s]\n",path));
       return(False);