mirror of
				https://github.com/9001/copyparty.git
				synced 2025-11-04 05:43:17 +00:00 
			
		
		
		
	shutil: ignore errors from copystat in copy2;
ntfs on linux can be picky about cloning mtime onto a new file;
generally we don't care if that fails, however, we also want the
speedup that CopyFile2 can offer, so cannot use copyfile directly
this avoids the following issue:
up2k:3537 <_symlink>: shutil.copy2(fsenc(csrc), fsenc(dst))
shutil:437 <copy2>: copystat(src, dst, follow_symlinks=follow_sym[...]
shutil:376 <copystat>: lookup("utime")(dst, ns=(st.st_atime_ns, s[...]
[PermissionError] [Errno 1] Operation not permitted, '/windows/videos'
			
			
This commit is contained in:
		@@ -60,6 +60,7 @@ from .util import (
 | 
			
		||||
    sfsenc,
 | 
			
		||||
    spack,
 | 
			
		||||
    statdir,
 | 
			
		||||
    trystat_shutil_copy2,
 | 
			
		||||
    ub64enc,
 | 
			
		||||
    unhumanize,
 | 
			
		||||
    vjoin,
 | 
			
		||||
@@ -2768,7 +2769,7 @@ class Up2k(object):
 | 
			
		||||
        cur.close()
 | 
			
		||||
        db.close()
 | 
			
		||||
 | 
			
		||||
        shutil.copy2(fsenc(db_path), fsenc(bak))
 | 
			
		||||
        trystat_shutil_copy2(self.log, fsenc(db_path), fsenc(bak))
 | 
			
		||||
        return self._orz(db_path)
 | 
			
		||||
 | 
			
		||||
    def _read_ver(self, cur: "sqlite3.Cursor") -> Optional[int]:
 | 
			
		||||
@@ -3591,7 +3592,7 @@ class Up2k(object):
 | 
			
		||||
                t = "BUG: no valid sources to link from! orig(%r) fsrc(%r) link(%r)"
 | 
			
		||||
                self.log(t, 1)
 | 
			
		||||
                raise Exception(t % (src, fsrc, dst))
 | 
			
		||||
            shutil.copy2(fsenc(csrc), fsenc(dst))
 | 
			
		||||
            trystat_shutil_copy2(self.log, fsenc(csrc), fsenc(dst))
 | 
			
		||||
 | 
			
		||||
        if lmod and (not linked or SYMTIME):
 | 
			
		||||
            bos.utime_c(self.log, dst, int(lmod), False)
 | 
			
		||||
@@ -4427,7 +4428,7 @@ class Up2k(object):
 | 
			
		||||
            b1, b2 = fsenc(sabs), fsenc(dabs)
 | 
			
		||||
            is_link = os.path.islink(b1)  # due to _relink
 | 
			
		||||
            try:
 | 
			
		||||
                shutil.copy2(b1, b2)
 | 
			
		||||
                trystat_shutil_copy2(self.log, b1, b2)
 | 
			
		||||
            except:
 | 
			
		||||
                try:
 | 
			
		||||
                    wunlink(self.log, dabs, dvn.flags)
 | 
			
		||||
@@ -4733,7 +4734,7 @@ class Up2k(object):
 | 
			
		||||
            b1, b2 = fsenc(sabs), fsenc(dabs)
 | 
			
		||||
            is_link = os.path.islink(b1)  # due to _relink
 | 
			
		||||
            try:
 | 
			
		||||
                shutil.copy2(b1, b2)
 | 
			
		||||
                trystat_shutil_copy2(self.log, b1, b2)
 | 
			
		||||
            except:
 | 
			
		||||
                try:
 | 
			
		||||
                    wunlink(self.log, dabs, dvn.flags)
 | 
			
		||||
 
 | 
			
		||||
@@ -2639,6 +2639,24 @@ def set_fperms(f: Union[typing.BinaryIO, typing.IO[Any]], vf: dict[str, Any]) ->
 | 
			
		||||
        os.fchown(fno, vf["uid"], vf["gid"])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def trystat_shutil_copy2(log: "NamedLogger", src: bytes, dst: bytes) -> bytes:
 | 
			
		||||
    try:
 | 
			
		||||
        return shutil.copy2(src, dst)
 | 
			
		||||
    except:
 | 
			
		||||
        # ignore failed mtime on linux+ntfs; for example:
 | 
			
		||||
        # shutil.py:437 <copy2>: copystat(src, dst, follow_symlinks=follow_symlinks)
 | 
			
		||||
        # shutil.py:376 <copystat>: lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns),
 | 
			
		||||
        # [PermissionError] [Errno 1] Operation not permitted, '/windows/_videos'
 | 
			
		||||
        _, _, tb = sys.exc_info()
 | 
			
		||||
        for _, _, fun, _ in traceback.extract_tb(tb):
 | 
			
		||||
            if fun == "copystat":
 | 
			
		||||
                if log:
 | 
			
		||||
                    t = "warning: failed to retain some file attributes (timestamp and/or permissions) during copy from %r to %r:\n%s"
 | 
			
		||||
                    log(t % (src, dst, min_ex()), 3)
 | 
			
		||||
                return dst  # close enough
 | 
			
		||||
        raise
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _fs_mvrm(
 | 
			
		||||
    log: "NamedLogger", src: str, dst: str, atomic: bool, flags: dict[str, Any]
 | 
			
		||||
) -> bool:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user