diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile index 7d04e36a..79116653 100644 --- a/luci-app-passwall2/Makefile +++ b/luci-app-passwall2/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall2 -PKG_VERSION:=26.6.3 +PKG_VERSION:=26.6.16 PKG_RELEASE:=1 PKG_PO_VERSION:=$(PKG_VERSION) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua index 22c48b1d..505d6b62 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua @@ -320,15 +320,6 @@ o.rewrite_option = "method" for a, t in ipairs(ss_method_list) do o:value(t) end o:depends({ [_n("protocol")] = "shadowsocks" }) -o = s:option(Flag, _n("iv_check"), translate("IV Check")) -o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-128-gcm" }) -o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "aes-256-gcm" }) -o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "chacha20-poly1305" }) -o:depends({ [_n("protocol")] = "shadowsocks", [_n("ss_method")] = "xchacha20-poly1305" }) - -o = s:option(Flag, _n("uot"), translate("UDP over TCP")) -o:depends({ [_n("protocol")] = "shadowsocks" }) - o = s:option(ListValue, _n("flow"), translate("flow")) o.default = "" o:value("", translate("Disable")) @@ -420,7 +411,6 @@ o:value("http/1.1") o:value("h2,http/1.1") o:value("h3,h2,http/1.1") o:depends({ [_n("tls")] = true, [_n("reality")] = false }) -o:depends({ [_n("protocol")] = "hysteria2" }) -- o = s:option(Value, _n("minversion"), translate("minversion")) -- o.default = "1.3" @@ -772,11 +762,6 @@ o.default = 0 o = s:option(Flag, _n("tcpMptcp"), "tcpMptcp", translate("Enable Multipath TCP, need to be enabled in both server and client configuration.")) o.default = 0 -o = s:option(Value, _n("preconns"), translate("Pre-connections"), translate("Number of early established connections to reduce latency.")) -o.datatype = "uinteger" -o.placeholder = 0 -o:depends({ [_n("protocol")] = "vless" }) - o = s:option(ListValue, _n("domain_resolver"), translate("Domain DNS Resolve"), translate("If the node address is a domain name, this DNS will be used for resolution.")) o:value("", translate("Auto")) o:value("tcp", "TCP") diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua index 14a48bc5..31104c2f 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua @@ -97,9 +97,6 @@ o.rewrite_option = "method" for a, t in ipairs(x_ss_method_list) do o:value(t) end o:depends({ [_n("protocol")] = "shadowsocks" }) -o = s:option(Flag, _n("iv_check"), translate("IV Check")) -o:depends({ [_n("protocol")] = "shadowsocks" }) - o = s:option(ListValue, _n("ss_network"), translate("Transport")) o.default = "tcp,udp" o:value("tcp", "TCP") @@ -232,7 +229,6 @@ o:value("http/1.1") o:value("h2,http/1.1") o:value("h3,h2,http/1.1") o:depends({ [_n("tls")] = true, [_n("reality")] = false }) -o:depends({ [_n("protocol")] = "hysteria2"}) o = s:option(Flag, _n("use_mldsa65Seed"), translate("ML-DSA-65")) o.default = "0" diff --git a/luci-app-passwall2/luasrc/passwall2/api.lua b/luci-app-passwall2/luasrc/passwall2/api.lua index 5ee4cb7b..e3519254 100644 --- a/luci-app-passwall2/luasrc/passwall2/api.lua +++ b/luci-app-passwall2/luasrc/passwall2/api.lua @@ -1611,27 +1611,23 @@ end function parse_realm_uri(uri) if type(uri) ~= "string" then return nil end - -- realm://token@server/realm_id?query - local token, server_url, realm_id, query = trim(uri):match("^realm://([^@]+)@([^/]+)/([^?]*)%??(.*)$") - if not token or not server_url or not realm_id then return nil end + -- realm[+http]://token@server/realm_id?query + local scheme, token, server_url, realm_id, query = trim(uri):match("^(realm%+http|realm)://([^@]+)@([^/]+)/([^?]*)%??(.*)$") + if not scheme or not token or not server_url or not realm_id then return nil end realm_id = realm_id:gsub("/+$", "") local realm = { + scheme = scheme, token = token, server_url = server_url, realm_id = realm_id } - -- 解析 query 中的 stun= - if query and query ~= "" then - local stun_servers = {} - for key, value in query:gmatch("([^&=?]+)=([^&]+)") do - if key == "stun" and value ~= "" then - stun_servers[#stun_servers + 1] = value - end - end - if #stun_servers > 0 then - realm.stun_servers = stun_servers - end + -- Parse stun= in the query + local stun_servers + for value in (query or ""):gmatch("[?&]?[Ss][Tt][Uu][Nn]=([^&]+)") do + if not stun_servers then stun_servers = {} end + stun_servers[#stun_servers + 1] = value end + realm.stun_servers = stun_servers return realm end diff --git a/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua b/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua index 43b586e2..48673249 100644 --- a/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua +++ b/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua @@ -64,7 +64,8 @@ function gen_config(var) server_host = api.get_ipv6_full(server_host) end - local server = server_host .. ":" .. ((server_port or "") .. "," .. (node.hysteria2_hop or "")):gsub("^[%s,]+", ""):gsub("[%s,]+$", ""):gsub(":", "-") + local port_hop = ((server_port or "") .. "," .. (node.hysteria2_hop or "")):gsub("^[%s,]+", ""):gsub("[%s,]+$", ""):gsub(":", "-") + local server = server_host .. ":" .. (port_hop ~= "" and port_hop or "443") local config = { server = (function() diff --git a/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua index 513a5cd8..39580747 100644 --- a/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua +++ b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua @@ -617,8 +617,9 @@ function gen_outbound(flag, node, tag, proxy_table) result.server_port = nil local realm = api.parse_realm_uri(node.hysteria2_realm_url) if realm then - realm.server_url = realm.server_url and "https://" .. realm.server_url or nil + realm.server_url = (realm.scheme == "realm+http" and "http://" or "https://") .. realm.server_url realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun + realm.scheme = nil return realm end return nil @@ -959,8 +960,9 @@ function gen_config_server(node) realm = node.hysteria2_realms and (function() local realm = api.parse_realm_uri(node.hysteria2_realm_url) if realm then - realm.server_url = realm.server_url and "https://" .. realm.server_url or nil + realm.server_url = (realm.scheme == "realm+http" and "http://" or "https://") .. realm.server_url realm.stun_servers = realm.stun_servers or node.hysteria2_realm_stun + realm.scheme = nil realm.stun_domain_resolver = "direct" return realm end @@ -1797,13 +1799,12 @@ function gen_config(var) end end - table.insert(route.rules, { - action = "route", - ip_is_private = true, - outbound = "direct" - }) - if COMMON.default_outbound_tag then + table.insert(route.rules, { + action = "route", + port_range = { "0:65535" }, + outbound = COMMON.default_outbound_tag + }) route.final = COMMON.default_outbound_tag end diff --git a/luci-app-passwall2/luasrc/passwall2/util_xray.lua b/luci-app-passwall2/luasrc/passwall2/util_xray.lua index 3c0f708b..bf6f6e89 100644 --- a/luci-app-passwall2/luasrc/passwall2/util_xray.lua +++ b/luci-app-passwall2/luasrc/passwall2/util_xray.lua @@ -285,21 +285,22 @@ function gen_outbound(flag, node, tag, proxy_table) local finalmask = {} local TP = node.transport if TP == "mkcp" then - local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", - dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} + local map = {none = "none", srtp = "srtp", utp = "utp", ["wechat-video"] = "wechat", + dtls = "dtls", wireguard = "wireguard", dns = "dns"} local udp = {} if node.mkcp_guise and node.mkcp_guise ~= "none" then - local g = { type = map[node.mkcp_guise] } + local g = { type = "mkcp-legacy" } + g.settings = { header = map[node.mkcp_guise] } if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then - g.settings = { domain = node.mkcp_domain } + g.settings.value = node.mkcp_domain end udp[#udp+1] = g end - local c = { type = (node.mkcp_seed and node.mkcp_seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } + local s = { type = "mkcp-legacy" } if node.mkcp_seed and node.mkcp_seed ~= "" then - c.settings = { password = node.mkcp_seed } + s.settings = { value = node.mkcp_seed } end - udp[#udp+1] = c + udp[#udp+1] = s finalmask.udp = udp elseif TP == "hysteria" then local udp = {} @@ -317,9 +318,7 @@ function gen_outbound(flag, node, tag, proxy_table) local realm = api.parse_realm_uri(node.hysteria2_realm_url) local url, stun if realm then - if realm.token and realm.server_url and realm.realm_id then - url = "realm://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id - end + url = realm.scheme .. "://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id stun = realm.stun_servers or node.hysteria2_realm_stun end local r = { @@ -386,43 +385,18 @@ function gen_outbound(flag, node, tag, proxy_table) end)() } or nil, settings = { - vnext = (node.protocol == "vmess" or node.protocol == "vless") and { - { - address = node.address, - port = tonumber(node.port), - users = { - { - id = node.uuid, - level = 0, - security = (node.protocol == "vmess") and node.security or nil, - testpre = (node.protocol == "vless") and tonumber(node.preconns) or nil, - encryption = (node.protocol == "vless") and ((node.encryption and node.encryption ~= "") and node.encryption or "none") or nil, - flow = (node.protocol == "vless" - and (node.tls == "1" or (node.encryption and node.encryption ~= "" and node.encryption ~= "none")) - and node.flow and node.flow ~= "") and node.flow or nil - } - } - } - } or nil, - servers = (node.protocol == "socks" or node.protocol == "http" or node.protocol == "shadowsocks" or node.protocol == "trojan") and { - { - address = node.address, - port = tonumber(node.port), - method = (node.method == "chacha20-ietf-poly1305" and "chacha20-poly1305") or - (node.method == "xchacha20-ietf-poly1305" and "xchacha20-poly1305") or - (node.method ~= "" and node.method) or nil, - ivCheck = (node.protocol == "shadowsocks") and node.iv_check == "1" or nil, - uot = (node.protocol == "shadowsocks") and node.uot == "1" or nil, - password = node.password or "", - users = (node.username and node.password) and { - { - user = node.username, - pass = node.password - } - } or nil - } - } or nil, - address = (node.protocol == "wireguard" and node.wireguard_local_address) or (node.protocol == "hysteria" and node.address) or nil, + address = (node.protocol == "wireguard") and node.wireguard_local_address or node.address, + port = tonumber(node.port), + id = (node.protocol == "vmess" or node.protocol == "vless") and node.uuid or nil, + encryption = (node.protocol == "vless") and ((node.encryption and node.encryption ~= "") and node.encryption or "none") or nil, + flow = (node.protocol == "vless" and (node.tls == "1" or (node.encryption and node.encryption ~= "" and node.encryption ~= "none")) + and node.flow and node.flow ~= "") and node.flow or nil, + security = (node.protocol == "vmess") and node.security or nil, + user = (node.protocol == "socks" or node.protocol == "http") and node.username or nil, + pass = (node.protocol == "socks" or node.protocol == "http") and node.password or nil, + password = (node.protocol == "shadowsocks" or node.protocol == "trojan") and node.password or nil, + method = (node.protocol == "shadowsocks") and ((node.method == "chacha20-ietf-poly1305" and "chacha20-poly1305") or + (node.method == "xchacha20-ietf-poly1305" and "xchacha20-poly1305") or (node.method ~= "" and node.method) or nil) or nil, secretKey = (node.protocol == "wireguard") and node.wireguard_secret_key or nil, peers = (node.protocol == "wireguard") and { { @@ -434,13 +408,13 @@ function gen_outbound(flag, node, tag, proxy_table) } or nil, mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil, reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil, - port = (node.protocol == "hysteria" and node.port) and tonumber(node.port) or nil, - version = node.protocol == "hysteria" and 2 or nil + version = (node.protocol == "hysteria") and 2 or nil, + level = 0 } } if node.protocol == "wireguard" then - result.settings.kernelMode = false + result.settings.noKernelTun = true if node.finalmask and node.finalmask ~= "" then local ok, fm = pcall(jsonc.parse, api.base64Decode(node.finalmask)) if ok and type(fm) == "table" then @@ -561,7 +535,6 @@ function gen_config_server(node) settings = { method = node.method, password = node.password, - ivCheck = ("1" == node.iv_check) and true or false, network = node.ss_network or "TCP,UDP" } elseif node.protocol == "trojan" then @@ -740,21 +713,22 @@ function gen_config_server(node) finalmask = (function() local finalmask = {} if node.transport == "mkcp" then - local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat", - dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"} + local map = {none = "none", srtp = "srtp", utp = "utp", ["wechat-video"] = "wechat", + dtls = "dtls", wireguard = "wireguard", dns = "dns"} local udp = {} if node.mkcp_guise and node.mkcp_guise ~= "none" then - local g = { type = map[node.mkcp_guise] } + local g = { type = "mkcp-legacy" } + g.settings = { header = map[node.mkcp_guise] } if node.mkcp_guise == "dns" and node.mkcp_domain and node.mkcp_domain ~= "" then - g.settings = { domain = node.mkcp_domain } + g.settings.value = node.mkcp_domain end udp[#udp+1] = g end - local c = { type = (node.mkcp_seed and node.mkcp_seed ~= "") and "mkcp-aes128gcm" or "mkcp-original" } + local s = { type = "mkcp-legacy" } if node.mkcp_seed and node.mkcp_seed ~= "" then - c.settings = { password = node.mkcp_seed } + s.settings = { value = node.mkcp_seed } end - udp[#udp+1] = c + udp[#udp+1] = s finalmask.udp = udp elseif node.transport == "hysteria" then local udp = {} @@ -772,9 +746,7 @@ function gen_config_server(node) local realm = api.parse_realm_uri(node.hysteria2_realm_url) local url, stun if realm then - if realm.token and realm.server_url and realm.realm_id then - url = "realm://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id - end + url = realm.scheme .. "://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id stun = realm.stun_servers or node.hysteria2_realm_stun end local r = { @@ -1524,7 +1496,7 @@ function gen_config(var) outboundTag = default_outboundTag, } if node.domainStrategy == "IPIfNonMatch" then - rule.ip = { "0.0.0.0/0", "::/0" } + rule.port = "1-65535" else rule.network = "tcp,udp" end @@ -1718,7 +1690,8 @@ function gen_config(var) }) end end - + + local dns_outbound if dns_listen_port then table.insert(inbounds, { listen = "127.0.0.1", @@ -1775,12 +1748,13 @@ function gen_config(var) } } local type_dns = direct_type_dns - table.insert(outbounds, { + dns_outbound = { tag = "dns-out", protocol = "dns", proxySettings = type_dns.proxySettings, settings = type_dns.settings - }) + } + table.insert(outbounds, dns_outbound) table.insert(routing.rules, 1, { inboundTag = { "dns-in" @@ -1815,6 +1789,7 @@ function gen_config(var) end -- Shunt rule DNS logic + local dns_out_rules = {} if dns_domain_rules and #dns_domain_rules > 0 then for index, value in ipairs(dns_domain_rules) do if value.domain and value.outboundTag then @@ -1834,19 +1809,19 @@ function gen_config(var) end end end - local dns_block = true -- If you do not want the blackhole rule to use DNS routing, please change it to `nil` or do not assign a value. if dns_outboundTag == "blackhole" then - if dns_block then - local dns_block_mode = "Hosts" -- use the Hosts mode to block. - if dns_block_mode == "Hosts" then - for d_i, d_k in ipairs(value.domain) do - dns.hosts[d_k] = "0.0.0.0" - end - dns_server = nil - end - else - dns_server = nil - end + table.insert(dns_out_rules, { + action = "return", + rCode = 0, + domain = api.clone(value.domain) + }) + dns_server = nil + else + table.insert(dns_out_rules, { + action = "hijack", + qType = "1,28", + domain = api.clone(value.domain) + }) end if dns_server then dns_server.finalQuery = true @@ -1861,6 +1836,11 @@ function gen_config(var) end end end + if dns_outbound and #dns_out_rules > 0 then + for i = #dns_out_rules, 1, -1 do + table.insert(dns_outbound.settings.rules, 1, dns_out_rules[i]) + end + end end end diff --git a/luci-app-passwall2/po/fa/passwall2.po b/luci-app-passwall2/po/fa/passwall2.po index e2cf45c5..c0617a07 100644 --- a/luci-app-passwall2/po/fa/passwall2.po +++ b/luci-app-passwall2/po/fa/passwall2.po @@ -1251,9 +1251,6 @@ msgstr "پاک کردن گزارش‌ها" msgid "Password" msgstr "رمز عبور" -msgid "IV Check" -msgstr "بررسی IV" - msgid "UDP over TCP" msgstr "UDP بر روی TCP" @@ -1266,12 +1263,6 @@ msgstr "پورت محلی" msgid "Fast Open" msgstr "بازگشایی سریع (Fast Open)" -msgid "Pre-connections" -msgstr "پیش‌اتصالات" - -msgid "Number of early established connections to reduce latency." -msgstr "تعداد اتصالات از پیش برقرار شده برای کاهش تاخیر." - msgid "plugin" msgstr "افزونه" diff --git a/luci-app-passwall2/po/ru/passwall2.po b/luci-app-passwall2/po/ru/passwall2.po index be21069c..f47553ad 100644 --- a/luci-app-passwall2/po/ru/passwall2.po +++ b/luci-app-passwall2/po/ru/passwall2.po @@ -1252,9 +1252,6 @@ msgstr "Очистить журнал" msgid "Password" msgstr "Пароль" -msgid "IV Check" -msgstr "Проверка IV" - msgid "UDP over TCP" msgstr "UDP через TCP" @@ -1267,12 +1264,6 @@ msgstr "Локальный порт" msgid "Fast Open" msgstr "Fast Open" -msgid "Pre-connections" -msgstr "Предварительные соединения" - -msgid "Number of early established connections to reduce latency." -msgstr "Количество заранее установленных соединений для снижения задержки." - msgid "plugin" msgstr "Плагин" diff --git a/luci-app-passwall2/po/zh-cn/passwall2.po b/luci-app-passwall2/po/zh-cn/passwall2.po index 026e4e91..6b566f38 100644 --- a/luci-app-passwall2/po/zh-cn/passwall2.po +++ b/luci-app-passwall2/po/zh-cn/passwall2.po @@ -1243,9 +1243,6 @@ msgstr "清空日志" msgid "Password" msgstr "密码" -msgid "IV Check" -msgstr "IV 检查" - msgid "UDP over TCP" msgstr "TCP 封装 UDP" @@ -1258,12 +1255,6 @@ msgstr "本地端口" msgid "Fast Open" msgstr "快速打开" -msgid "Pre-connections" -msgstr "预连接" - -msgid "Number of early established connections to reduce latency." -msgstr "预连接的数量,用于降低延迟。" - msgid "plugin" msgstr "插件" diff --git a/luci-app-passwall2/po/zh-tw/passwall2.po b/luci-app-passwall2/po/zh-tw/passwall2.po index cf6d3089..26cecd9c 100644 --- a/luci-app-passwall2/po/zh-tw/passwall2.po +++ b/luci-app-passwall2/po/zh-tw/passwall2.po @@ -1243,9 +1243,6 @@ msgstr "清空日誌" msgid "Password" msgstr "密碼" -msgid "IV Check" -msgstr "IV 檢查" - msgid "UDP over TCP" msgstr "TCP 封装 UDP" @@ -1258,12 +1255,6 @@ msgstr "本地端口" msgid "Fast Open" msgstr "快速打開" -msgid "Pre-connections" -msgstr "預連接" - -msgid "Number of early established connections to reduce latency." -msgstr "預連接的數量,用於降低延遲。" - msgid "plugin" msgstr "插件" diff --git a/luci-app-passwall2/root/etc/init.d/passwall2_server b/luci-app-passwall2/root/etc/init.d/passwall2_server index 1cf39fea..1374563f 100755 --- a/luci-app-passwall2/root/etc/init.d/passwall2_server +++ b/luci-app-passwall2/root/etc/init.d/passwall2_server @@ -2,6 +2,15 @@ START=99 +boot_func() { + sleep 90 + restart +} + +boot() { + boot_func >/dev/null 2>&1 & +} + start() { lua /usr/lib/lua/luci/passwall2/server_app.lua start } diff --git a/luci-app-passwall2/root/usr/share/passwall2/0_default_config b/luci-app-passwall2/root/usr/share/passwall2/0_default_config index 647a2d98..5dc1def0 100644 --- a/luci-app-passwall2/root/usr/share/passwall2/0_default_config +++ b/luci-app-passwall2/root/usr/share/passwall2/0_default_config @@ -88,6 +88,23 @@ config shunt_rules 'Russia' option ip_list 'geoip:ru #rule-set:remote:https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/refs/heads/release/sing-box/rule-set-geoip/geoip-ru.srs' +config shunt_rules 'PrivateIP' + option remarks 'PrivateIP' + option network 'tcp,udp' + option ip_list '10.0.0.0/8 +127.0.0.0/8 +198.51.100.0/24 +192.0.0.0/24 +169.254.0.0/16 +224.0.0.0/3 +192.168.0.0/16 +192.88.99.0/24 +100.64.0.0/10 +172.16.0.0/12 +0.0.0.0/8 +192.0.2.0/24 +203.0.113.0/24' + config nodes 'examplenode' option remarks 'Example' option type 'Xray' @@ -104,6 +121,7 @@ config nodes 'rulenode' option remarks 'rulenode' option type 'Xray' option protocol '_shunt' + option PrivateIP '_direct' option default_node 'examplenode' option domainStrategy 'IPOnDemand' option domainMatcher 'hybrid' diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua index f8c8f01e..eb40231f 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -1937,7 +1937,6 @@ local function curl(url, file, ua, mode) ua = (ua == "passwall2") and ("passwall2/" .. api.get_version()) or ua curl_args[#curl_args + 1] = '--user-agent "' .. ua .. '"' end - curl_args[#curl_args + 1] = get_headers() local return_code, result if mode == "direct" then return_code, result = api.curl_direct(url, file, curl_args) @@ -1949,57 +1948,6 @@ local function curl(url, file, ua, mode) return return_code, tonumber(result) end -function get_headers() - local cache_file = "/tmp/etc/" .. appname .. "_tmp/sub_curl_headers" - if fs.access(cache_file) then - return luci.sys.exec("cat " .. cache_file) - end - local headers = {} - - local function readfile(path) - local f = io.open(path, "r") - if not f then return nil end - local c = f:read("*a") - f:close() - return api.trim(c) - end - - headers[#headers + 1] = "x-device-os: OpenWrt" - - local rel = readfile("/etc/openwrt_release") - local os_ver = rel and rel:match("DISTRIB_RELEASE='([^']+)'") - if os_ver then - headers[#headers + 1] = "x-ver-os: " .. os_ver - end - - local model = readfile("/tmp/sysinfo/model") - if model then - headers[#headers + 1] = "x-device-model: " .. model - end - - local mac = readfile("/sys/class/net/eth0/address") - if mac and model then - local raw = mac .. "-" .. model - local p = io.popen("printf '%s' '" .. raw:gsub("'", "'\\''") .. "' | sha256sum") - if p then - local hash = p:read("*l") - p:close() - hash = hash and hash:match("^%w+") - if hash then - headers[#headers + 1] = "x-hwid: " .. hash - end - end - end - - local out = {} - for i = 1, #headers do - out[i] = "-H '" .. headers[i]:gsub("'", "'\\''") .. "'" - end - local headers_str = table.concat(out, " ") - local f = io.open(cache_file, "w"); if f then f:write(headers_str); f:close() end - return headers_str -end - local function truncate_nodes(group) for _, config in pairs(CONFIG) do if config.currentNodes and #config.currentNodes > 0 then diff --git a/luci-app-store/Makefile b/luci-app-store/Makefile index cdc69a4a..10713823 100644 --- a/luci-app-store/Makefile +++ b/luci-app-store/Makefile @@ -5,19 +5,21 @@ include $(TOPDIR)/rules.mk -LUCI_TITLE:=LuCI based ipk store -LUCI_DESCRIPTION:=luci-app-store is a ipk store developed by LinkEase team -LUCI_DEPENDS:=+curl +opkg +tar +libuci-lua +mount-utils +luci-lib-taskd +LUCI_TITLE:=LuCI based ipk/apk store +LUCI_DESCRIPTION:=luci-app-store is a ipk/apk store developed by LinkEase team +LUCI_DEPENDS:=+curl +tar +libuci-lua +mount-utils +luci-lib-taskd +LUCI_DEPENDS+=$(if $(CONFIG_USE_APK),+apk +luci-compat,+opkg) + LUCI_EXTRA_DEPENDS:=luci-lib-taskd (>=1.0.19) LUCI_PKGARCH:=all -PKG_VERSION:=0.1.34-1 +PKG_VERSION:=0.2.0-r1 # PKG_RELEASE MUST be empty for luci.mk PKG_RELEASE:= -ISTORE_UI_VERSION:=0.1.32 +ISTORE_UI_VERSION:=0.2.0 ISTORE_UI_RELEASE:=1 -PKG_HASH:=d4f86a88bfd2d6fdd59d5e7f356c1bd51d333f70271f4f28e45feecee9bc1578 +PKG_HASH:=01f91eec06a3d9125bd74a9a75e457f4fbb591afd9333bd2e9073c2522b79b3d PKG_SOURCE_URL_FILE:=v$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE).tar.gz PKG_SOURCE:=istore-ui-$(PKG_SOURCE_URL_FILE) @@ -27,6 +29,7 @@ PKG_MAINTAINER:=jjm2473 TARGET_CONFIGURE_OPTS= FRONTEND_DIST="$(BUILD_DIR)/istore-ui-$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE)/app-store-ui/src/dist" APP_STORE_VERSION="$(PKG_VERSION)" TARGET_CONFIGURE_OPTS+= SED="$(SED)" +TARGET_CONFIGURE_OPTS+= USE_APK="$(CONFIG_USE_APK)" define Package/luci-app-store/conffiles /etc/.app_store.id diff --git a/luci-app-store/luasrc/controller/store.lua b/luci-app-store/luasrc/controller/store.lua index 90cad52a..3379a93d 100644 --- a/luci-app-store/luasrc/controller/store.lua +++ b/luci-app-store/luasrc/controller/store.lua @@ -166,6 +166,11 @@ end function store_index() local fs = require "nixio.fs" local features = { "_lua_force_array_" } + if fs.access("/etc/apk/arch") then + features[#features+1] = "apk" + else + features[#features+1] = "opkg" + end if fs.access("/usr/libexec/istore/backup") then features[#features+1] = "backup" end @@ -251,7 +256,7 @@ function validate_pkgname(val) end local function get_installed_and_cache() - local metadir = "/usr/lib/opkg/meta" + local metadir = "/tmp/run/istore-meta/meta" local cachedir = "/tmp/cache/istore" local cachefile = cachedir .. "/installed.json" local nixio = require "nixio" @@ -321,7 +326,7 @@ local function get_installed_and_cache() end function store_action(param) - local metadir = "/usr/lib/opkg/meta" + local metadir = "/tmp/run/istore-meta/meta" local metapkgpre = "app-meta-" local code, out, err, ret local fs = require "nixio.fs" diff --git a/luci-app-store/root/bin/is-opkg b/luci-app-store/root/bin/is-opkg index cd25cad2..c088edba 100755 --- a/luci-app-store/root/bin/is-opkg +++ b/luci-app-store/root/bin/is-opkg @@ -10,25 +10,46 @@ if [ "${action:0:9}" = "AUTOCONF=" ]; then fi IS_ROOT=/tmp/is-root -DL_DIR=${IS_ROOT}/tmp/dl -LISTS_DIR_O=/tmp/opkg-lists -LISTS_DIR=${IS_ROOT}${LISTS_DIR_O} -OPKG_CONF_DIR=${IS_ROOT}/etc/opkg -OPKG_CONF_DIR_M=${IS_ROOT}/etc/opkg_m -FEEDS_SERVER=https://istore.istoreos.com/repo -FEEDS_SERVER_MIRRORS="https://repo.istoreos.com/repo" +TMP_SELF_COPY=/var/run/cloned-is-opkg +USE_APK=false DISABLE_MIRROR=false -ARCH=`sed -n -e 's/^Architecture: *\([^ ]\+\) *$/\1/p' /rom/usr/lib/opkg/info/libc.control /usr/lib/opkg/info/libc.control 2>/dev/null | head -1` +if [[ -s /etc/apk/arch ]]; then + USE_APK=true +fi + +if $USE_APK; then + LISTS_DIR=${IS_ROOT}/apk + APK_CONF=${IS_ROOT}/etc/apk.conf + FEEDS_SERVER=https://istore.istoreos.com/repo-apk + FEEDS_SERVER_MIRRORS="https://repo.istoreos.com/repo-apk" + ISTORE_INDEX=$FEEDS_SERVER/all/store/packages.adb + META_DIR=/lib/apk + + ARCH=`cat /rom/etc/apk/arch /etc/apk/arch 2>/dev/null | head -1` +else + LISTS_DIR_O=/tmp/opkg-lists + LISTS_DIR=${IS_ROOT}${LISTS_DIR_O} + OPKG_CONF_DIR=${IS_ROOT}/etc/opkg + OPKG_CONF_DIR_M=${IS_ROOT}/etc/opkg_m + FEEDS_SERVER=https://istore.istoreos.com/repo + FEEDS_SERVER_MIRRORS="https://repo.istoreos.com/repo" + ISTORE_INDEX=$FEEDS_SERVER/all/store/Packages.gz + META_DIR=/usr/lib/opkg + + ARCH=`sed -n -e 's/^Architecture: *\([^ ]\+\) *$/\1/p' /rom/usr/lib/opkg/info/libc.control /usr/lib/opkg/info/libc.control 2>/dev/null | head -1` +fi # for istore self upgrade ISTORE_PKG=luci-app-store ISTORE_DEP_PKGS="luci-lib-taskd luci-lib-xterm taskd" -ISTORE_INDEX=https://istore.istoreos.com/repo/all/store/Packages.gz NEWLINE=$'\n' is_init() { - mkdir -p ${DL_DIR} ${LISTS_DIR} ${IS_ROOT}/etc ${IS_ROOT}/var + mkdir -p ${LISTS_DIR} ${IS_ROOT}/etc ${IS_ROOT}/var + if $USE_APK; then + return 0 + fi cat /etc/opkg.conf | grep -Fv lists_dir | grep -Fv check_signature > ${IS_ROOT}/etc/opkg.conf @@ -44,35 +65,71 @@ is_init() { [ -e ${IS_ROOT}/var/lock ] || ln -s /var/lock ${IS_ROOT}/var/lock } +apk_wrap() { + APK_CONFIG=${APK_CONF} apk "$@" +} + opkg_wrap() { OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@" } -opkg_wrap_mirrors() { +simple_apk_opkg() { + local action="$1" + shift + if $USE_APK; then + case "$action" in + "install") + action=add + ;; + "remove") + action=del + ;; + esac + apk_wrap "$action" "$@" + else + opkg_wrap "$action" "$@" + fi +} + +do_in_mirrors() { local server - local file if ! $DISABLE_MIRROR; then + local newpath="/usr/libexec/istore/mirror-bin:$PATH" for server in $FEEDS_SERVER_MIRRORS ; do - rm -rf "${OPKG_CONF_DIR_M}" 2>/dev/null - mkdir -p "${OPKG_CONF_DIR_M}" 2>/dev/null - ls "${OPKG_CONF_DIR}/" | while read; do - file="$REPLY" - if [ -f "${OPKG_CONF_DIR}/$file" -a "${file: -5}" = ".conf" ]; then - sed "s#$FEEDS_SERVER/#$server/#g" "${OPKG_CONF_DIR}/$file" >"${OPKG_CONF_DIR_M}/$file" - touch -r "${OPKG_CONF_DIR}/$file" "${OPKG_CONF_DIR_M}/$file" 2>/dev/null - else - cp -a "${OPKG_CONF_DIR}/$file" "${OPKG_CONF_DIR_M}/" - fi - done echo "Try mirror server $server" - OPKG_CONF_DIR=${OPKG_CONF_DIR_M} opkg -f ${IS_ROOT}/etc/opkg.conf "$@" && return 0 + PATH="$newpath" IS_ORIG_SERVER=$FEEDS_SERVER IS_MIRROR_SERVER=$server "$@" && return 0 done DISABLE_MIRROR=true fi echo "Try origin server $FEEDS_SERVER" - OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@" + "$@" } +apk_wrap_mirrors() { + do_in_mirrors apk_wrap "$@" +} + +opkg_wrap_mirrors() { + do_in_mirrors opkg_wrap "$@" +} + +do_install_in_mirrors() { + if $USE_APK; then + apk_wrap_mirrors add "$@" + else + opkg_wrap_mirrors install "$@" + fi +} + +do_upgrade_in_mirrors() { + if $USE_APK; then + apk_wrap_mirrors upgrade "$@" + else + opkg_wrap_mirrors upgrade "$@" + fi +} + + alias fcurl='curl -L --fail --show-error' check_space() { @@ -91,14 +148,41 @@ update() { fi echo "Fetch feed list for ${ARCH}" - fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \ - fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \ - fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" || \ - return 1 + if $USE_APK; then + rm -rf ${IS_ROOT}/var/tmp ${IS_ROOT}/etc/arch ${IS_ROOT}/etc/istore.pem + mkdir -p ${IS_ROOT}/var/tmp + fcurl --no-progress-meter -o ${IS_ROOT}/var/tmp/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \ + fcurl --no-progress-meter -o ${IS_ROOT}/var/tmp/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \ + fcurl --no-progress-meter -o ${IS_ROOT}/var/tmp/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" && \ + fcurl --no-progress-meter -o ${IS_ROOT}/etc/arch "${FEEDS_SERVER}/${ARCH}/archlist.conf" || \ + return 1 + echo "cache-dir $LISTS_DIR" > ${APK_CONF} + cat ${IS_ROOT}/var/tmp/arch.conf ${IS_ROOT}/var/tmp/all.conf ${IS_ROOT}/var/tmp/meta.conf >> ${APK_CONF} + local line + while read -r line; do + if [[ -n "$line" ]]; then + grep -Fxq "$line" /etc/apk/arch || echo "$line" >> /etc/apk/arch + fi + done < ${IS_ROOT}/etc/arch + sync /etc/apk/arch + if [[ ! -s /etc/apk/keys/istore.pem && ! -s /etc/apk/keys/istore-tmp.pem ]]; then + fcurl --no-progress-meter -o ${IS_ROOT}/etc/istore.pem "${FEEDS_SERVER}/istore-apk.pem" && \ + cp -a ${IS_ROOT}/etc/istore.pem /etc/apk/keys/istore-tmp.pem || \ + return 1 + fi + else + fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \ + fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \ + fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" || \ + return 1 + fi echo "Update feeds index" - opkg -f ${IS_ROOT}/etc/opkg_o.conf --offline-root ${IS_ROOT} update - + if $USE_APK; then + apk_wrap update + else + opkg -f ${IS_ROOT}/etc/opkg_o.conf --offline-root ${IS_ROOT} update + fi return 0 } @@ -110,9 +194,30 @@ update_if_outdate() { return 0 } +get_online_version() { + local index="$1" + local pkg="$2" + if $USE_APK; then + apk --cache-dir $LISTS_DIR --cache-max-age 0 --repositories-file /dev/null --repository "$index" update >/dev/null 2>&1 + local ver=$(apk --cache-dir $LISTS_DIR --cache-max-age 0 --repositories-file /dev/null --repository "$index" query --available --fields version "$pkg" 2>/dev/null | grep -Fm1 'Version: ' | sed 's/^Version: //') + echo "${ver:-0.2.0-r1}" + else + curl --connect-timeout 2 --max-time 5 -s "$index" | gunzip | grep -FA10 "Package: $pkg" | grep -Fm1 'Version: ' | sed 's/^Version: //' + fi +} + +get_local_version() { + local pkg="$1" + if $USE_APK; then + apk query --installed --fields version "$pkg" 2>/dev/null | grep -Fm1 'Version: ' | sed 's/^Version: //' + else + grep -Fm1 'Version: ' /usr/lib/opkg/info/$pkg.control 2>/dev/null | sed 's/^Version: //' + fi +} + check_self_upgrade() { - local newest=`curl --connect-timeout 2 --max-time 5 -s ${ISTORE_INDEX} | gunzip | grep -FA10 "Package: ${ISTORE_PKG}" | grep -Fm1 'Version: ' | sed 's/^Version: //'` - local current=`grep -Fm1 'Version: ' /usr/lib/opkg/info/${ISTORE_PKG}.control | sed 's/^Version: //'` + local newest=`get_online_version "$ISTORE_INDEX" "$ISTORE_PKG"` + local current=`get_local_version "$ISTORE_PKG"` if [ "v$newest" = "v" -o "v$current" = "v" ]; then echo "Check version failed!" >&2 exit 255 @@ -124,13 +229,13 @@ check_self_upgrade() { } do_self_upgrade_0() { - opkg_wrap upgrade ${ISTORE_DEP_PKGS} && opkg_wrap upgrade ${ISTORE_PKG} + simple_apk_opkg upgrade ${ISTORE_DEP_PKGS} && simple_apk_opkg upgrade ${ISTORE_PKG} } do_self_upgrade() { check_mtime || return 1 - local newest=`curl --connect-timeout 2 --max-time 5 -s ${ISTORE_INDEX} | gunzip | grep -FA10 "Package: ${ISTORE_PKG}" | grep -Fm1 'Version: ' | sed 's/^Version: //'` - local current=`grep -Fm1 'Version: ' /usr/lib/opkg/info/${ISTORE_PKG}.control | sed 's/^Version: //'` + local newest=`get_online_version "$ISTORE_INDEX" "$ISTORE_PKG"` + local current=`get_local_version "$ISTORE_PKG"` if [ "v$newest" = "v" -o "v$current" = "v" ]; then echo "Check version failed!" >&2 return 1 @@ -139,7 +244,7 @@ do_self_upgrade() { echo "Already the latest version!" >&2 return 1 fi - if opkg_wrap info ${ISTORE_PKG} | grep -qFm1 "Version: $newest"; then + if $USE_APK || opkg_wrap info ${ISTORE_PKG} | grep -qFm1 "Version: $newest"; then do_self_upgrade_0 && return 0 update_if_outdate || return 1 do_self_upgrade_0 @@ -150,7 +255,13 @@ do_self_upgrade() { } check_mtime() { - find ${OPKG_CONF_DIR}/arch.conf -mtime -1 2>/dev/null | grep -q . || update + local file + if $USE_APK; then + file=${APK_CONF} + else + file=${OPKG_CONF_DIR}/arch.conf + fi + find "$file" -mtime -1 2>/dev/null | grep -q . || update } wrapped_in_update() { @@ -164,7 +275,7 @@ refresh_installed() { local pkg for pkg in $@; do [[ $pkg == app-meta-* ]] || continue - pkg="/usr/lib/opkg/meta/${pkg#app-meta-}.json" + pkg="$META_DIR/meta/${pkg#app-meta-}.json" [[ -f "$pkg" ]] && touch "$pkg" done return 0 @@ -182,10 +293,10 @@ step_upgrade() { fi done if [ -n "$pkgs" ]; then - opkg_wrap_mirrors upgrade $pkgs || return 1 + do_upgrade_in_mirrors $pkgs || return 1 fi if [ -n "$metapkg" ]; then - opkg_wrap_mirrors upgrade $metapkg || return 1 + do_upgrade_in_mirrors $metapkg || return 1 refresh_installed $metapkg fi return 0 @@ -194,7 +305,7 @@ step_upgrade() { new_upgrade() { check_mtime || return 1 local metapkg=`echo "$@" | sed 's/ /\n/g' | grep -F app-meta-` - if [ -z "$metapkg" ] || opkg_wrap info $metapkg | grep -qF not-installed ; then + if [[ -z "$metapkg" ]] || [[ -z "$(get_local_version $metapkg)" ]]; then true else update_if_outdate @@ -203,7 +314,11 @@ new_upgrade() { } remove() { - opkg_wrap --autoremove --force-removal-of-dependent-packages remove "$@" + if $USE_APK; then + apk_wrap del -r "$@" + else + opkg_wrap --autoremove --force-removal-of-dependent-packages remove "$@" + fi } autoconf_to_env() { @@ -235,16 +350,29 @@ try_autoconf() { PATH="$CLEANPATH" /usr/libexec/istorea/${ISTORE_AUTOCONF}.sh } + try_upgrade_depends() { local pkg="$1" if [[ $pkg == app-meta-* ]]; then - local deps=$(grep '^Depends: ' /usr/lib/opkg/info/$pkg.control | busybox sed -e 's/^Depends: //' -e 's/,/\n/g' -e 's/ //g' | grep -vFw libc | xargs echo) - [ -z "$deps" ] || opkg_wrap_mirrors install $deps + local deps + if $USE_APK; then + deps=$(apk --repositories-file /dev/null info -R "$pkg" | tail +2 | grep -vFw libc | xargs echo) + else + deps=$(grep '^Depends: ' "/usr/lib/opkg/info/$pkg.control" | busybox sed -e 's/^Depends: //' -e 's/,/\n/g' -e 's/ //g' | grep -vFw libc | xargs echo) + fi + [ -z "$deps" ] || do_install_in_mirrors $deps fi return 0 } -CMD_INSTALLED="opkg list-installed | cut -d' ' -f1 | sort -u" +if $USE_APK; then + CMD_INSTALLED="apk --repositories-file /dev/null info | cut -d' ' -f1 | sort -u" + CMD_INSTALL="apk add --allow-untrusted" +else + CMD_INSTALLED="opkg list-installed | cut -d' ' -f1 | sort -u" + CMD_INSTALL="opkg install" +fi + dotrun() { local path="$1" [ -f "$path" ] || { echo "file not found: $path" >&2; return 1; } @@ -259,8 +387,8 @@ dotrun() { echo "Executing .run file" chmod 0755 "$path" && "$path" else - echo "Installing .ipk file" - opkg install "$path" + echo "Installing pkg file" + $CMD_INSTALL "$path" fi local RET=$? rm -f "$path" @@ -297,6 +425,13 @@ run_records() { echo "]" } + +if $USE_APK; then + CMD_REMOVE="apk del" +else + CMD_REMOVE="opkg --autoremove remove" +fi + unrun() { local id="$1" [ -s "/usr/share/istore/run-records/$id.txt" ] || { echo "record not found: $id" >&2; return 1; } @@ -306,9 +441,9 @@ unrun() { local round max_round=6 for round in `seq 1 $max_round`; do if [ $round == $max_round ]; then - opkg --autoremove remove `cat "/tmp/is-root/tmp/to_unrun_$id.txt"` + $CMD_REMOVE `cat "/tmp/is-root/tmp/to_unrun_$id.txt"` else - opkg --autoremove remove `cat "/tmp/is-root/tmp/to_unrun_$id.txt"` 2>/dev/null && break + $CMD_REMOVE `cat "/tmp/is-root/tmp/to_unrun_$id.txt"` 2>/dev/null && break fi done sh -c "$CMD_INSTALLED" > "/tmp/is-root/tmp/post_unrun_$id.txt" @@ -338,13 +473,19 @@ usage() { echo " do_self_upgrade Upgrade iStore" echo " arch Show libc architecture" echo " opkg sys opkg wrap" - echo " dotrun {path} install .run/.ipk" - echo " run_records list .run/.ipk install records" - echo " del_record {id} delete .run/.ipk install record" - echo " unrun {id} Remove installed packages by .run/.ipk" + echo " dotrun {path} install .run/.ipk/.apk" + echo " run_records list .run/.ipk/.apk install records" + echo " del_record {id} delete .run/.ipk/.apk install record" + echo " unrun {id} Remove installed packages by .run/.ipk/.apk" exit 1 } +if [[ "$action" = "do_self_upgrade" && "$0" != "$TMP_SELF_COPY" ]]; then + echo "copy self $0 to $TMP_SELF_COPY when self upgrade" + cp -af "$0" "$TMP_SELF_COPY" || exit 1 + exec "$TMP_SELF_COPY" do_self_upgrade "$@" || exit 1 +fi + is_init >/dev/null 2>&1 CLEANPATH="$PATH" @@ -363,7 +504,7 @@ case $action in ;; "install") check_space - wrapped_in_update opkg_wrap_mirrors install "$@" && refresh_installed "$1" && try_upgrade_depends "$1" && try_autoconf + wrapped_in_update do_install_in_mirrors "$@" && refresh_installed "$1" && try_upgrade_depends "$1" && try_autoconf ;; "autoconf") try_autoconf @@ -375,10 +516,18 @@ case $action in remove "$@" || remove "$@" ;; "info") - opkg_wrap info "$@" + if $USE_APK; then + apk_wrap query "$@" + else + opkg_wrap info "$@" + fi ;; "list-upgradable") - opkg_wrap list-upgradable + if $USE_APK; then + apk_wrap query --upgradable --summarize package '*' + else + opkg_wrap list-upgradable + fi ;; "check_self_upgrade") check_self_upgrade @@ -405,6 +554,11 @@ case $action in "unrun") unrun "$1" ;; + "link_meta") + [[ -d "$META_DIR/meta" ]] || mkdir -p "$META_DIR/meta" + mkdir -p /tmp/run/istore + ln -sf "$META_DIR" /tmp/run/istore-meta + ;; *) usage ;; diff --git a/luci-app-store/root/etc/init.d/istore b/luci-app-store/root/etc/init.d/istore index a7aa1a1a..eb2dc748 100755 --- a/luci-app-store/root/etc/init.d/istore +++ b/luci-app-store/root/etc/init.d/istore @@ -7,6 +7,7 @@ boot() { local ARCH=`/bin/is-opkg arch` generate_store_id $ARCH generate_super_arch $ARCH + /bin/is-opkg link_meta } generate_store_id() { diff --git a/luci-app-store/root/etc/uci-defaults/luci-app-store b/luci-app-store/root/etc/uci-defaults/luci-app-store index 005eb24a..02f22195 100644 --- a/luci-app-store/root/etc/uci-defaults/luci-app-store +++ b/luci-app-store/root/etc/uci-defaults/luci-app-store @@ -9,4 +9,7 @@ if [ -z "`uci -q get istore.istore.hide_docker`" ] && ! which docker >/dev/null; EOF fi +# remove tmp keys that used for self-installation, which is not needed after installation +rm -f /etc/apk/keys/istore-tmp.pem + rm -rf /tmp/luci-indexcache /tmp/luci-modulecache diff --git a/luci-app-store/root/usr/libexec/istore/backup b/luci-app-store/root/usr/libexec/istore/backup index acd9cd31..f4db68a8 100755 --- a/luci-app-store/root/usr/libexec/istore/backup +++ b/luci-app-store/root/usr/libexec/istore/backup @@ -5,11 +5,12 @@ IS_ROOT=/tmp/is-backup APP_LIST_FILE=/etc/istore/app.list BACKUP_CONFIG_FILE=/etc/config/istore +USE_APK=false +[[ -s /etc/apk/arch ]] && USE_APK=true action=${1} shift - is_init() { mkdir -p ${IS_ROOT} } @@ -90,23 +91,23 @@ ipk_build() { # if arg is NULL, use light backup, otherwise use local backup backup() { - [ -n "$1" ] && BACKUP_PATH=$1 + if [ -n "$1" ]; then + if $USE_APK; then + echo "does not support apk package manager" >&2 + exit 1 + fi + BACKUP_PATH=$1 + fi - #1.add all istore self data to sysupgrade config file, - #sysupgrade will backup/restore it auto when flash new firmware - echo "/etc/.app_store.id" > /lib/upgrade/keep.d/luci-app-store - cat /usr/lib/opkg/info/luci-app-store.list >> /lib/upgrade/keep.d/luci-app-store - echo "/etc/rc.d/S45istore" >> /lib/upgrade/keep.d/luci-app-store - echo "/etc/istore/uci-defaults_bak" >> /lib/upgrade/keep.d/luci-app-store - echo "${APP_LIST_FILE}" >> /lib/upgrade/keep.d/luci-app-store - echo "${BACKUP_CONFIG_FILE}" >> /lib/upgrade/keep.d/luci-app-store - - #write user installed package list to file - opkg_list_installed_packages "userinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/user_installed_package.list - - #write installed package list by istore feed to file - cat ${IS_ROOT}/user_installed_package.list | \ - grep '^app-meta-' > ${IS_ROOT}/istore_installed_package.list + if $USE_APK; then + ( cd /lib/apk/packages && ls *.list ) | grep '^app-meta-' | sed 's/.list$//' | sort -u > ${IS_ROOT}/istore_installed_package.list + else + #write user installed package list to file + opkg_list_installed_packages "userinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/user_installed_package.list + #write installed package list by istore feed to file + cat ${IS_ROOT}/user_installed_package.list | \ + grep '^app-meta-' > ${IS_ROOT}/istore_installed_package.list + fi #if no input backup path, only back app.list mkdir -p /etc/istore @@ -186,6 +187,10 @@ backup() { # if arg is NULL, use light backup, otherwise use local backup restore() { if [ -n "$1" ]; then + if $USE_APK; then + echo "does not support apk package manager" >&2 + exit 1 + fi BACKUP_PATH_FILE=$1 else echo "install package by ${APP_LIST_FILE}" @@ -233,7 +238,7 @@ restore() { get_support_backup_features() { echo "light_backup" #istore custom img mean support local_backup - if [ -f /etc/istore_img_flag ];then + if ! $USE_APK; then echo "local_backup" fi } diff --git a/luci-app-store/root/usr/libexec/istore/mirror-bin/curl b/luci-app-store/root/usr/libexec/istore/mirror-bin/curl new file mode 100755 index 00000000..80335d67 --- /dev/null +++ b/luci-app-store/root/usr/libexec/istore/mirror-bin/curl @@ -0,0 +1,18 @@ +#!/bin/sh + +newpath=$(echo ":$PATH:" | sed -e 's#:/usr/libexec/istore/mirror-bin:#:#g' -e 's/^:*//' -e 's/:*$//') +[ -z "$newpath" ] && newpath="/usr/sbin:/usr/bin:/sbin:/bin" + +export PATH="$newpath" + +# if url starts with $IS_ORIG_SERVER, replace it with $IS_MIRROR_SERVER +if [ -n "$IS_ORIG_SERVER" ] && [ -n "$IS_MIRROR_SERVER" ]; then + for i in "$@"; do + if [[ "$i" == "$IS_ORIG_SERVER"* ]]; then + set -- "${@/$i/$IS_MIRROR_SERVER${i#$IS_ORIG_SERVER}}" + fi + done +fi +export -n IS_ORIG_SERVER IS_MIRROR_SERVER + +exec curl "$@" diff --git a/luci-app-store/root/usr/libexec/istore/mirror-bin/wget b/luci-app-store/root/usr/libexec/istore/mirror-bin/wget new file mode 100755 index 00000000..62cf8f38 --- /dev/null +++ b/luci-app-store/root/usr/libexec/istore/mirror-bin/wget @@ -0,0 +1,18 @@ +#!/bin/sh + +newpath=$(echo ":$PATH:" | sed -e 's#:/usr/libexec/istore/mirror-bin:#:#g' -e 's/^:*//' -e 's/:*$//') +[ -z "$newpath" ] && newpath="/usr/sbin:/usr/bin:/sbin:/bin" + +export PATH="$newpath" + +# if url starts with $IS_ORIG_SERVER, replace it with $IS_MIRROR_SERVER +if [ -n "$IS_ORIG_SERVER" ] && [ -n "$IS_MIRROR_SERVER" ]; then + for i in "$@"; do + if [[ "$i" == "$IS_ORIG_SERVER"* ]]; then + set -- "${@/$i/$IS_MIRROR_SERVER${i#$IS_ORIG_SERVER}}" + fi + done +fi +export -n IS_ORIG_SERVER IS_MIRROR_SERVER + +exec wget "$@" diff --git a/luci-app-store/src/Makefile b/luci-app-store/src/Makefile index 8d61b39e..e48055e8 100644 --- a/luci-app-store/src/Makefile +++ b/luci-app-store/src/Makefile @@ -10,13 +10,17 @@ include $(TOPDIR)/feeds/luci/luci.mk install: [ -n "$(APP_STORE_VERSION)" ] - mkdir -p "$(DESTDIR)/www/luci-static" + mkdir -p "$(DESTDIR)/www/luci-static" "$(DESTDIR)/etc" cp -a "$(FRONTEND_DIST)/luci-static/istore" "$(DESTDIR)/www/luci-static/" $(SED) 's#\.js"#.js?v=$(APP_STORE_VERSION)"#g' "$(DESTDIR)/www/luci-static/istore/index.js" - mkdir -p "$(DESTDIR)/etc/opkg/keys" echo "$(APP_STORE_VERSION)" > "$(DESTDIR)/etc/.app_store.version" - cp -a ./compat.conf "$(DESTDIR)/etc/opkg/compatfeeds.conf" +ifneq ($(USE_APK),) + cp -pR ./root-apk/* "$(DESTDIR)/" +else + cp -pR ./root-opkg/* "$(DESTDIR)/" + mkdir -p "$(DESTDIR)/etc/opkg/keys" cp -a ./key-build.pub $(DESTDIR)/etc/opkg/keys/`$(STAGING_DIR_HOST)/bin/usign -F -p ./key-build.pub` +endif mkdir -p "$(DESTDIR)$(LUCI_LIBRARYDIR)/i18n" $(foreach lang,$(LUCI_LANGUAGES),$(foreach po,$(wildcard ${CURDIR}/po/$(lang)/*.po), \ po2lmo $(po) \ diff --git a/luci-app-store/src/root-apk/etc/apk/keys/istore.pem b/luci-app-store/src/root-apk/etc/apk/keys/istore.pem new file mode 100644 index 00000000..81070b0d --- /dev/null +++ b/luci-app-store/src/root-apk/etc/apk/keys/istore.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEybK5eaXsrK06Thc1dbA3FC45Tlp8 +8X5Z831vU6JggiV6tJiwI/B05IsdklTaZE8SYh0XCHcnXSjzRMLtarBisg== +-----END PUBLIC KEY----- diff --git a/luci-app-store/src/root-apk/etc/apk/repositories.d/compat.list b/luci-app-store/src/root-apk/etc/apk/repositories.d/compat.list new file mode 100644 index 00000000..4c83d106 --- /dev/null +++ b/luci-app-store/src/root-apk/etc/apk/repositories.d/compat.list @@ -0,0 +1 @@ +https://istore.istoreos.com/repo-apk/all/compat/packages.adb diff --git a/luci-app-store/src/compat.conf b/luci-app-store/src/root-opkg/etc/opkg/compatfeeds.conf similarity index 100% rename from luci-app-store/src/compat.conf rename to luci-app-store/src/root-opkg/etc/opkg/compatfeeds.conf diff --git a/luci-app-store/root/usr/libexec/istore/ipkg-build b/luci-app-store/src/root-opkg/usr/libexec/istore/ipkg-build similarity index 100% rename from luci-app-store/root/usr/libexec/istore/ipkg-build rename to luci-app-store/src/root-opkg/usr/libexec/istore/ipkg-build diff --git a/luci-app-store/root/usr/share/opkg/intercept/rm b/luci-app-store/src/root-opkg/usr/share/opkg/intercept/rm similarity index 100% rename from luci-app-store/root/usr/share/opkg/intercept/rm rename to luci-app-store/src/root-opkg/usr/share/opkg/intercept/rm diff --git a/tuic-client/Makefile b/tuic-client/Makefile index 7efa98f8..dcd10597 100644 --- a/tuic-client/Makefile +++ b/tuic-client/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=tuic-client -PKG_VERSION:=1.8.6 +PKG_VERSION:=1.8.7 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/Itsusinn/tuic/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=2ddd401f414aa7e6fa52d711e234edcc11646a79a65eda781023d003aa1e06c3 +PKG_HASH:=d393071e5e840d3e3440b28c8b175d40e939699f610815da0ace171037a44028 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) PKG_MAINTAINER:=Tianling Shen diff --git a/v2ray-geodata/Makefile b/v2ray-geodata/Makefile index 6c599c63..1f3e6b7c 100644 --- a/v2ray-geodata/Makefile +++ b/v2ray-geodata/Makefile @@ -21,13 +21,13 @@ define Download/geoip HASH:=a322dfb6bfd8987c83453c39582a07771c9deddf9f8f7d2d19c7927ebd5e76c8 endef -GEOSITE_VER:=20260614143513 +GEOSITE_VER:=20260616073835 GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) define Download/geosite URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL_FILE:=dlc.dat FILE:=$(GEOSITE_FILE) - HASH:=7452b05d903867db8f3b3ace0c462b6033b37bef0b842a60133e5c6f91d3ef5d + HASH:=b42bbf00f29270806e088f7402298f6f02932caef159f69d5a1ee5d18acd7496 endef GEOSITE_IRAN_VER:=202606150209