mirror of
https://github.com/9001/copyparty.git
synced 2025-09-28 12:42:26 -06:00
clamp utime to filesystem limits (#539)
This commit is contained in:
parent
e6755aa8a1
commit
eeb7738b53
|
@ -2,18 +2,22 @@
|
||||||
from __future__ import print_function, unicode_literals
|
from __future__ import print_function, unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
from ..util import SYMTIME, fsdec, fsenc
|
from ..util import SYMTIME, fsdec, fsenc
|
||||||
from . import path as path
|
from . import path as path
|
||||||
|
|
||||||
if True: # pylint: disable=using-constant-test
|
if True: # pylint: disable=using-constant-test
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional, Union
|
||||||
|
|
||||||
|
from ..util import NamedLogger
|
||||||
|
|
||||||
MKD_755 = {"chmod_d": 0o755}
|
MKD_755 = {"chmod_d": 0o755}
|
||||||
MKD_700 = {"chmod_d": 0o700}
|
MKD_700 = {"chmod_d": 0o700}
|
||||||
|
UTIME_CLAMPS = ((max, -2147483647), (max, 1), (min, 4294967294), (min, 2147483646))
|
||||||
|
|
||||||
_ = (path, MKD_755, MKD_700)
|
_ = (path, MKD_755, MKD_700, UTIME_CLAMPS)
|
||||||
__all__ = ["path", "MKD_755", "MKD_700"]
|
__all__ = ["path", "MKD_755", "MKD_700", "UTIME_CLAMPS"]
|
||||||
|
|
||||||
# grep -hRiE '(^|[^a-zA-Z_\.-])os\.' . | gsed -r 's/ /\n/g;s/\(/(\n/g' | grep -hRiE '(^|[^a-zA-Z_\.-])os\.' | sort | uniq -c
|
# grep -hRiE '(^|[^a-zA-Z_\.-])os\.' . | gsed -r 's/ /\n/g;s/\(/(\n/g' | grep -hRiE '(^|[^a-zA-Z_\.-])os\.' | sort | uniq -c
|
||||||
# printf 'os\.(%s)' "$(grep ^def bos/__init__.py | gsed -r 's/^def //;s/\(.*//' | tr '\n' '|' | gsed -r 's/.$//')"
|
# printf 'os\.(%s)' "$(grep ^def bos/__init__.py | gsed -r 's/^def //;s/\(.*//' | tr '\n' '|' | gsed -r 's/.$//')"
|
||||||
|
@ -99,6 +103,40 @@ def utime(
|
||||||
return os.utime(fsenc(p), times)
|
return os.utime(fsenc(p), times)
|
||||||
|
|
||||||
|
|
||||||
|
def utime_c(
|
||||||
|
log: Union["NamedLogger", Any], p: str, ts: int, follow_symlinks: bool = True, throw: bool = False
|
||||||
|
) -> Optional[int]:
|
||||||
|
clamp = 0
|
||||||
|
ov = ts
|
||||||
|
bp = fsenc(p)
|
||||||
|
now = int(time.time())
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
if SYMTIME:
|
||||||
|
os.utime(bp, (now, ts), follow_symlinks=follow_symlinks)
|
||||||
|
else:
|
||||||
|
os.utime(bp, (now, ts))
|
||||||
|
if clamp:
|
||||||
|
t = "filesystem rejected utime(%r); clamped %s to %s"
|
||||||
|
log(t % (p, ov, ts))
|
||||||
|
return ts
|
||||||
|
except Exception as ex:
|
||||||
|
pv = ts
|
||||||
|
while clamp < len(UTIME_CLAMPS):
|
||||||
|
fun, cv = UTIME_CLAMPS[clamp]
|
||||||
|
ts = fun(ts, cv)
|
||||||
|
clamp += 1
|
||||||
|
if ts != pv:
|
||||||
|
break
|
||||||
|
if clamp >= len(UTIME_CLAMPS):
|
||||||
|
if throw:
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
t = "could not utime(%r) to %s; %s, %r"
|
||||||
|
log(t % (p, ov, ex, ex))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
if hasattr(os, "lstat"):
|
if hasattr(os, "lstat"):
|
||||||
|
|
||||||
def lstat(p: str) -> os.stat_result:
|
def lstat(p: str) -> os.stat_result:
|
||||||
|
|
|
@ -409,12 +409,8 @@ class FtpFs(AbstractedFS):
|
||||||
return st
|
return st
|
||||||
|
|
||||||
def utime(self, path: str, timeval: float) -> None:
|
def utime(self, path: str, timeval: float) -> None:
|
||||||
try:
|
ap = self.rv2a(path, w=True)[0]
|
||||||
ap = self.rv2a(path, w=True)[0]
|
bos.utime_c(logging.warning, ap, int(timeval), False)
|
||||||
return bos.utime(ap, (int(time.time()), int(timeval)))
|
|
||||||
except Exception as ex:
|
|
||||||
logging.error("ftp.utime: %s, %r", ex, ex)
|
|
||||||
raise
|
|
||||||
|
|
||||||
def lstat(self, path: str) -> os.stat_result:
|
def lstat(self, path: str) -> os.stat_result:
|
||||||
ap = self.rv2a(path)[0]
|
ap = self.rv2a(path)[0]
|
||||||
|
|
|
@ -2329,12 +2329,7 @@ class HttpCli(object):
|
||||||
at = mt = time.time() - lifetime
|
at = mt = time.time() - lifetime
|
||||||
cli_mt = self.headers.get("x-oc-mtime")
|
cli_mt = self.headers.get("x-oc-mtime")
|
||||||
if cli_mt:
|
if cli_mt:
|
||||||
try:
|
bos.utime_c(self.log, path, int(cli_mt), False)
|
||||||
mt = int(cli_mt)
|
|
||||||
times = (int(time.time()), mt)
|
|
||||||
bos.utime(path, times, False)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if nameless and "magic" in vfs.flags:
|
if nameless and "magic" in vfs.flags:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -373,7 +373,7 @@ class SMB(object):
|
||||||
t = "blocked utime (no-write-acc %s): /%s @%s"
|
t = "blocked utime (no-write-acc %s): /%s @%s"
|
||||||
yeet(t % (vfs.axs.uwrite, vpath, uname))
|
yeet(t % (vfs.axs.uwrite, vpath, uname))
|
||||||
|
|
||||||
return bos.utime(ap, times)
|
bos.utime_c(info, ap, int(times[1]), False)
|
||||||
|
|
||||||
def _p_exists(self, vpath: str) -> bool:
|
def _p_exists(self, vpath: str) -> bool:
|
||||||
# ap = "?"
|
# ap = "?"
|
||||||
|
|
|
@ -3435,10 +3435,9 @@ class Up2k(object):
|
||||||
cur.connection.commit()
|
cur.connection.commit()
|
||||||
|
|
||||||
ap = djoin(job["ptop"], job["prel"], job["name"])
|
ap = djoin(job["ptop"], job["prel"], job["name"])
|
||||||
times = (int(time.time()), int(cj["lmod"]))
|
mt = bos.utime_c(self.log, ap, int(cj["lmod"]), False, True)
|
||||||
bos.utime(ap, times, False)
|
|
||||||
|
|
||||||
self.log("touched %r from %d to %d" % (ap, job["lmod"], cj["lmod"]))
|
self.log("touched %r from %d to %d" % (ap, job["lmod"], mt))
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.log("umod failed, %r" % (ex,), 3)
|
self.log("umod failed, %r" % (ex,), 3)
|
||||||
|
|
||||||
|
@ -3593,8 +3592,7 @@ class Up2k(object):
|
||||||
shutil.copy2(fsenc(csrc), fsenc(dst))
|
shutil.copy2(fsenc(csrc), fsenc(dst))
|
||||||
|
|
||||||
if lmod and (not linked or SYMTIME):
|
if lmod and (not linked or SYMTIME):
|
||||||
times = (int(time.time()), int(lmod))
|
bos.utime_c(self.log, dst, int(lmod), False)
|
||||||
bos.utime(dst, times, False)
|
|
||||||
|
|
||||||
def handle_chunks(
|
def handle_chunks(
|
||||||
self, ptop: str, wark: str, chashes: list[str]
|
self, ptop: str, wark: str, chashes: list[str]
|
||||||
|
@ -3767,10 +3765,8 @@ class Up2k(object):
|
||||||
times = (int(time.time()), int(job["lmod"]))
|
times = (int(time.time()), int(job["lmod"]))
|
||||||
t = "no more chunks, setting times %s (%d) on %r"
|
t = "no more chunks, setting times %s (%d) on %r"
|
||||||
self.log(t % (times, bos.path.getsize(dst), dst))
|
self.log(t % (times, bos.path.getsize(dst), dst))
|
||||||
try:
|
bos.utime_c(self.log, dst, times[1], False)
|
||||||
bos.utime(dst, times)
|
# the above logmsg (and associated logic) is retained due to unforget.py
|
||||||
except:
|
|
||||||
self.log("failed to utime (%r, %s)" % (dst, times))
|
|
||||||
|
|
||||||
zs = "prel name lmod size ptop vtop wark dwrk host user addr"
|
zs = "prel name lmod size ptop vtop wark dwrk host user addr"
|
||||||
z2 = [job[x] for x in zs.split()]
|
z2 = [job[x] for x in zs.split()]
|
||||||
|
@ -4919,7 +4915,10 @@ class Up2k(object):
|
||||||
mt = bos.path.getmtime(slabs, False)
|
mt = bos.path.getmtime(slabs, False)
|
||||||
flags = self.flags.get(ptop) or {}
|
flags = self.flags.get(ptop) or {}
|
||||||
atomic_move(self.log, sabs, slabs, flags)
|
atomic_move(self.log, sabs, slabs, flags)
|
||||||
bos.utime(slabs, (int(time.time()), int(mt)), False)
|
try:
|
||||||
|
bos.utime(slabs, (int(time.time()), int(mt)), False)
|
||||||
|
except:
|
||||||
|
self.log("relink: failed to utime(%r, %s)" % (slabs, mt), 3)
|
||||||
self._symlink(slabs, sabs, flags, False, is_mv=True)
|
self._symlink(slabs, sabs, flags, False, is_mv=True)
|
||||||
full[slabs] = (ptop, rem)
|
full[slabs] = (ptop, rem)
|
||||||
sabs = slabs
|
sabs = slabs
|
||||||
|
|
Loading…
Reference in a new issue