diff -ur samba-2.2.2-ja-0.5.orig/source/include/proto.h samba-2.2.2-ja-0.5/source/include/proto.h --- samba-2.2.2-ja-0.5.orig/source/include/proto.h Thu Nov 1 11:55:44 2001 +++ samba-2.2.2-ja-0.5/source/include/proto.h Mon Nov 26 09:19:50 2001 @@ -1931,6 +1931,7 @@ char *lp_hide_files __P((int)); char *lp_veto_oplocks __P((int)); char *lp_driverlocation __P((int)); +char *lp_recyclebin __P((int)); BOOL lp_msdfs_root __P((int)); BOOL lp_autoloaded __P((int)); BOOL lp_preexec_close __P((int)); diff -ur samba-2.2.2-ja-0.5.orig/source/param/loadparm.c samba-2.2.2-ja-0.5/source/param/loadparm.c --- samba-2.2.2-ja-0.5.orig/source/param/loadparm.c Tue Oct 30 15:28:59 2001 +++ samba-2.2.2-ja-0.5/source/param/loadparm.c Mon Nov 26 09:19:50 2001 @@ -342,6 +342,7 @@ char *printer_admin; char *volume; char *fstype; + char *recycle_bin; char *szVfsObjectFile; char *szVfsOptions; int iMinPrintSpace; @@ -457,6 +458,7 @@ NULL, /* printer admin */ NULL, /* volume */ NULL, /* fstype */ + NULL, /* recycle_bin */ NULL, /* vfs object */ NULL, /* vfs options */ 0, /* iMinPrintSpace */ @@ -1046,6 +1048,7 @@ {N_("panic action"), P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0}, {N_("hide local users"), P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, 0}, + {"recycle bin", P_STRING, P_LOCAL, &sDefault.recycle_bin, NULL, NULL, FLAG_SHARE}, {N_("VFS options"), P_SEP, P_SEPARATOR}, @@ -1673,6 +1676,7 @@ FN_LOCAL_STRING(lp_hide_files, szHideFiles) FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles) FN_LOCAL_STRING(lp_driverlocation, szPrinterDriverLocation) +FN_LOCAL_STRING(lp_recyclebin,recycle_bin) FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot) FN_LOCAL_BOOL(lp_autoloaded, autoloaded) FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose) diff -ur samba-2.2.2-ja-0.5.orig/source/smbd/reply.c samba-2.2.2-ja-0.5/source/smbd/reply.c --- samba-2.2.2-ja-0.5.orig/source/smbd/reply.c Thu Nov 1 11:41:52 2001 +++ samba-2.2.2-ja-0.5/source/smbd/reply.c Mon Nov 26 09:19:50 2001 @@ -1962,6 +1962,64 @@ return(True); } +/******************************************************************** +check if file should be recycled +*********************************************************************/ +static int recycle(connection_struct *conn, char *fname, pstring cvt_buf, char *recycle_bin) +{ + char *base, *ext; + pstring bin; + int i=1, len, addlen; + int dir_mask=0700; + + SMB_BIG_UINT dfree,dsize,bsize; + + if(!recycle_bin || !*recycle_bin) { + DEBUG(3, ("recycle bin: share parameter not set, purging %s...\n", fname)); + return vfs_unlink(conn,fname,cvt_buf); + } + + if(get_file_size(fname) == 0) { + DEBUG(3, ("recycle bin: file %s is empty, purging...\n", fname)); + return vfs_unlink(conn,fname,cvt_buf); + } + + base = strrchr(fname, '/') + 1; + if(base == (char*)1) base = fname; + + ext = strrchr(base, '.'); + + pstrcpy(bin, recycle_bin); + pstrcat(bin, "/"); + pstrcat(bin, base); + + if(strcmp(fname,bin) == 0) { + DEBUG(3, ("recycle bin: file %s exists, purging...\n", fname)); + return vfs_unlink(conn,fname,cvt_buf); + } + + len = strlen(bin); + addlen = sizeof(pstring)-len-1; + while(vfs_file_exist(conn,bin, NULL)) { + slprintf(bin+len, addlen, " (Copy #%d)", i++); + pstrcat(bin, ext); + } + + DEBUG(3, ("recycle bin: moving source=%s to dest=%s\n", fname, bin)); + sys_disk_free(".",True,&bsize,&dfree,&dsize); + if((unsigned int)dfree > 0) { + if(!directory_exist(recycle_bin,NULL)) { + DEBUG(3, ("recycle bin: directory %s nonexistant, creating...\n", recycle_bin)); + vfs_mkdir(conn,recycle_bin,dir_mask); + } + DEBUG(3, ("recycle bin: move successful\n")); + return rename(fname, bin); + } else { + DEBUG(3, ("recycle bin: move failed, purging...\n")); + return vfs_unlink(conn,fname,cvt_buf); + } +} + /**************************************************************************** The guts of the unlink command, split out so it may be called by the NT SMB code. @@ -1973,6 +2031,7 @@ pstring directory; pstring mask; char *p; + char *recycle_bin = lp_recyclebin(SNUM(conn)); int count=0; int error = ERRnoaccess; BOOL has_wild; @@ -2012,7 +2071,7 @@ if (!has_wild) { pstrcat(directory,"/"); pstrcat(directory,mask); - if (can_delete(directory,conn,dirtype) && !vfs_unlink(conn,directory,cvt_buf)) + if (can_delete(directory,conn,dirtype) && !recycle(conn,directory,cvt_buf,recycle_bin)) count++; if (!count) exists = vfs_file_exist(conn,directory,&sbuf); @@ -2045,7 +2104,7 @@ error = ERRnoaccess; slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); if (!can_delete(fname,conn,dirtype)) continue; - if (!vfs_unlink(conn,fname,cvt_buf)) count++; + if (!recycle(conn,fname,cvt_buf,recycle_bin)) count++; DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname)); } CloseDir(dirptr);