mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
fix mdns on windows
This commit is contained in:
parent
2fbdc0a85e
commit
99efc290df
|
@ -12,11 +12,11 @@ except:
|
||||||
TYPE_CHECKING = False
|
TYPE_CHECKING = False
|
||||||
|
|
||||||
if True:
|
if True:
|
||||||
from typing import Any, Callable, Union
|
from typing import Any, Callable
|
||||||
|
|
||||||
PY2 = sys.version_info < (3,)
|
PY2 = sys.version_info < (3,)
|
||||||
if not PY2:
|
if not PY2:
|
||||||
unicode: Callable[[Union[str, int, float]], str] = str
|
unicode: Callable[[Any], str] = str
|
||||||
else:
|
else:
|
||||||
sys.dont_write_bytecode = True
|
sys.dont_write_bytecode = True
|
||||||
unicode = unicode # noqa: F821 # pylint: disable=undefined-variable,self-assigning-variable
|
unicode = unicode # noqa: F821 # pylint: disable=undefined-variable,self-assigning-variable
|
||||||
|
|
|
@ -666,15 +666,15 @@ def run_argparse(
|
||||||
|
|
||||||
ap2 = ap.add_argument_group("Zeroconf options")
|
ap2 = ap.add_argument_group("Zeroconf options")
|
||||||
ap2.add_argument("-z", action="store_true", help="enable all zeroconf backends (mdns, ssdp)")
|
ap2.add_argument("-z", action="store_true", help="enable all zeroconf backends (mdns, ssdp)")
|
||||||
ap2.add_argument("--z-on", metavar="NICS/NETS", type=u, default="", help="enable zeroconf ONLY on the comma-separated list of subnets and/or interface names\n └─example: \033[32meth0, wlo1, virhost0, 192.168.123.0/24, fd00:fda::/96\033[0m")
|
ap2.add_argument("--z-on", metavar="NICS/NETS", type=u, default="", help="enable zeroconf ONLY on the comma-separated list of subnets and/or interface names/indexes\n └─example: \033[32meth0, wlo1, virhost0, 192.168.123.0/24, fd00:fda::/96\033[0m")
|
||||||
ap2.add_argument("--z-off", metavar="NICS/NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names")
|
ap2.add_argument("--z-off", metavar="NICS/NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names/indexes")
|
||||||
ap2.add_argument("-zv", action="store_true", help="verbose all zeroconf backends")
|
ap2.add_argument("-zv", action="store_true", help="verbose all zeroconf backends")
|
||||||
ap2.add_argument("--mc-hop", metavar="SEC", type=int, default=0, help="rejoin multicast groups every SEC seconds (workaround for some switches/routers which cause mDNS to suddenly stop working after some time); try [\033[32m300\033[0m] or [\033[32m180\033[0m]")
|
ap2.add_argument("--mc-hop", metavar="SEC", type=int, default=0, help="rejoin multicast groups every SEC seconds (workaround for some switches/routers which cause mDNS to suddenly stop working after some time); try [\033[32m300\033[0m] or [\033[32m180\033[0m]")
|
||||||
|
|
||||||
ap2 = ap.add_argument_group("Zeroconf-mDNS options:")
|
ap2 = ap.add_argument_group("Zeroconf-mDNS options:")
|
||||||
ap2.add_argument("--zm", action="store_true", help="announce the enabled protocols over mDNS (multicast DNS-SD) -- compatible with KDE, gnome, macOS, ...")
|
ap2.add_argument("--zm", action="store_true", help="announce the enabled protocols over mDNS (multicast DNS-SD) -- compatible with KDE, gnome, macOS, ...")
|
||||||
ap2.add_argument("--zm-on", metavar="NICS/NETS", type=u, default="", help="enable zeroconf ONLY on the comma-separated list of subnets and/or interface names")
|
ap2.add_argument("--zm-on", metavar="NICS/NETS", type=u, default="", help="enable zeroconf ONLY on the comma-separated list of subnets and/or interface names/indexes")
|
||||||
ap2.add_argument("--zm-off", metavar="NICS/NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names")
|
ap2.add_argument("--zm-off", metavar="NICS/NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names/indexes")
|
||||||
ap2.add_argument("--zm4", action="store_true", help="IPv4 only -- try this if some clients can't connect")
|
ap2.add_argument("--zm4", action="store_true", help="IPv4 only -- try this if some clients can't connect")
|
||||||
ap2.add_argument("--zm6", action="store_true", help="IPv6 only")
|
ap2.add_argument("--zm6", action="store_true", help="IPv6 only")
|
||||||
ap2.add_argument("--zmv", action="store_true", help="verbose mdns")
|
ap2.add_argument("--zmv", action="store_true", help="verbose mdns")
|
||||||
|
@ -690,8 +690,8 @@ def run_argparse(
|
||||||
|
|
||||||
ap2 = ap.add_argument_group("Zeroconf-SSDP options:")
|
ap2 = ap.add_argument_group("Zeroconf-SSDP options:")
|
||||||
ap2.add_argument("--zs", action="store_true", help="announce the enabled protocols over SSDP -- compatible with Windows")
|
ap2.add_argument("--zs", action="store_true", help="announce the enabled protocols over SSDP -- compatible with Windows")
|
||||||
ap2.add_argument("--zs-on", metavar="NICS/NETS", type=u, default="", help="enable zeroconf ONLY on the comma-separated list of subnets and/or interface names")
|
ap2.add_argument("--zs-on", metavar="NICS/NETS", type=u, default="", help="enable zeroconf ONLY on the comma-separated list of subnets and/or interface names/indexes")
|
||||||
ap2.add_argument("--zs-off", metavar="NICS/NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names")
|
ap2.add_argument("--zs-off", metavar="NICS/NETS", type=u, default="", help="disable zeroconf on the comma-separated list of subnets and/or interface names/indexes")
|
||||||
ap2.add_argument("--zsv", action="store_true", help="verbose SSDP")
|
ap2.add_argument("--zsv", action="store_true", help="verbose SSDP")
|
||||||
ap2.add_argument("--zsl", metavar="PATH", type=u, default="/?hc", help="location to include in the url (or a complete external URL), for example [\033[32mpriv/?pw=hunter2\033[0m] or [\033[32mpriv/?pw=hunter2\033[0m]")
|
ap2.add_argument("--zsl", metavar="PATH", type=u, default="/?hc", help="location to include in the url (or a complete external URL), for example [\033[32mpriv/?pw=hunter2\033[0m] or [\033[32mpriv/?pw=hunter2\033[0m]")
|
||||||
ap2.add_argument("--zsid", metavar="UUID", type=u, default=uuid.uuid4().urn[4:], help="USN (device identifier) to announce")
|
ap2.add_argument("--zsid", metavar="UUID", type=u, default=uuid.uuid4().urn[4:], help="USN (device identifier) to announce")
|
||||||
|
|
|
@ -34,7 +34,6 @@ from .util import (
|
||||||
if True: # pylint: disable=using-constant-test
|
if True: # pylint: disable=using-constant-test
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
|
|
||||||
import typing
|
|
||||||
from typing import Any, Generator, Optional, Union
|
from typing import Any, Generator, Optional, Union
|
||||||
|
|
||||||
from .util import RootLogger
|
from .util import RootLogger
|
||||||
|
|
|
@ -38,6 +38,7 @@ from .util import (
|
||||||
Garda,
|
Garda,
|
||||||
Magician,
|
Magician,
|
||||||
NetMap,
|
NetMap,
|
||||||
|
Netdev,
|
||||||
ipnorm,
|
ipnorm,
|
||||||
min_ex,
|
min_ex,
|
||||||
shut_socket,
|
shut_socket,
|
||||||
|
@ -140,7 +141,7 @@ class HttpSrv(object):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def set_netdevs(self, netdevs: dict[str, str]) -> None:
|
def set_netdevs(self, netdevs: dict[str, Netdev]) -> None:
|
||||||
self.nm = NetMap([self.ip], netdevs)
|
self.nm = NetMap([self.ip], netdevs)
|
||||||
|
|
||||||
def start_threads(self, n: int) -> None:
|
def start_threads(self, n: int) -> None:
|
||||||
|
|
|
@ -25,7 +25,7 @@ from .stolen.dnslib import (
|
||||||
DNSQuestion,
|
DNSQuestion,
|
||||||
DNSRecord,
|
DNSRecord,
|
||||||
)
|
)
|
||||||
from .util import CachedSet, Daemon, min_ex
|
from .util import CachedSet, Daemon, Netdev, min_ex
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .svchub import SvcHub
|
from .svchub import SvcHub
|
||||||
|
@ -42,13 +42,12 @@ class MDNS_Sck(MC_Sck):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
sck: socket.socket,
|
sck: socket.socket,
|
||||||
idx: int,
|
nd: Netdev,
|
||||||
name: str,
|
|
||||||
grp: str,
|
grp: str,
|
||||||
ip: str,
|
ip: str,
|
||||||
net: Union[IPv4Network, IPv6Network],
|
net: Union[IPv4Network, IPv6Network],
|
||||||
):
|
):
|
||||||
super(MDNS_Sck, self).__init__(sck, idx, name, grp, ip, net)
|
super(MDNS_Sck, self).__init__(sck, nd, grp, ip, net)
|
||||||
|
|
||||||
self.bp_probe = b""
|
self.bp_probe = b""
|
||||||
self.bp_ip = b""
|
self.bp_ip = b""
|
||||||
|
@ -263,7 +262,8 @@ class MDNS(MCast):
|
||||||
try:
|
try:
|
||||||
bound = self.create_servers()
|
bound = self.create_servers()
|
||||||
except:
|
except:
|
||||||
self.log("no server IP matches the mdns config", 1)
|
t = "no server IP matches the mdns config\n{}"
|
||||||
|
self.log(t.format(min_ex()), 1)
|
||||||
bound = []
|
bound = []
|
||||||
|
|
||||||
if not bound:
|
if not bound:
|
||||||
|
|
|
@ -7,8 +7,8 @@ import time
|
||||||
import ipaddress
|
import ipaddress
|
||||||
from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network
|
from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network
|
||||||
|
|
||||||
from .__init__ import MACOS, TYPE_CHECKING
|
from .__init__ import TYPE_CHECKING
|
||||||
from .util import min_ex, spack
|
from .util import Netdev, min_ex, spack
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .svchub import SvcHub
|
from .svchub import SvcHub
|
||||||
|
@ -30,15 +30,14 @@ class MC_Sck(object):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
sck: socket.socket,
|
sck: socket.socket,
|
||||||
idx: int,
|
nd: Netdev,
|
||||||
name: str,
|
|
||||||
grp: str,
|
grp: str,
|
||||||
ip: str,
|
ip: str,
|
||||||
net: Union[IPv4Network, IPv6Network],
|
net: Union[IPv4Network, IPv6Network],
|
||||||
):
|
):
|
||||||
self.sck = sck
|
self.sck = sck
|
||||||
self.idx = idx
|
self.idx = nd.idx
|
||||||
self.name = name
|
self.name = nd.name
|
||||||
self.grp = grp
|
self.grp = grp
|
||||||
self.mreq = b""
|
self.mreq = b""
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
@ -112,7 +111,7 @@ class MCast(object):
|
||||||
for lst in (on, off):
|
for lst in (on, off):
|
||||||
for av in list(lst):
|
for av in list(lst):
|
||||||
for sk, sv in netdevs.items():
|
for sk, sv in netdevs.items():
|
||||||
if av == sv.split(",")[0] and sk not in lst:
|
if (av == str(sv.idx) or av == sv.name) and sk not in lst:
|
||||||
lst.append(sk)
|
lst.append(sk)
|
||||||
|
|
||||||
if on:
|
if on:
|
||||||
|
@ -137,12 +136,8 @@ class MCast(object):
|
||||||
|
|
||||||
for ip in ips:
|
for ip in ips:
|
||||||
v6 = ":" in ip
|
v6 = ":" in ip
|
||||||
netdev = "?"
|
netdev = netdevs[ip]
|
||||||
try:
|
if not netdev.idx:
|
||||||
netdev = netdevs[ip].split(",")[0]
|
|
||||||
idx = socket.if_nametoindex(netdev)
|
|
||||||
except:
|
|
||||||
idx = socket.INADDR_ANY
|
|
||||||
t = "using INADDR_ANY for ip [{}], netdev [{}]"
|
t = "using INADDR_ANY for ip [{}], netdev [{}]"
|
||||||
if not self.srv and ip not in ["::", "0.0.0.0"]:
|
if not self.srv and ip not in ["::", "0.0.0.0"]:
|
||||||
self.log(t.format(ip, netdev), 3)
|
self.log(t.format(ip, netdev), 3)
|
||||||
|
@ -159,20 +154,14 @@ class MCast(object):
|
||||||
# most ipv6 clients expect multicast on linklocal ip only;
|
# most ipv6 clients expect multicast on linklocal ip only;
|
||||||
# add a/aaaa records for the other nic IPs
|
# add a/aaaa records for the other nic IPs
|
||||||
other_ips: set[str] = set()
|
other_ips: set[str] = set()
|
||||||
if v6 and netdev not in ("?", ""):
|
if v6:
|
||||||
for oip, onic in netdevs.items():
|
for nd in netdevs.values():
|
||||||
if (
|
if nd.idx == netdev.idx and nd.ip in all_selected and ":" in nd.ip:
|
||||||
onic.split(",")[0] == netdev
|
other_ips.add(nd.ip)
|
||||||
and oip in all_selected
|
|
||||||
and ":" in oip
|
|
||||||
):
|
|
||||||
other_ips.add(oip)
|
|
||||||
|
|
||||||
net = ipaddress.ip_network(ip, False)
|
net = ipaddress.ip_network(ip, False)
|
||||||
ip = ip.split("/")[0]
|
ip = ip.split("/")[0]
|
||||||
srv = self.Srv(
|
srv = self.Srv(sck, netdev, self.grp6 if ":" in ip else self.grp4, ip, net)
|
||||||
sck, idx, netdev, self.grp6 if ":" in ip else self.grp4, ip, net
|
|
||||||
)
|
|
||||||
for oth_ip in other_ips:
|
for oth_ip in other_ips:
|
||||||
srv.ips[oth_ip.split("/")[0]] = ipaddress.ip_network(oth_ip, False)
|
srv.ips[oth_ip.split("/")[0]] = ipaddress.ip_network(oth_ip, False)
|
||||||
|
|
||||||
|
@ -225,8 +214,11 @@ class MCast(object):
|
||||||
self.b2srv[bip] = srv
|
self.b2srv[bip] = srv
|
||||||
self.b6.append(bip)
|
self.b6.append(bip)
|
||||||
|
|
||||||
grp = self.grp6 if srv.idx and not MACOS else ""
|
grp = self.grp6 if srv.idx else ""
|
||||||
sck.bind((grp, self.port, 0, srv.idx))
|
try:
|
||||||
|
sck.bind((grp, self.port, 0, srv.idx))
|
||||||
|
except:
|
||||||
|
sck.bind(("", self.port, 0, srv.idx))
|
||||||
|
|
||||||
bgrp = socket.inet_pton(socket.AF_INET6, self.grp6)
|
bgrp = socket.inet_pton(socket.AF_INET6, self.grp6)
|
||||||
dev = spack(b"@I", srv.idx)
|
dev = spack(b"@I", srv.idx)
|
||||||
|
@ -249,8 +241,12 @@ class MCast(object):
|
||||||
self.b2srv[bip] = srv
|
self.b2srv[bip] = srv
|
||||||
self.b4.append(bip)
|
self.b4.append(bip)
|
||||||
|
|
||||||
grp = self.grp4 if srv.idx and not MACOS else ""
|
grp = self.grp4 if srv.idx else ""
|
||||||
sck.bind((grp, self.port))
|
try:
|
||||||
|
sck.bind((grp, self.port))
|
||||||
|
except:
|
||||||
|
sck.bind(("", self.port))
|
||||||
|
|
||||||
bgrp = socket.inet_aton(self.grp4)
|
bgrp = socket.inet_aton(self.grp4)
|
||||||
dev = (
|
dev = (
|
||||||
spack(b"=I", socket.INADDR_ANY)
|
spack(b"=I", socket.INADDR_ANY)
|
||||||
|
|
|
@ -105,7 +105,8 @@ class SSDPd(MCast):
|
||||||
try:
|
try:
|
||||||
bound = self.create_servers()
|
bound = self.create_servers()
|
||||||
except:
|
except:
|
||||||
self.log("no server IP matches the ssdp config", 1)
|
t = "no server IP matches the ssdp config\n{}"
|
||||||
|
self.log(t.format(min_ex()), 1)
|
||||||
bound = []
|
bound = []
|
||||||
|
|
||||||
if not bound:
|
if not bound:
|
||||||
|
@ -130,7 +131,7 @@ class SSDPd(MCast):
|
||||||
for sck in rx:
|
for sck in rx:
|
||||||
buf, addr = sck.recvfrom(4096)
|
buf, addr = sck.recvfrom(4096)
|
||||||
try:
|
try:
|
||||||
self.eat(buf, addr, sck)
|
self.eat(buf, addr)
|
||||||
except:
|
except:
|
||||||
if not self.running:
|
if not self.running:
|
||||||
return
|
return
|
||||||
|
@ -144,7 +145,7 @@ class SSDPd(MCast):
|
||||||
self.running = False
|
self.running = False
|
||||||
self.srv = {}
|
self.srv = {}
|
||||||
|
|
||||||
def eat(self, buf: bytes, addr: tuple[str, int], sck: socket.socket) -> None:
|
def eat(self, buf: bytes, addr: tuple[str, int]) -> None:
|
||||||
cip = addr[0]
|
cip = addr[0]
|
||||||
if cip.startswith("169.254"):
|
if cip.startswith("169.254"):
|
||||||
return
|
return
|
||||||
|
|
|
@ -6,14 +6,14 @@ import re
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .__init__ import ANYWIN, MACOS, PY2, TYPE_CHECKING, VT100, unicode
|
from .__init__ import ANYWIN, PY2, TYPE_CHECKING, VT100, unicode
|
||||||
from .stolen.qrcodegen import QrCode
|
from .stolen.qrcodegen import QrCode
|
||||||
from .util import (
|
from .util import (
|
||||||
E_ACCESS,
|
E_ACCESS,
|
||||||
E_ADDR_IN_USE,
|
E_ADDR_IN_USE,
|
||||||
E_ADDR_NOT_AVAIL,
|
E_ADDR_NOT_AVAIL,
|
||||||
E_UNREACH,
|
E_UNREACH,
|
||||||
chkcmd,
|
Netdev,
|
||||||
min_ex,
|
min_ex,
|
||||||
sunpack,
|
sunpack,
|
||||||
termsize,
|
termsize,
|
||||||
|
@ -101,7 +101,10 @@ class TcpSrv(object):
|
||||||
if pad:
|
if pad:
|
||||||
self.log("tcpsrv", "")
|
self.log("tcpsrv", "")
|
||||||
|
|
||||||
eps = {"127.0.0.1": "local only", "::1": "local only"}
|
eps = {
|
||||||
|
"127.0.0.1": Netdev("127.0.0.1", 0, "", "local only"),
|
||||||
|
"::1": Netdev("::1", 0, "", "local only"),
|
||||||
|
}
|
||||||
nonlocals = [x for x in self.args.i if x not in [k.split("/")[0] for k in eps]]
|
nonlocals = [x for x in self.args.i if x not in [k.split("/")[0] for k in eps]]
|
||||||
if nonlocals:
|
if nonlocals:
|
||||||
try:
|
try:
|
||||||
|
@ -114,7 +117,7 @@ class TcpSrv(object):
|
||||||
eps.update({k.split("/")[0]: v for k, v in self.netdevs.items()})
|
eps.update({k.split("/")[0]: v for k, v in self.netdevs.items()})
|
||||||
if not eps:
|
if not eps:
|
||||||
for x in nonlocals:
|
for x in nonlocals:
|
||||||
eps[x] = "external"
|
eps[x] = Netdev(x, 0, "", "external")
|
||||||
else:
|
else:
|
||||||
self.netdevs = {}
|
self.netdevs = {}
|
||||||
|
|
||||||
|
@ -264,143 +267,11 @@ class TcpSrv(object):
|
||||||
|
|
||||||
self.log("tcpsrv", "ok bye")
|
self.log("tcpsrv", "ok bye")
|
||||||
|
|
||||||
def ips_linux_ifconfig(self) -> dict[str, str]:
|
def detect_interfaces(self, listen_ips: list[str]) -> dict[str, Netdev]:
|
||||||
# for termux
|
|
||||||
try:
|
|
||||||
txt, _ = chkcmd(["ifconfig"])
|
|
||||||
except:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
eps: dict[str, str] = {}
|
|
||||||
dev = None
|
|
||||||
ip = None
|
|
||||||
up = None
|
|
||||||
for ln in (txt + "\n").split("\n"):
|
|
||||||
if not ln.strip() and dev and ip:
|
|
||||||
eps[ip] = dev + ("" if up else ", \033[31mLINK-DOWN")
|
|
||||||
dev = ip = up = None
|
|
||||||
continue
|
|
||||||
|
|
||||||
if ln == ln.lstrip():
|
|
||||||
dev = re.split(r"[: ]", ln)[0]
|
|
||||||
|
|
||||||
if "UP" in re.split(r"[<>, \t]", ln):
|
|
||||||
up = True
|
|
||||||
|
|
||||||
m = re.match(r"^\s+inet\s+([^ ]+)", ln)
|
|
||||||
if m:
|
|
||||||
ip = m.group(1)
|
|
||||||
|
|
||||||
return eps
|
|
||||||
|
|
||||||
def ips_linux(self) -> dict[str, str]:
|
|
||||||
try:
|
|
||||||
txt, _ = chkcmd(["ip", "addr"])
|
|
||||||
except:
|
|
||||||
return self.ips_linux_ifconfig()
|
|
||||||
|
|
||||||
r = re.compile(r"^\s+inet6? ([^ ]+)/")
|
|
||||||
ri = re.compile(r"^[0-9]+: ([^:]+): ")
|
|
||||||
dev = ""
|
|
||||||
up = False
|
|
||||||
eps: dict[str, str] = {}
|
|
||||||
for ln in txt.split("\n"):
|
|
||||||
m = ri.match(ln)
|
|
||||||
if m:
|
|
||||||
dev = m.group(1)
|
|
||||||
up = "UP" in re.split("[>,< ]", ln)
|
|
||||||
|
|
||||||
m = r.match(ln.rstrip())
|
|
||||||
if not m or not dev or " scope link" in ln:
|
|
||||||
continue
|
|
||||||
|
|
||||||
ip = m.group(1)
|
|
||||||
eps[ip] = dev + ("" if up else ", \033[31mLINK-DOWN")
|
|
||||||
|
|
||||||
return eps
|
|
||||||
|
|
||||||
def ips_macos(self) -> dict[str, str]:
|
|
||||||
eps: dict[str, str] = {}
|
|
||||||
try:
|
|
||||||
txt, _ = chkcmd(["ifconfig"])
|
|
||||||
except:
|
|
||||||
return eps
|
|
||||||
|
|
||||||
rdev = re.compile(r"^([^ ]+):")
|
|
||||||
rip = re.compile(r"^\tinet ([0-9\.]+) ")
|
|
||||||
dev = "UNKNOWN"
|
|
||||||
for ln in txt.split("\n"):
|
|
||||||
m = rdev.match(ln)
|
|
||||||
if m:
|
|
||||||
dev = m.group(1)
|
|
||||||
|
|
||||||
m = rip.match(ln)
|
|
||||||
if m:
|
|
||||||
eps[m.group(1)] = dev
|
|
||||||
dev = "UNKNOWN"
|
|
||||||
|
|
||||||
return eps
|
|
||||||
|
|
||||||
def ips_windows_ipconfig(self) -> tuple[dict[str, str], set[str]]:
|
|
||||||
eps: dict[str, str] = {}
|
|
||||||
offs: set[str] = set()
|
|
||||||
try:
|
|
||||||
txt, _ = chkcmd(["ipconfig"])
|
|
||||||
except:
|
|
||||||
return eps, offs
|
|
||||||
|
|
||||||
rdev = re.compile(r"(^[^ ].*):$")
|
|
||||||
rip = re.compile(r"^ +IPv?4? [^:]+: *([0-9\.]{7,15})$")
|
|
||||||
roff = re.compile(r".*: Media disconnected$")
|
|
||||||
dev = None
|
|
||||||
for ln in txt.replace("\r", "").split("\n"):
|
|
||||||
m = rdev.match(ln)
|
|
||||||
if m:
|
|
||||||
if dev and dev not in eps.values():
|
|
||||||
offs.add(dev)
|
|
||||||
|
|
||||||
dev = m.group(1).split(" adapter ", 1)[-1]
|
|
||||||
|
|
||||||
if dev and roff.match(ln):
|
|
||||||
offs.add(dev)
|
|
||||||
dev = None
|
|
||||||
|
|
||||||
m = rip.match(ln)
|
|
||||||
if m and dev:
|
|
||||||
eps[m.group(1)] = dev
|
|
||||||
dev = None
|
|
||||||
|
|
||||||
if dev and dev not in eps.values():
|
|
||||||
offs.add(dev)
|
|
||||||
|
|
||||||
return eps, offs
|
|
||||||
|
|
||||||
def ips_windows_netsh(self) -> dict[str, str]:
|
|
||||||
eps: dict[str, str] = {}
|
|
||||||
try:
|
|
||||||
txt, _ = chkcmd("netsh interface ip show address".split())
|
|
||||||
except:
|
|
||||||
return eps
|
|
||||||
|
|
||||||
rdev = re.compile(r'.* "([^"]+)"$')
|
|
||||||
rip = re.compile(r".* IP\b.*: +([0-9\.]{7,15})$")
|
|
||||||
dev = None
|
|
||||||
for ln in txt.replace("\r", "").split("\n"):
|
|
||||||
m = rdev.match(ln)
|
|
||||||
if m:
|
|
||||||
dev = m.group(1)
|
|
||||||
|
|
||||||
m = rip.match(ln)
|
|
||||||
if m and dev:
|
|
||||||
eps[m.group(1)] = dev
|
|
||||||
|
|
||||||
return eps
|
|
||||||
|
|
||||||
def detect_interfaces(self, listen_ips: list[str]) -> dict[str, str]:
|
|
||||||
from .stolen.ifaddr import get_adapters
|
from .stolen.ifaddr import get_adapters
|
||||||
|
|
||||||
nics = get_adapters(True)
|
nics = get_adapters(True)
|
||||||
eps = {}
|
eps: dict[str, Netdev] = {}
|
||||||
for nic in nics:
|
for nic in nics:
|
||||||
for nip in nic.ips:
|
for nip in nic.ips:
|
||||||
ipa = nip.ip[0] if ":" in str(nip.ip) else nip.ip
|
ipa = nip.ip[0] if ":" in str(nip.ip) else nip.ip
|
||||||
|
@ -409,14 +280,15 @@ class TcpSrv(object):
|
||||||
# browsers dont impl linklocal
|
# browsers dont impl linklocal
|
||||||
continue
|
continue
|
||||||
|
|
||||||
eps[sip] = nic.nice_name
|
eps[sip] = Netdev(sip, nic.index or 0, nic.nice_name, "")
|
||||||
|
|
||||||
if "0.0.0.0" not in listen_ips and "::" not in listen_ips:
|
if "0.0.0.0" not in listen_ips and "::" not in listen_ips:
|
||||||
eps = {k: v for k, v in eps.items() if k.split("/")[0] in listen_ips}
|
eps = {k: v for k, v in eps.items() if k.split("/")[0] in listen_ips}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ext_devs = list(self._extdevs_nix())
|
ext_devs = list(self._extdevs_nix())
|
||||||
ext_ips = [k for k, v in eps.items() if v.split(",")[0] in ext_devs]
|
ext_ips = [k for k, v in eps.items() if v.name in ext_devs]
|
||||||
|
ext_ips = [x.split("/")[0] for x in ext_ips]
|
||||||
if not ext_ips:
|
if not ext_ips:
|
||||||
raise Exception()
|
raise Exception()
|
||||||
except:
|
except:
|
||||||
|
@ -430,11 +302,9 @@ class TcpSrv(object):
|
||||||
desc = "\033[32mexternal"
|
desc = "\033[32mexternal"
|
||||||
ips = ext_ips if lip in ["0.0.0.0", "::"] else [lip]
|
ips = ext_ips if lip in ["0.0.0.0", "::"] else [lip]
|
||||||
for ip in ips:
|
for ip in ips:
|
||||||
try:
|
ip = next((x for x in eps if x.startswith(ip + "/")), "")
|
||||||
if "external" not in eps[ip]:
|
if ip and "external" not in eps[ip].desc:
|
||||||
eps[ip] += ", " + desc
|
eps[ip].desc += ", " + desc
|
||||||
except:
|
|
||||||
eps[ip] = desc
|
|
||||||
|
|
||||||
return eps
|
return eps
|
||||||
|
|
||||||
|
|
|
@ -188,10 +188,14 @@ IMPLICATIONS = [
|
||||||
["z", "zm"],
|
["z", "zm"],
|
||||||
["z", "zs"],
|
["z", "zs"],
|
||||||
["zmvv", "zmv"],
|
["zmvv", "zmv"],
|
||||||
|
["zm4", "zm"],
|
||||||
|
["zm6", "zm"],
|
||||||
["zmv", "zm"],
|
["zmv", "zm"],
|
||||||
["zms", "zm"],
|
["zms", "zm"],
|
||||||
["zsv", "zs"],
|
["zsv", "zs"],
|
||||||
]
|
]
|
||||||
|
if ANYWIN:
|
||||||
|
IMPLICATIONS.extend([["z", "zm4"]])
|
||||||
|
|
||||||
|
|
||||||
UNPLICATIONS = [["no_dav", "daw"]]
|
UNPLICATIONS = [["no_dav", "daw"]]
|
||||||
|
@ -363,6 +367,23 @@ class Daemon(threading.Thread):
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
|
|
||||||
|
class Netdev(object):
|
||||||
|
def __init__(self, ip: str, idx: int, name: str, desc: str):
|
||||||
|
self.ip = ip
|
||||||
|
self.idx = idx
|
||||||
|
self.name = name
|
||||||
|
self.desc = desc
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "{}-{}{}".format(self.idx, self.name, self.desc)
|
||||||
|
|
||||||
|
def __lt__(self, rhs):
|
||||||
|
return str(self) < str(rhs)
|
||||||
|
|
||||||
|
def __eq__(self, rhs):
|
||||||
|
return str(self) == str(rhs)
|
||||||
|
|
||||||
|
|
||||||
class Cooldown(object):
|
class Cooldown(object):
|
||||||
def __init__(self, maxage: float) -> None:
|
def __init__(self, maxage: float) -> None:
|
||||||
self.maxage = maxage
|
self.maxage = maxage
|
||||||
|
@ -434,7 +455,7 @@ class HLog(logging.Handler):
|
||||||
|
|
||||||
|
|
||||||
class NetMap(object):
|
class NetMap(object):
|
||||||
def __init__(self, ips: list[str], netdevs: dict[str, str]) -> None:
|
def __init__(self, ips: list[str], netdevs: dict[str, Netdev]) -> None:
|
||||||
if "::" in ips:
|
if "::" in ips:
|
||||||
ips = [x for x in ips if x != "::"] + list(
|
ips = [x for x in ips if x != "::"] + list(
|
||||||
[x.split("/")[0] for x in netdevs if ":" in x]
|
[x.split("/")[0] for x in netdevs if ":" in x]
|
||||||
|
@ -1791,11 +1812,14 @@ if not PY2 or not WINDOWS:
|
||||||
else:
|
else:
|
||||||
# moonrunes become \x3f with bytestrings,
|
# moonrunes become \x3f with bytestrings,
|
||||||
# losing mojibake support is worth
|
# losing mojibake support is worth
|
||||||
def _not_actually_mbcs(txt: str) -> str:
|
def _not_actually_mbcs_enc(txt: str) -> bytes:
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
fsenc = _not_actually_mbcs
|
def _not_actually_mbcs_dec(txt: bytes) -> str:
|
||||||
fsdec = _not_actually_mbcs
|
return txt
|
||||||
|
|
||||||
|
fsenc = _not_actually_mbcs_enc
|
||||||
|
fsdec = _not_actually_mbcs_dec
|
||||||
|
|
||||||
|
|
||||||
def s3enc(mem_cur: "sqlite3.Cursor", rd: str, fn: str) -> tuple[str, str]:
|
def s3enc(mem_cur: "sqlite3.Cursor", rd: str, fn: str) -> tuple[str, str]:
|
||||||
|
|
|
@ -109,6 +109,7 @@ pre, code {
|
||||||
html.z pre,
|
html.z pre,
|
||||||
html.z code {
|
html.z code {
|
||||||
color: #9e0;
|
color: #9e0;
|
||||||
|
background: #000;
|
||||||
background: rgba(0,16,0,0.2);
|
background: rgba(0,16,0,0.2);
|
||||||
}
|
}
|
||||||
.os {
|
.os {
|
||||||
|
|
|
@ -138,7 +138,7 @@ tmpdir="$(
|
||||||
)"
|
)"
|
||||||
|
|
||||||
necho() {
|
necho() {
|
||||||
printf '\033[G%s\033[K' "$*"
|
printf '\033[G%s ... \033[K' "$*"
|
||||||
}
|
}
|
||||||
|
|
||||||
[ $repack ] && {
|
[ $repack ] && {
|
||||||
|
@ -331,7 +331,6 @@ find -name py.typed -delete
|
||||||
find -type f \( -name .DS_Store -or -name ._.DS_Store \) -delete
|
find -type f \( -name .DS_Store -or -name ._.DS_Store \) -delete
|
||||||
find -type f -name ._\* | while IFS= read -r f; do cmp <(printf '\x00\x05\x16') <(head -c 3 -- "$f") && rm -f -- "$f"; done
|
find -type f -name ._\* | while IFS= read -r f; do cmp <(printf '\x00\x05\x16') <(head -c 3 -- "$f") && rm -f -- "$f"; done
|
||||||
|
|
||||||
echo use smol web deps
|
|
||||||
rm -f copyparty/web/deps/*.full.* copyparty/web/dbg-* copyparty/web/Makefile
|
rm -f copyparty/web/deps/*.full.* copyparty/web/dbg-* copyparty/web/Makefile
|
||||||
|
|
||||||
find copyparty | LC_ALL=C sort | sed 's/\.gz$//;s/$/,/' > have
|
find copyparty | LC_ALL=C sort | sed 's/\.gz$//;s/$/,/' > have
|
||||||
|
@ -466,7 +465,7 @@ zdir="$tmpdir/cpp-mk$CSN"
|
||||||
[ -e "$zdir/$stamp" ] || rm -rf "$zdir"
|
[ -e "$zdir/$stamp" ] || rm -rf "$zdir"
|
||||||
mkdir -p "$zdir"
|
mkdir -p "$zdir"
|
||||||
echo a > "$zdir/$stamp"
|
echo a > "$zdir/$stamp"
|
||||||
nf=$(ls -1 "$zdir"/arc.* | wc -l)
|
nf=$(ls -1 "$zdir"/arc.* 2>/dev/null | wc -l)
|
||||||
[ $nf -ge 2 ] && [ ! $repack ] && use_zdir=1 || use_zdir=
|
[ $nf -ge 2 ] && [ ! $repack ] && use_zdir=1 || use_zdir=
|
||||||
|
|
||||||
[ $use_zdir ] || {
|
[ $use_zdir ] || {
|
||||||
|
|
|
@ -3,6 +3,7 @@ set -e
|
||||||
|
|
||||||
curl -k https://192.168.123.1:3923/cpp/scripts/pyinstaller/build.sh |
|
curl -k https://192.168.123.1:3923/cpp/scripts/pyinstaller/build.sh |
|
||||||
tee build2.sh | cmp build.sh && rm build2.sh || {
|
tee build2.sh | cmp build.sh && rm build2.sh || {
|
||||||
|
[ -s build2.sh ] || exit 1
|
||||||
echo "new build script; upgrade y/n:"
|
echo "new build script; upgrade y/n:"
|
||||||
while true; do read -u1 -n1 -r r; [[ $r =~ [yYnN] ]] && break; done
|
while true; do read -u1 -n1 -r r; [[ $r =~ [yYnN] ]] && break; done
|
||||||
[[ $r =~ [yY] ]] && mv build{2,}.sh && exec ./build.sh
|
[[ $r =~ [yY] ]] && mv build{2,}.sh && exec ./build.sh
|
||||||
|
|
Loading…
Reference in a new issue