mirror of
https://github.com/samba-team/samba.git
synced 2025-03-05 20:58:40 +03:00
Fix for deleting directories that contain only veto files.
Needed for interoperability with netatalk volumes. Jeremy (jallison@whistle.com) (This used to be commit e72a8513bccf77177f6fb6002057fee608947a32)
This commit is contained in:
parent
751eb54b6b
commit
f6384eca67
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user