Compare commits

...

6 Commits

Author SHA1 Message Date
ed
feb1acd43a v1.3.3 2022-06-27 22:57:05 +02:00
ed
a9591db734 cleanup 2022-06-27 22:56:29 +02:00
ed
9ebf148cbe support android9 sdcardfs on sdcard 2022-06-27 22:15:35 +02:00
ed
a473e5e19a always include custom css/js 2022-06-27 17:24:30 +02:00
ed
5d3034c231 detect sparse support from st_blocks 2022-06-23 18:23:42 +02:00
ed
c3a895af64 android sdcardfs can be fat32 2022-06-23 16:27:30 +02:00
6 changed files with 87 additions and 48 deletions

View File

@@ -481,7 +481,6 @@ def run_argparse(argv: list[str], formatter: Any) -> argparse.Namespace:
ap2.add_argument("--hardlink", action="store_true", help="prefer hardlinks instead of symlinks when possible (within same filesystem)")
ap2.add_argument("--never-symlink", action="store_true", help="do not fallback to symlinks when a hardlink cannot be made")
ap2.add_argument("--no-dedup", action="store_true", help="disable symlink/hardlink creation; copy file contents instead")
ap2.add_argument("--thickfs", metavar="REGEX", type=u, default="fat|vfat|ex.?fat|hpfs|fuse", help="filesystems which dont support sparse files")
ap2.add_argument("--sparse", metavar="MiB", type=int, default=4, help="windows-only: minimum size of incoming uploads through up2k before they are made into sparse files")
ap2.add_argument("--turbo", metavar="LVL", type=int, default=0, help="configure turbo-mode in up2k client; 0 = off and warn if enabled, 1 = off, 2 = on, 3 = on and disable datecheck")

View File

@@ -1,8 +1,8 @@
# coding: utf-8
VERSION = (1, 3, 2)
VERSION = (1, 3, 3)
CODENAME = "god dag"
BUILD_DT = (2022, 6, 20)
BUILD_DT = (2022, 6, 27)
S_VERSION = ".".join(map(str, VERSION))
S_BUILD_DT = "{0:04d}-{1:02d}-{2:02d}".format(*BUILD_DT)

View File

@@ -10,7 +10,7 @@ from .authsrv import AXS, VFS
from .util import chkcmd, min_ex
try:
from typing import Optional, Union
from typing import Any, Optional, Union
from .util import RootLogger
except:
@@ -28,8 +28,8 @@ class Fstab(object):
def log(self, msg: str, c: Union[int, str] = 0) -> None:
self.log_func("fstab", msg + "\033[K", c)
def get(self, path: str):
if time.time() - self.age > 600 or len(self.cache) > 9000:
def get(self, path: str) -> str:
if len(self.cache) > 9000:
self.age = time.time()
self.tab = None
self.cache = {}
@@ -64,7 +64,7 @@ class Fstab(object):
self.log("found {} at {}".format(fs, path))
return fs
def build_tab(self):
def build_tab(self) -> None:
self.log("building tab")
sptn = r"^.*? on (.*) type ([^ ]+) \(.*"
@@ -79,7 +79,8 @@ class Fstab(object):
if not m:
continue
tab1.append(m.groups())
zs1, zs2 = m.groups()
tab1.append((str(zs1), str(zs2)))
tab1.sort(key=lambda x: (len(x[0]), x[0]))
path1, fs1 = tab1[0]
@@ -89,18 +90,30 @@ class Fstab(object):
self.tab = tab
def get_unix(self, path: str):
def relabel(self, path: str, nval: str) -> None:
assert self.tab
ptn = re.compile(r"^[^\\/]*")
vn, _ = self.tab._find(path)
visit = [vn]
while visit:
vn = visit.pop()
vn.realpath = ptn.sub(nval, vn.realpath)
visit.extend(list(vn.nodes.values()))
self.cache = {}
def get_unix(self, path: str) -> str:
if not self.tab:
self.build_tab()
assert self.tab
return self.tab._find(path)[0].realpath.split("/")[0]
def get_w32(self, path: str):
def get_w32(self, path: str) -> str:
# list mountpoints: fsutil fsinfo drives
from ctypes.wintypes import BOOL, DWORD, LPCWSTR, LPDWORD, LPWSTR, MAX_PATH
def echk(rc, fun, args):
def echk(rc: int, fun: Any, args: Any) -> None:
if not rc:
raise ctypes.WinError(ctypes.get_last_error())
return None

View File

@@ -2403,6 +2403,16 @@ class HttpCli(object):
"themes": self.args.themes,
"turbolvl": self.args.turbo,
}
if self.args.js_browser:
j2a["js"] = self.args.js_browser
if self.args.css_browser:
j2a["css"] = self.args.css_browser
if not self.conn.hsrv.prism:
j2a["no_prism"] = True
if not self.can_read:
if is_ls:
return self.tx_ls(ls_ret)
@@ -2602,9 +2612,6 @@ class HttpCli(object):
if doctxt is not None:
j2a["doc"] = doctxt
if not self.conn.hsrv.prism:
j2a["no_prism"] = True
for d in dirs:
d["name"] += "/"
@@ -2616,19 +2623,12 @@ class HttpCli(object):
else:
j2a["files"] = dirs + files
j2a["logues"] = logues
j2a["taglist"] = taglist
j2a["txt_ext"] = self.args.textfiles.replace(",", " ")
if "mth" in vn.flags:
j2a["def_hcols"] = vn.flags["mth"].split(",")
if self.args.js_browser:
j2a["js"] = self.args.js_browser
if self.args.css_browser:
j2a["css"] = self.args.css_browser
html = self.j2s(tpl, **j2a)
self.reply(html.encode("utf-8", "replace"))
return True

View File

@@ -132,7 +132,6 @@ class Up2k(object):
thr.start()
self.fstab = Fstab(self.log_func)
self.no_sparse = re.compile(self.args.thickfs)
if self.args.no_fastboot:
self.deferred_init()
@@ -1327,7 +1326,7 @@ class Up2k(object):
# check if filesystem supports sparse files;
# refuse out-of-order / multithreaded uploading if sprs False
sprs = not self.no_sparse.match(self.fstab.get(pdir))
sprs = self.fstab.get(pdir) != "ng"
with self.mutex:
cur = self.cur.get(cj["ptop"])
@@ -2214,31 +2213,49 @@ class Up2k(object):
dip = job["addr"].replace(":", ".")
suffix = "-{:.6f}-{}".format(job["t0"], dip)
t0 = time.time()
with ren_open(tnam, "wb", fdir=pdir, suffix=suffix) as zfw:
f, job["tnam"] = zfw["orz"]
abspath = os.path.join(pdir, job["tnam"])
sprs = job["sprs"]
sz = job["size"]
relabel = False
if (
ANYWIN
and job["sprs"]
and sprs
and self.args.sparse
and self.args.sparse * 1024 * 1024 <= job["size"]
and self.args.sparse * 1024 * 1024 <= sz
):
fp = os.path.join(pdir, job["tnam"])
try:
sp.check_call(["fsutil", "sparse", "setflag", fp])
sp.check_call(["fsutil", "sparse", "setflag", abspath])
except:
self.log("could not sparse [{}]".format(fp), 3)
self.log("could not sparse [{}]".format(abspath), 3)
relabel = True
sprs = False
if job["hash"] and job["sprs"]:
f.seek(job["size"] - 1)
if not ANYWIN and sprs and sz > 1024 * 1024:
fs = self.fstab.get(pdir)
if fs != "ok":
relabel = True
f.seek(1024 * 1024 - 1)
f.write(b"e")
f.flush()
try:
nblk = bos.stat(abspath).st_blocks
sprs = nblk < 2048
except:
sprs = False
if relabel:
t = "sparse files {} on {} filesystem at {}"
nv = "ok" if sprs else "ng"
self.log(t.format(nv, self.fstab.get(pdir), pdir))
self.fstab.relabel(pdir, nv)
job["sprs"] = sprs
if job["hash"] and sprs:
f.seek(sz - 1)
f.write(b"e")
td = time.time() - t0
if td > 3 and not ANYWIN:
t = "WARNING: filesystem [{}] at [{}] probably does support sparse files; adjust the list in --thickfs and maybe create a github issue (please mention the filesystem + any related info about your setup if you do)"
fs = self.fstab.get(pdir)
self.log(t.format(fs, pdir), 1)
if not job["hash"]:
self._finish_upload(job["ptop"], job["wark"])

View File

@@ -589,6 +589,7 @@ def ren_open(
ext = bname[ofs:] + ext
bname = bname[:ofs]
asciified = False
b64 = ""
while True:
try:
@@ -614,11 +615,20 @@ def ren_open(
except OSError as ex_:
ex = ex_
if ex.errno == 22 and not asciified:
asciified = True
bname, fname = [
zs.encode("ascii", "replace").decode("ascii").replace("?", "_")
for zs in [bname, fname]
]
continue
if ex.errno not in [36, 63] and (not WINDOWS or ex.errno != 22):
raise
if not b64:
zs = (bname + ext).encode("utf-8", "replace")
zs = (orig_name + "\n" + suffix).encode("utf-8", "replace")
zs = hashlib.sha512(zs).digest()[:12]
b64 = base64.urlsafe_b64encode(zs).decode("utf-8")
@@ -1695,16 +1705,16 @@ def termsize() -> tuple[int, int]:
# from hashwalk
env = os.environ
def ioctl_GWINSZ(fd):
def ioctl_GWINSZ(fd: int) -> Optional[tuple[int, int]]:
try:
import fcntl
import struct
import termios
cr = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234"))
cr = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, b"1234"))
return int(cr[1]), int(cr[0])
except:
return
return cr
return None
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
@@ -1715,13 +1725,13 @@ def termsize() -> tuple[int, int]:
except:
pass
if not cr:
try:
cr = (env["LINES"], env["COLUMNS"])
except:
cr = (25, 80)
if cr:
return cr
return int(cr[1]), int(cr[0])
try:
return int(env["COLUMNS"]), int(env["LINES"])
except:
return 80, 25
class Pebkac(Exception):