package lienol: update

This commit is contained in:
CN_SZTL 2019-12-07 17:12:35 +08:00
parent e017119564
commit 1a20f96cf8
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
54 changed files with 4970 additions and 1443 deletions

View File

@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=3.0
PKG_RELEASE:=115-20191201
PKG_RELEASE:=120-20191207
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PO2LMO:=./po2lmo
@ -77,19 +77,19 @@ endmenu
endef
define Package/$(PKG_NAME)
CATEGORY:=LuCI
CATEGORY:=LuCI for Lienol
SUBMENU:=3. Applications
TITLE:=LuCI support for PassWall By Lienol
PKGARCH:=all
DEPENDS:=+curl +libcurl +libmbedtls +ca-bundle +ca-certificates +resolveip +iptables-mod-tproxy +kmod-ipt-tproxy +iptables-mod-ipopt +kmod-ipt-ipopt +ip +ipset +coreutils +coreutils-base64 +coreutils-nohup +luci-lib-jsonc +unzip \
+dnsmasq-full \
+dnsmasq-full +tcping \
+PACKAGE_$(PKG_NAME)_INCLUDE_redsocks2:redsocks2 \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR:shadowsocksr-libev-alt \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_socks:shadowsocks-libev-ss-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_socks:shadowsocksr-libev-ssr-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan +redsocks2 \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
+PACKAGE_$(PKG_NAME)_INCLUDE_Brook:brook \
+PACKAGE_$(PKG_NAME)_INCLUDE_kcptun:kcptun-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_haproxy:haproxy \
@ -110,17 +110,25 @@ endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/usr/share/passwall
$(INSTALL_CONF) ./root/etc/config/passwall $(1)/etc/config/passwall
$(INSTALL_CONF) ./root/etc/config/passwall_show $(1)/etc/config/passwall_show
$(INSTALL_DIR) $(1)/etc/config/passwall_rule
cp -pR ./root/etc/config/passwall_rule/* $(1)/etc/config/passwall_rule/
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_CONF) ./root/etc/uci-defaults/* $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./root/etc/init.d/passwall $(1)/etc/init.d/passwall
$(INSTALL_DIR) $(1)/usr/share/passwall
cp -pR ./root/usr/share/passwall/* $(1)/usr/share/passwall
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci/
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
cp -pR ./root/usr/share/passwall/* $(1)/usr/share/passwall
chmod 755 $(PO2LMO)
$(PO2LMO) ./po/zh-cn/passwall.po $(1)/usr/lib/lua/luci/i18n/passwall.zh-cn.lmo
endef

View File

@ -179,21 +179,37 @@ function connect_status()
end
function auto_ping_node()
local index = luci.http.formvalue("index")
local address = luci.http.formvalue("address")
local port = luci.http.formvalue("port")
local e = {}
e.index = luci.http.formvalue("index")
e.ping = luci.sys.exec(
"ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print$2}'" %
luci.http.formvalue("domain"))
e.index = index
if luci.sys.exec("echo -n `command -v tcping`") ~= "" then
e.ping = luci.sys.exec("tcping -q -c 1 -i 3 -p " .. port .. " " ..
address ..
" 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print$2}'")
else
e.ping = luci.sys.exec(
"ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print$2}'" %
address)
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function ping_node()
local e = {}
local node = luci.http.formvalue("node")
e.ping = luci.sys.exec(
"echo -n `ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print$2}'`" %
node)
local address = luci.http.formvalue("address")
local port = luci.http.formvalue("port")
if luci.sys.exec("echo -n `command -v tcping`") ~= "" then
e.ping = luci.sys.exec("tcping -q -c 1 -i 3 -p " .. port .. " " ..
address ..
" 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print$2}'")
else
e.ping = luci.sys.exec(
"echo -n `ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print$2}'`" %
address)
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
@ -229,20 +245,53 @@ function copy_node()
end
function check_port()
local retstring = "<br />"
retstring = retstring ..
"<font color='red'>暂时不支持UDP检测</font><br />"
local s
local node_name = ""
local uci = luci.model.uci.cursor()
uci:foreach("passwall", "nodes", function(s)
local ret = ""
local tcp_socket
local udp_socket
if (s.use_kcp and s.use_kcp == "1" and s.kcp_port) or
(s.v2ray_transport and s.v2ray_transport == "mkcp" and s.port) then
--[[local port = (s.use_kcp == "1" and s.kcp_port) and s.kcp_port or (s.v2ray_transport == "mkcp" and s.port) and s.port or nil
local retstring = "<br />"
retstring = retstring ..
"<font color='red'>暂时不支持UDP检测</font><br />"
if luci.sys.exec("echo -n `command -v tcping`") ~= "" then
retstring = retstring ..
"<font color='green'>使用tcping检测端口延迟</font><br />"
uci:foreach("passwall", "nodes", function(s)
local ret = ""
local tcp_socket
if (s.use_kcp and s.use_kcp == "1" and s.kcp_port) or
(s.v2ray_transport and s.v2ray_transport == "mkcp" and s.port) then
else
if s.type and s.address and s.port and s.remarks then
node_name = "[%s] [%s:%s]" %
{s.remarks, s.address, s.port}
end
result = luci.sys.exec("tcping -q -c 1 -i 3 -p " .. s.port ..
" " .. s.address ..
" 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print$2}'")
if result and result ~= "" then
retstring =
retstring .. "<font color='green'>" .. node_name ..
" " .. result .. "ms.</font><br />"
else
retstring =
retstring .. "<font color='red'>" .. node_name ..
" Error.</font><br />"
end
ret = ""
end
end)
else
retstring = retstring ..
"<font color='green'>使用socket检测端口是否打开</font><br />"
uci:foreach("passwall", "nodes", function(s)
local ret = ""
local tcp_socket
local udp_socket
if (s.use_kcp and s.use_kcp == "1" and s.kcp_port) or
(s.v2ray_transport and s.v2ray_transport == "mkcp" and s.port) then
--[[local port = (s.use_kcp == "1" and s.kcp_port) and s.kcp_port or (s.v2ray_transport == "mkcp" and s.port) and s.port or nil
if port then
udp_socket = nixio.socket("inet", "dgram")
udp_socket:setopt("socket", "rcvtimeo", 3)
@ -251,27 +300,30 @@ function check_port()
r,c,d=udp_socket:recvfrom(10)
ret=""
end--]]
else
if s.type and s.address and s.port and s.remarks then
node_name = "%s[%s] %s:%s" %
{s.type, s.remarks, s.address, s.port}
end
tcp_socket = nixio.socket("inet", "stream")
tcp_socket:setopt("socket", "rcvtimeo", 3)
tcp_socket:setopt("socket", "sndtimeo", 3)
ret = tcp_socket:connect(s.address, s.port)
if tostring(ret) == "true" then
retstring = retstring .. "<font color='green'>" .. node_name ..
" OK.</font><br />"
else
retstring = retstring .. "<font color='red'>" .. node_name ..
" Error.</font><br />"
if s.type and s.address and s.port and s.remarks then
node_name = "%s[%s] %s:%s" %
{s.type, s.remarks, s.address, s.port}
end
tcp_socket = nixio.socket("inet", "stream")
tcp_socket:setopt("socket", "rcvtimeo", 3)
tcp_socket:setopt("socket", "sndtimeo", 3)
ret = tcp_socket:connect(s.address, s.port)
if tostring(ret) == "true" then
retstring =
retstring .. "<font color='green'>" .. node_name ..
" OK.</font><br />"
else
retstring =
retstring .. "<font color='red'>" .. node_name ..
" Error.</font><br />"
end
ret = ""
end
ret = ""
end
if tcp_socket then tcp_socket:close() end
if udp_socket then udp_socket:close() end
end)
if tcp_socket then tcp_socket:close() end
if udp_socket then udp_socket:close() end
end)
end
luci.http.prepare_content("application/json")
luci.http.write_json({ret = retstring})
end

View File

@ -17,10 +17,7 @@ end)
m = Map("passwall")
-- [[ Haproxy Settings ]]--
s = m:section(TypedSection, "global_haproxy", translate("Load Balancing"),
"<input type='button' class='cbi-button cbi-input-reload' value='" ..
translate("Click here to setting your Load Balancing") ..
"' onclick=javascript:window.open('http://koolshare.cn/thread-65561-1-1.html','target'); />")
s = m:section(TypedSection, "global_haproxy", translate("Load Balancing"))
s.anonymous = true
---- Balancing Enable
@ -46,7 +43,8 @@ o.default = "1188"
o:depends("balancing_enable", 1)
---- Haproxy Port
o = s:option(Value, "haproxy_port", translate("Haproxy Port"))
o = s:option(Value, "haproxy_port", translate("Haproxy Port"), translate(
"Configure this node with 127.0.0.1: this port"))
o.default = "1181"
o:depends("balancing_enable", 1)

View File

@ -90,7 +90,8 @@ for i = 1, socks5_node_num, 1 do
end
---- DNS Forward Mode
o = s:option(ListValue, "dns_mode", translate("DNS Forward Mode"))
o = s:option(ListValue, "dns_mode", translate("DNS Forward Mode"),
translate("if you use no patterns are used, DNS of wan will be used by default as upstream of dnsmasq"))
o.rmempty = false
o:reset_values()
if is_installed("openwrt_chinadns") or is_finded("chinadns") then
@ -106,6 +107,7 @@ if is_installed("pdnsd") or is_installed("pdnsd-alt") or is_finded("pdnsd") then
o:value("pdnsd", "pdnsd")
end
o:value("local_7913", translate("Use local port 7913 as DNS"))
o:value("nonuse", translate("No patterns are used"))
---- upstreamm DNS Server for ChinaDNS
o = s:option(ListValue, "up_chinadns_mode",

View File

@ -79,7 +79,7 @@ o.cfgvalue = function(t, n)
end--]]
---- Ping
o = s:option(DummyValue, "address", translate("Ping"))
o = s:option(DummyValue, "ping", translate("Ping"))
if api.uci_get_type("global_other", "auto_ping", "0") == "0" then
o.template = "passwall/node_list/ping"
else

View File

@ -6,7 +6,7 @@ s = m:section(TypedSection, "global", translate("Set Blacklist And Whitelist"))
s.anonymous = true
---- Whitelist Hosts
local t = "/usr/share/passwall/rule/whitelist_host"
local t = "/etc/config/passwall_rule/whitelist_host"
o = s:option(TextValue, "whitelist_host", translate("Whitelist Hosts"))
o.description = translate(
"Join the white list of domain names will not go agent.")
@ -16,7 +16,7 @@ o.cfgvalue = function(a, a) return fs.readfile(t) or "" end
o.write = function(o, o, a)
fs.writefile("/tmp/whitelist_host", a:gsub("\r\n", "\n"))
if (luci.sys.call(
"cmp -s /tmp/whitelist_host /usr/share/passwall/rule/whitelist_host") ==
"cmp -s /tmp/whitelist_host /etc/config/passwall_rule/whitelist_host") ==
1) then
fs.writefile(t, a:gsub("\r\n", "\n"))
luci.sys.call("rm -f /tmp/dnsmasq.d/whitelist_host.conf >/dev/null")
@ -25,7 +25,7 @@ o.write = function(o, o, a)
end
---- Whitelist IP
local t = "/usr/share/passwall/rule/whitelist_ip"
local t = "/etc/config/passwall_rule/whitelist_ip"
o = s:option(TextValue, "whitelist_ip", translate("Whitelist IP"))
o.description = translate(
"These had been joined ip addresses will not use proxy.Please input the ip address or ip address segment,every line can input only one ip address.For example,112.123.134.145/24 or 112.123.134.145.")
@ -35,7 +35,7 @@ o.cfgvalue = function(a, a) return fs.readfile(t) or "" end
o.write = function(o, o, a) fs.writefile(t, a:gsub("\r\n", "\n")) end
---- Blacklist Hosts
local t = "/usr/share/passwall/rule/blacklist_host"
local t = "/etc/config/passwall_rule/blacklist_host"
o = s:option(TextValue, "blacklist_host", translate("Blacklist Hosts"))
o.description = translate(
"These had been joined websites will use proxy.Please input the domain names of websites,every line can input only one website domain.For example,google.com.")
@ -45,7 +45,7 @@ o.cfgvalue = function(a, a) return fs.readfile(t) or "" end
o.write = function(o, o, a)
fs.writefile("/tmp/blacklist_host", a:gsub("\r\n", "\n"))
if (luci.sys.call(
"cmp -s /tmp/blacklist_host /usr/share/passwall/rule/blacklist_host") ==
"cmp -s /tmp/blacklist_host /etc/config/passwall_rule/blacklist_host") ==
1) then
fs.writefile(t, a:gsub("\r\n", "\n"))
luci.sys.call("rm -f /tmp/dnsmasq.d/blacklist_host.conf >/dev/null")
@ -54,7 +54,7 @@ o.write = function(o, o, a)
end
---- Blacklist IP
local t = "/usr/share/passwall/rule/blacklist_ip"
local t = "/etc/config/passwall_rule/blacklist_ip"
o = s:option(TextValue, "blacklist_ip", translate("Blacklist IP"))
o.description = translate(
"These had been joined ip addresses will use proxy.Please input the ip address or ip address segment,every line can input only one ip address.For example,112.123.134.145/24 or 112.123.134.145.")
@ -64,7 +64,7 @@ o.cfgvalue = function(a, a) return fs.readfile(t) or "" end
o.write = function(o, o, a) fs.writefile(t, a:gsub("\r\n", "\n")) end
---- Router Hosts
local t = "/usr/share/passwall/rule/router"
local t = "/etc/config/passwall_rule/router"
o = s:option(TextValue, "routerlist", translate("Router Hosts"))
o.description = translate(
"These had been joined websites will use proxy,but only Router model.Please input the domain names of websites,every line can input only one website domain.For example,google.com.")
@ -73,7 +73,7 @@ o.wrap = "off"
o.cfgvalue = function(a, a) return fs.readfile(t) or "" end
o.write = function(o, o, a)
fs.writefile("/tmp/router", a:gsub("\r\n", "\n"))
if (luci.sys.call("cmp -s /tmp/router /usr/share/passwall/rule/router") == 1) then
if (luci.sys.call("cmp -s /tmp/router /etc/config/passwall_rule/router") == 1) then
fs.writefile(t, a:gsub("\r\n", "\n"))
luci.sys.call("rm -f /tmp/dnsmasq.d/router.conf >/dev/null")
end

View File

@ -56,6 +56,10 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
font-size:.9rem;
color: #fb6340;
}
.yellow{
font-size:.9rem;
color: #b9b90b;
}
.sk-text-success{
color: #2dce89;
@ -352,13 +356,32 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
var div = s.parentNode.parentNode.parentNode.parentNode;
div.removeAttribute('onclick');
s.innerHTML = '<%:Check...%>';
var sendDate = (new Date()).getTime();
XHR.get('<%=dsp.build_url("admin/vpn/passwall/connect_status")%>', {
type: type
},
function(x, rv) {
if (rv.status) {
s.className="green";
s.innerHTML = '<%:Working...%>';
var receiveDate = (new Date()).getTime();
var responseTimeMs = receiveDate - sendDate;
var speed = "";
if (responseTimeMs < 300) {
s.className="green";
speed = "<%:very good%>";
} else if (responseTimeMs < 600) {
s.className="green";
speed = "<%:good%>";
} else if (responseTimeMs < 2000) {
s.className="yellow";
speed = "<%:general%>";
} else if (responseTimeMs < 5000) {
s.className="red";
speed = "<%:bad%>";
} else if (responseTimeMs >= 5000) {
s.className="red";
speed = "<%:very bad%>";
}
s.innerHTML = speed;
}
else {
s.className="red";

View File

@ -208,6 +208,7 @@ local socks5_node_num = api.uci_get_type("global_other", "socks5_node_num", 1)
function check_connect(btn, type) {
btn.disabled = true;
btn.value = '<%:Check...%>';
var sendDate = (new Date()).getTime();
XHR.get('<%=dsp.build_url("admin/vpn/passwall/connect_status")%>', {
type: type
},
@ -215,12 +216,32 @@ local socks5_node_num = api.uci_get_type("global_other", "socks5_node_num", 1)
var s = document.getElementById('_' + type + '_status');
if(s) {
if(rv.status) {
//s.setAttribute("color","green");
btn.setAttribute("style","background-color: green !important; border-color: green !important;");
btn.value = '<%:Working...%> ✓';
var receiveDate = (new Date()).getTime();
var responseTimeMs = receiveDate - sendDate;
var speed = "";
var color="red";
if (responseTimeMs < 300) {
color = "green";
speed = "<%:very good%>";
} else if (responseTimeMs < 600) {
color = "green";
speed = "<%:good%>";
} else if (responseTimeMs < 2000) {
color = "#b9b90b";
speed = "<%:general%>";
} else if (responseTimeMs < 5000) {
color = "red";
speed = "<%:bad%>";
} else if (responseTimeMs >= 5000) {
color = "red";
speed = "<%:very bad%>";
}
//s.setAttribute("color", color);
btn.setAttribute("style","background-color: " + color + " !important; border-color: " + color + " !important;");
btn.value = speed;
}
else {
//s.setAttribute("color","red");
//s.setAttribute("color", "red");
btn.setAttribute("style","background-color:red !important; border-color: red !important;");
btn.value = '<%:Problem detected!%> X';
}

View File

@ -1,3 +1,3 @@
<%+cbi/valueheader%>
<span class="auto_ping_value" server="<%=self:cfgvalue(section)%>">-- ms</span>
<span class="auto_ping_value" cbiid="<%=section%>">-- ms</span>
<%+cbi/valuefooter%>

View File

@ -51,11 +51,11 @@ local dsp = require "luci.dispatcher"
function add_node() {
var nodes_link = document.getElementById("nodes_link").value;
if (nodes_link.trim() != "") {
if (nodes_link.indexOf("ss://") == 0 || nodes_link.indexOf("ssr://") == 0 || nodes_link.indexOf("vmess://") == 0) {
if (nodes_link.indexOf("ss://") == 0 || nodes_link.indexOf("ssr://") == 0 || nodes_link.indexOf("vmess://") == 0 || nodes_link.indexOf("trojan://") == 0) {
ajax_add_node(nodes_link);
}
else {
alert("<%:Please enter the correct link, ss:// ssr:// vmess://%>");
alert("<%:Please enter the correct link, ss:// ssr:// vmess:// trojan://%>");
}
}
else {
@ -75,7 +75,7 @@ local dsp = require "luci.dispatcher"
<div id="add_link_div">
<div class="cbi-value">
<label class="cbi-value-title"><%:Please Enter The SS/SSR/V2ray Link%></label>
<label class="cbi-value-title"><%:Please Enter The SS/SSR/V2ray/Trojan Link%></label>
<div class="cbi-value-field">
<textarea id="nodes_link" rows="5" cols="50"></textarea>
</div>

View File

@ -46,9 +46,13 @@ table td, .table .td {
var auto_ping_value = document.getElementsByClassName('auto_ping_value');
for(var i = 0; i < auto_ping_value.length; i++) {
var cbi_id = auto_ping_value[i].getAttribute("cbiid");
var address = document.getElementById("cbid.passwall." + cbi_id + ".address").value;
var port = document.getElementById("cbid.passwall." + cbi_id + ".port").value;
XHR.get('<%=dsp.build_url("admin/vpn/passwall/auto_ping_node")%>', {
index: i,
domain: auto_ping_value[i].getAttribute("server")
address: address,
port: port
},
function(x, result) {
auto_ping_value[result.index].innerHTML = (result.ping ? result.ping : "--") + " ms";
@ -68,11 +72,19 @@ table td, .table .td {
}
}
function ping_node(node,dom) {
XHR.get('<%=dsp.build_url("admin/vpn/passwall/ping_node")%>', { "node" : node },
function ping_node(cbi_id,dom) {
var address = document.getElementById("cbid.passwall." + cbi_id + ".address").value;
var port = document.getElementById("cbid.passwall." + cbi_id + ".port").value;
XHR.get('<%=dsp.build_url("admin/vpn/passwall/ping_node")%>', {
address: address,
port: port
},
function(x, result) {
if(x && x.status == 200) {
dom.outerHTML = result.ping + " ms";
if (result.ping != null && result.ping != "")
dom.outerHTML = result.ping + " ms";
else
dom.outerHTML = "--";
}
}
);

View File

@ -6,6 +6,6 @@
<%+cbi/valueheader%>
<span class="ping">
<a href="javascript:void(0)" onclick="javascript:ping_node('<%=self:cfgvalue(section)%>',this)">Ping</a>
<a href="javascript:void(0)" onclick="javascript:ping_node('<%=section%>',this)">Ping</a>
</span>
<%+cbi/valuefooter%>

View File

@ -34,6 +34,21 @@ msgstr "连接正常"
msgid "Problem detected!"
msgstr "连接失败"
msgid "very good"
msgstr "非常好"
msgid "good"
msgstr "好"
msgid "general"
msgstr "一般般"
msgid "bad"
msgstr "差"
msgid "very bad"
msgstr "非常差"
msgid "Touch Check"
msgstr "点我检测"
@ -130,8 +145,17 @@ msgstr "选中的服务器不会使用Kcptun。"
msgid "The client can use the router's Socks5 proxy"
msgstr "客户端可以使用路由器的Socks5代理"
msgid "Use Local 7913 Port"
msgstr "使用本机7913端口"
msgid "DNS Forward Mode"
msgstr "DNS转发模式"
msgid "Use local port 7913 as DNS"
msgstr "使用本机7913端口的DNS"
msgid "No patterns are used"
msgstr "不使用"
msgid "if you use no patterns are used, DNS of wan will be used by default as upstream of dnsmasq"
msgstr "如果您没有使用任何模式则会使用WAN的DNS"
msgid "upstreamm DNS Server for ChinaDNS"
msgstr "ChinaDNS的上游服务器"
@ -184,12 +208,6 @@ msgstr "游戏模式"
msgid "Return Home"
msgstr "回国模式"
msgid "DNS Forward Mode"
msgstr "DNS转发模式"
msgid "Use local port 7913 as DNS"
msgstr "使用本机7913端口的DNS"
msgid "Localhost"
msgstr "本机"
@ -202,11 +220,11 @@ msgstr "添加节点"
msgid "Add the node via the link"
msgstr "通过链接添加节点"
msgid "Please Enter The SS/SSR/V2ray Link"
msgstr "请输入SS/SSR/V2ray链接"
msgid "Please Enter The SS/SSR/V2ray/Trojan Link"
msgstr "请输入SS/SSR/V2ray/Trojan链接"
msgid "Please enter the correct link, ss:// ssr:// vmess://"
msgstr "请输入正确的链接ss:// ssr:// vmess://"
msgid "Please enter the correct link, ss:// ssr:// vmess:// trojan://"
msgstr "请输入正确的链接ss:// ssr:// vmess:// trojan://"
msgid "Are you sure set to"
msgstr "你确定要设为"
@ -388,11 +406,8 @@ msgstr "当勾选此选项时,不能使用自动切换"
msgid "List of alternate TCP forwarding servers"
msgstr "备用TCP转发服务器的列表"
msgid "Load Balancing Setting"
msgstr "负载均衡设置"
msgid "Click here to setting your Load Balancing"
msgstr "点击这里查看负载均衡设置教程。"
msgid "Configure this node with 127.0.0.1: this port"
msgstr "使用127.0.0.1和此端口配置节点"
msgid "Enable Load Balancing"
msgstr "开启负载均衡"

View File

@ -37,7 +37,7 @@ config global_proxy
option proxy_ipv6 '0'
config global_other
option auto_ping '1'
option auto_ping '0'
option tcp_node_num '1'
option udp_node_num '1'
option socks5_node_num '1'
@ -47,8 +47,8 @@ config global_rules
option auto_update '0'
option gfwlist_update '1'
option chnroute_update '1'
option chnroute_version '2019-10-18'
option gfwlist_version '2019-11-27'
option gfwlist_version '2019-12-01'
option chnroute_version '2019-12-05'
config global_app
option v2ray_file '/usr/bin/v2ray/'

View File

@ -99,6 +99,9 @@
14.208.0.0/12
20.134.160.0/20
20.139.160.0/20
23.236.64.0/25
23.236.64.128/26
23.236.64.192/27
27.0.128.0/21
27.0.160.0/21
27.0.188.0/22
@ -173,6 +176,7 @@
36.255.164.0/22
36.255.172.0/22
36.255.176.0/22
38.142.239.114
39.0.0.0/24
39.0.2.0/23
39.0.4.0/22
@ -358,7 +362,8 @@
43.228.64.0/21
43.228.76.0/22
43.228.100.0/22
43.228.116.0/22
43.228.116.0/24
43.228.118.0/23
43.228.132.0/22
43.228.136.0/22
43.228.148.0/22
@ -572,8 +577,6 @@
45.40.208.0/21
45.40.224.0/19
45.65.16.0/20
45.85.196.0/22
45.88.101.0/24
45.112.132.0/22
45.112.188.0/22
45.112.208.0/22
@ -590,7 +593,6 @@
45.113.184.0/22
45.113.200.0/21
45.113.208.0/20
45.113.228.0/22
45.113.240.0/22
45.113.252.0/22
45.114.0.0/22
@ -706,11 +708,6 @@
45.127.128.0/22
45.127.144.0/21
45.127.156.0/22
45.133.148.0/22
45.136.44.0/24
45.136.46.0/24
45.136.180.0/22
45.138.160.0/22
45.248.8.0/22
45.248.80.0/22
45.248.88.0/22
@ -875,11 +872,17 @@
59.83.136.0/21
59.83.144.0/20
59.83.160.0/19
59.83.192.0/18
59.83.192.0/19
59.83.224.0/20
59.83.240.0/21
59.83.248.0/22
59.83.252.0/23
59.83.254.0/24
59.107.0.0/16
59.108.0.0/14
59.151.0.0/17
59.152.16.0/20
59.152.35.0/24
59.152.36.0/22
59.152.64.0/20
59.152.112.0/21
@ -1023,7 +1026,9 @@
101.192.0.0/14
101.196.0.0/16
101.198.128.0/18
101.198.194.0/24
101.198.196.0/23
101.198.200.0/22
101.198.224.0/19
101.199.0.0/19
101.199.48.0/20
@ -1056,7 +1061,6 @@
103.1.8.0/22
103.1.20.0/22
103.1.24.0/22
103.1.72.0/22
103.1.88.0/22
103.1.168.0/22
103.2.108.0/22
@ -1751,6 +1755,7 @@
103.94.88.0/22
103.94.116.0/22
103.94.160.0/22
103.94.182.0/24
103.94.200.0/22
103.95.31.0/24
103.95.52.0/22
@ -1824,7 +1829,8 @@
103.101.60.0/22
103.101.121.0/24
103.101.122.0/23
103.101.124.0/22
103.101.124.0/24
103.101.126.0/23
103.101.144.0/21
103.101.180.0/22
103.101.184.0/22
@ -1962,7 +1968,6 @@
103.121.250.0/24
103.121.252.0/22
103.122.48.0/22
103.122.177.0/24
103.122.178.0/23
103.122.192.0/22
103.122.240.0/22
@ -2032,7 +2037,6 @@
103.137.180.0/22
103.137.236.0/22
103.138.2.0/23
103.138.81.0/24
103.138.82.0/23
103.138.134.0/23
103.138.208.0/23
@ -2068,7 +2072,7 @@
103.142.156.0/23
103.142.180.0/23
103.142.186.0/23
103.142.190.0/23
103.142.191.0/24
103.142.220.0/23
103.142.230.0/24
103.142.234.0/23
@ -2076,8 +2080,29 @@
103.143.16.0/22
103.143.31.0/24
103.143.74.0/23
103.143.124.0/23
103.143.132.0/22
103.143.174.0/23
103.143.228.0/23
103.144.40.0/23
103.144.66.0/23
103.144.70.0/23
103.144.72.0/23
103.144.109.0/24
103.144.136.0/23
103.144.158.0/23
103.145.38.0/23
103.145.40.0/22
103.145.60.0/23
103.145.72.0/23
103.145.80.0/23
103.145.86.0/23
103.145.90.0/23
103.145.92.0/22
103.145.98.0/23
103.145.106.0/23
103.145.122.0/23
103.145.188.0/22
103.192.0.0/19
103.192.48.0/21
103.192.56.0/22
@ -2192,6 +2217,7 @@
103.205.52.0/22
103.205.108.0/22
103.205.116.0/22
103.205.120.0/24
103.205.136.0/22
103.205.162.0/24
103.205.188.0/22
@ -2312,8 +2338,8 @@
103.220.200.0/22
103.220.240.0/20
103.221.0.0/19
103.221.32.0/22
103.221.88.0/22
103.221.32.0/21
103.221.88.0/21
103.221.96.0/19
103.221.128.0/18
103.221.192.0/20
@ -2402,6 +2428,7 @@
103.231.180.0/22
103.231.244.0/22
103.232.4.0/22
103.232.17.168/29
103.232.144.0/22
103.233.4.0/22
103.233.44.0/22
@ -2849,7 +2876,10 @@
114.113.208.0/20
114.113.224.0/20
114.114.0.0/15
114.116.0.0/14
114.116.0.0/15
114.118.0.0/16
114.119.0.0/17
114.119.192.0/18
114.132.0.0/16
114.135.0.0/16
114.138.0.0/15
@ -3134,7 +3164,6 @@
119.2.128.0/17
119.3.0.0/16
119.4.0.0/14
119.8.0.0/16
119.10.0.0/17
119.15.136.0/21
119.16.0.0/16
@ -3532,10 +3561,7 @@
129.204.0.0/16
129.211.0.0/16
129.223.254.0/24
129.227.98.0/23
129.227.100.0/22
129.227.104.0/21
129.227.112.0/20
129.227.99.0/24
130.214.218.0/23
131.228.96.0/24
131.253.12.0/29
@ -3639,7 +3665,6 @@
144.7.0.0/16
144.12.0.0/16
144.36.146.0/23
144.48.12.0/22
144.48.64.0/22
144.48.88.0/22
144.48.156.0/22
@ -3701,11 +3726,9 @@
150.242.248.0/22
150.255.0.0/16
152.32.178.0/23
152.32.225.0/24
152.32.226.0/23
152.32.228.0/22
152.32.232.0/21
152.32.240.0/20
152.32.249.0/24
152.32.251.0/24
152.32.252.0/22
152.104.128.0/17
152.136.0.0/16
153.0.0.0/16
@ -3719,6 +3742,8 @@
155.126.176.0/23
156.107.160.0/24
156.107.170.0/24
156.107.179.0/24
156.107.181.0/24
156.154.62.0/23
157.0.0.0/16
157.18.0.0/16
@ -3963,6 +3988,7 @@
183.192.0.0/10
185.109.236.0/24
185.203.36.0/22
185.216.118.0/24
185.223.134.0/23
185.224.116.0/22
188.131.128.0/17
@ -3991,6 +4017,8 @@
193.17.120.0/22
193.20.64.0/22
193.112.0.0/16
193.200.196.0/24
193.200.222.160/28
194.138.136.0/24
194.138.202.0/23
194.138.245.0/24
@ -4191,6 +4219,7 @@
202.52.143.0/24
202.53.140.0/24
202.53.143.0/24
202.53.202.0/24
202.57.212.0/22
202.57.216.0/22
202.57.240.0/20
@ -4288,7 +4317,6 @@
202.94.74.0/24
202.94.81.0/24
202.94.92.0/22
202.95.4.0/22
202.95.240.0/21
202.95.252.0/22
202.96.0.0/12
@ -5294,7 +5322,11 @@
203.104.32.0/20
203.105.96.0/19
203.105.128.0/19
203.107.0.0/17
203.107.0.0/19
203.107.32.0/20
203.107.52.0/22
203.107.56.0/21
203.107.64.0/18
203.110.160.0/19
203.110.208.0/20
203.110.232.0/23
@ -5373,6 +5405,8 @@
203.191.2.0/24
203.191.5.0/24
203.191.7.0/24
203.191.29.0/24
203.191.30.0/23
203.191.64.0/18
203.191.133.0/24
203.191.144.0/20
@ -5434,7 +5468,15 @@
210.28.0.0/14
210.32.0.0/12
210.51.0.0/16
210.52.0.0/15
210.52.0.0/18
210.52.64.0/23
210.52.66.0/24
210.52.68.0/22
210.52.72.0/21
210.52.80.0/20
210.52.96.0/19
210.52.128.0/17
210.53.0.0/16
210.56.192.0/19
210.72.0.0/14
210.76.0.0/15
@ -5505,7 +5547,20 @@
218.28.0.0/15
218.30.0.0/19
218.30.64.0/18
218.30.128.0/17
218.30.128.0/18
218.30.192.0/19
218.30.224.0/20
218.30.240.0/21
218.30.248.0/22
218.30.252.0/25
218.30.252.128/26
218.30.252.194/31
218.30.252.196/30
218.30.252.200/29
218.30.252.208/28
218.30.252.224/27
218.30.253.0/24
218.30.254.0/23
218.31.0.0/16
218.56.0.0/13
218.64.0.0/11
@ -5701,7 +5756,12 @@
223.166.0.0/15
223.192.0.0/15
223.198.0.0/15
223.201.0.0/16
223.201.4.0/22
223.201.8.0/21
223.201.16.0/20
223.201.32.0/19
223.201.64.0/18
223.201.128.0/17
223.202.0.0/15
223.208.0.0/13
223.220.0.0/15

View File

@ -16,12 +16,12 @@ CONFIG_UDP_FILE=$CONFIG_PATH/UDP.json
CONFIG_SOCKS5_FILE=$CONFIG_PATH/SOCKS5.json
LOCK_FILE=$CONFIG_PATH/$CONFIG.lock
LOG_FILE=/var/log/$CONFIG.log
RULE_PATH=/etc/config/${CONFIG}_rule
APP_PATH=/usr/share/$CONFIG
APP_PATH_RULE=$APP_PATH/rule
APP_PATH_DNSMASQ=$APP_PATH/dnsmasq.d
TMP_DNSMASQ_PATH=/var/etc/dnsmasq-passwall.d
DNSMASQ_PATH=/etc/dnsmasq.d
lanip=$(uci get network.lan.ipaddr)
DNS_PORT=7913
get_date() {
echo "$(date "+%Y-%m-%d %H:%M:%S")"
@ -617,24 +617,27 @@ stop_crontab() {
start_dns() {
case "$DNS_MODE" in
nonuse)
echolog "不使用任何DNS转发模式将会直接将WAN口DNS给dnsmasq上游"
;;
dns2socks)
if [ -n "$SOCKS5_NODE1" -a "$SOCKS5_NODE1" != "nil" ]; then
dns2socks_bin=$(find_bin dns2socks)
[ -n "$dns2socks_bin" ] && {
nohup $dns2socks_bin 127.0.0.1:$SOCKS5_PROXY_PORT1 $DNS_FORWARD 127.0.0.1:7913 >/dev/null 2>&1 &
nohup $dns2socks_bin 127.0.0.1:$SOCKS5_PROXY_PORT1 $DNS_FORWARD 127.0.0.1:$DNS_PORT >/dev/null 2>&1 &
echolog "运行DNS转发模式dns2socks..."
}
else
echolog "dns2socks模式需要使用Socks5代理服务器请开启"
fi
;;
;;
Pcap_DNSProxy)
Pcap_DNSProxy_bin=$(find_bin Pcap_DNSProxy)
[ -n "$Pcap_DNSProxy_bin" ] && {
nohup $Pcap_DNSProxy_bin -c /etc/pcap-dnsproxy >/dev/null 2>&1 &
echolog "运行DNS转发模式Pcap_DNSProxy..."
}
;;
;;
pdnsd)
pdnsd_bin=$(find_bin pdnsd)
[ -n "$pdnsd_bin" ] && {
@ -642,10 +645,10 @@ start_dns() {
nohup $pdnsd_bin --daemon -c $CACHEDIR/pdnsd.conf -p $RUN_PID_PATH/pdnsd.pid -d >/dev/null 2>&1 &
echolog "运行DNS转发模式Pdnsd..."
}
;;
;;
local_7913)
echolog "运行DNS转发模式使用本机7913端口DNS服务解析域名..."
;;
;;
chinadns)
chinadns_bin=$(find_bin ChinaDNS)
[ -n "$chinadns_bin" ] && {
@ -656,40 +659,40 @@ start_dns() {
case "$UP_CHINADNS_MODE" in
OpenDNS_1)
other=0
nohup $chinadns_bin -p 7913 -c $APP_PATH_RULE/chnroute -m -d -s $dns1,208.67.222.222:443,208.67.222.222:5353 >/dev/null 2>&1 &
nohup $chinadns_bin -p $DNS_PORT -c $RULE_PATH/chnroute -m -d -s $dns1,208.67.222.222:443,208.67.222.222:5353 >/dev/null 2>&1 &
echolog "运行ChinaDNS上游转发模式$dns1,208.67.222.222..."
;;
OpenDNS_2)
other=0
nohup $chinadns_bin -p 7913 -c $APP_PATH_RULE/chnroute -m -d -s $dns1,208.67.220.220:443,208.67.220.220:5353 >/dev/null 2>&1 &
nohup $chinadns_bin -p $DNS_PORT -c $RULE_PATH/chnroute -m -d -s $dns1,208.67.220.220:443,208.67.220.220:5353 >/dev/null 2>&1 &
echolog "运行ChinaDNS上游转发模式$dns1,208.67.220.220..."
;;
custom)
other=0
UP_CHINADNS_CUSTOM=$(config_t_get global up_chinadns_custom '114.114.114.114,208.67.222.222:5353')
nohup $chinadns_bin -p 7913 -c $APP_PATH_RULE/chnroute -m -d -s $UP_CHINADNS_CUSTOM >/dev/null 2>&1 &
nohup $chinadns_bin -p $DNS_PORT -c $RULE_PATH/chnroute -m -d -s $UP_CHINADNS_CUSTOM >/dev/null 2>&1 &
echolog "运行ChinaDNS上游转发模式$UP_CHINADNS_CUSTOM..."
;;
dnsproxy)
dnsproxy_bin=$(find_bin dnsproxy)
[ -n "$dnsproxy_bin" ] && {
nohup $dnsproxy_bin -d -T -p 7913 -R $DNS_FORWARD_IP -P $DNS_FORWARD_PORT >/dev/null 2>&1 &
nohup $dnsproxy_bin -d -T -p $DNS_PORT -R $DNS_FORWARD_IP -P $DNS_FORWARD_PORT >/dev/null 2>&1 &
echolog "运行ChinaDNS上游转发模式dnsproxy..."
}
;;
dns-forwarder)
dnsforwarder_bin=$(find_bin dns-forwarder)
[ -n "$dnsforwarder_bin" ] && {
nohup $dnsforwarder_bin -p 7913 -s $DNS_FORWARD >/dev/null 2>&1 &
nohup $dnsforwarder_bin -p $DNS_PORT -s $DNS_FORWARD >/dev/null 2>&1 &
echolog "运行ChinaDNS上游转发模式dns-forwarder..."
}
;;
esac
if [ "$other" = "1" ]; then
nohup $chinadns_bin -p 7923 -c $APP_PATH_RULE/chnroute -m -d -s $dns1,127.0.0.1:7913 >/dev/null 2>&1 &
nohup $chinadns_bin -p 7923 -c $RULE_PATH/chnroute -m -d -s $dns1,127.0.0.1:$DNS_PORT >/dev/null 2>&1 &
fi
}
;;
;;
esac
echolog "若不正常,请尝试其他模式!"
}
@ -807,10 +810,10 @@ EOF
[ -n "$subscribe_url" ] && {
for url in $subscribe_url; do
if [ -n "$(echo -n "$url" | grep "//")" ]; then
echo -n "$url" | awk -F'/' '{print $3}' | sed "s/^/server=&\/./g" | sed "s/$/\/127.0.0.1#7913/g" >>$TMP_DNSMASQ_PATH/subscribe.conf
echo -n "$url" | awk -F'/' '{print $3}' | sed "s/^/server=&\/./g" | sed "s/$/\/127.0.0.1#$DNS_PORT/g" >>$TMP_DNSMASQ_PATH/subscribe.conf
echo -n "$url" | awk -F'/' '{print $3}' | sed "s/^/ipset=&\/./g" | sed "s/$/\/router/g" >>$TMP_DNSMASQ_PATH/subscribe.conf
else
echo -n "$url" | awk -F'/' '{print $1}' | sed "s/^/server=&\/./g" | sed "s/$/\/127.0.0.1#7913/g" >>$TMP_DNSMASQ_PATH/subscribe.conf
echo -n "$url" | awk -F'/' '{print $1}' | sed "s/^/server=&\/./g" | sed "s/$/\/127.0.0.1#$DNS_PORT/g" >>$TMP_DNSMASQ_PATH/subscribe.conf
echo -n "$url" | awk -F'/' '{print $1}' | sed "s/^/ipset=&\/./g" | sed "s/$/\/router/g" >>$TMP_DNSMASQ_PATH/subscribe.conf
fi
done
@ -818,29 +821,29 @@ EOF
}
}
if [ ! -f "$TMP_DNSMASQ_PATH/gfwlist.conf" ]; then
ln -s $APP_PATH_DNSMASQ/gfwlist.conf $TMP_DNSMASQ_PATH/gfwlist.conf
if [ ! -f "$TMP_DNSMASQ_PATH/gfwlist.conf" -a "$DNS_MODE" != "nonuse" ]; then
ln -s $RULE_PATH/gfwlist.conf $TMP_DNSMASQ_PATH/gfwlist.conf
restdns=1
fi
if [ ! -f "$TMP_DNSMASQ_PATH/blacklist_host.conf" ]; then
cat $APP_PATH_RULE/blacklist_host | awk '{print "server=/."$1"/127.0.0.1#7913\nipset=/."$1"/blacklist"}' >>$TMP_DNSMASQ_PATH/blacklist_host.conf
if [ ! -f "$TMP_DNSMASQ_PATH/blacklist_host.conf" -a "$DNS_MODE" != "nonuse" ]; then
cat $RULE_PATH/blacklist_host | awk '{print "server=/."$1"/127.0.0.1#'$DNS_PORT'\nipset=/."$1"/blacklist"}' >>$TMP_DNSMASQ_PATH/blacklist_host.conf
restdns=1
fi
if [ ! -f "$TMP_DNSMASQ_PATH/whitelist_host.conf" ]; then
cat $APP_PATH_RULE/whitelist_host | sed "s/^/ipset=&\/./g" | sed "s/$/\/&whitelist/g" | sort | awk '{if ($0!=line) print;line=$0}' >$TMP_DNSMASQ_PATH/whitelist_host.conf
cat $RULE_PATH/whitelist_host | sed "s/^/ipset=&\/./g" | sed "s/$/\/&whitelist/g" | sort | awk '{if ($0!=line) print;line=$0}' >$TMP_DNSMASQ_PATH/whitelist_host.conf
restdns=1
fi
if [ ! -f "$TMP_DNSMASQ_PATH/router.conf" ]; then
cat $APP_PATH_RULE/router | awk '{print "server=/."$1"/127.0.0.1#7913\nipset=/."$1"/router"}' >>$TMP_DNSMASQ_PATH/router.conf
if [ ! -f "$TMP_DNSMASQ_PATH/router.conf" -a "$DNS_MODE" != "nonuse" ]; then
cat $RULE_PATH/router | awk '{print "server=/."$1"/127.0.0.1#'$DNS_PORT'\nipset=/."$1"/router"}' >>$TMP_DNSMASQ_PATH/router.conf
restdns=1
fi
userconf=$(grep -c "" $APP_PATH_DNSMASQ/user.conf)
userconf=$(grep -c "" $RULE_PATH/user.conf)
if [ "$userconf" -gt 0 ]; then
ln -s $APP_PATH_DNSMASQ/user.conf $TMP_DNSMASQ_PATH/user.conf
ln -s $RULE_PATH/user.conf $TMP_DNSMASQ_PATH/user.conf
restdns=1
fi
@ -940,7 +943,7 @@ gen_pdnsd_config() {
cache_dir="/var/pdnsd";
run_as="root";
server_ip = 127.0.0.1;
server_port=7913;
server_port=$DNS_PORT;
status_ctl = on;
query_method=tcp_only;
min_ttl=1d;

View File

@ -200,9 +200,9 @@ add_firewall_rule() {
ipset -! create $IPSET_BLACKLIST nethash && ipset flush $IPSET_BLACKLIST
ipset -! create $IPSET_WHITELIST nethash && ipset flush $IPSET_WHITELIST
sed -e "s/^/add $IPSET_CHN &/g" $APP_PATH_RULE/chnroute | awk '{print $0} END{print "COMMIT"}' | ipset -R
sed -e "s/^/add $IPSET_BLACKLIST &/g" $APP_PATH_RULE/blacklist_ip | awk '{print $0} END{print "COMMIT"}' | ipset -R
sed -e "s/^/add $IPSET_WHITELIST &/g" $APP_PATH_RULE/whitelist_ip | awk '{print $0} END{print "COMMIT"}' | ipset -R
sed -e "s/^/add $IPSET_CHN &/g" $RULE_PATH/chnroute | awk '{print $0} END{print "COMMIT"}' | ipset -R
sed -e "s/^/add $IPSET_BLACKLIST &/g" $RULE_PATH/blacklist_ip | awk '{print $0} END{print "COMMIT"}' | ipset -R
sed -e "s/^/add $IPSET_WHITELIST &/g" $RULE_PATH/whitelist_ip | awk '{print $0} END{print "COMMIT"}' | ipset -R
ipset -! -R <<-EOF || return 1
$(gen_laniplist | sed -e "s/^/add $IPSET_LANIPLIST /")

View File

@ -85,10 +85,12 @@ for i in $(seq 1 $SOCKS5_NODE_NUM); do
done
#dns
icount=$(netstat -apn | grep 7913 | wc -l)
if [ $icount = 0 ]; then
/etc/init.d/passwall restart
exit 0
if [ "$dns_mode" != "nonuse" ]; then
icount=$(netstat -apn | grep 7913 | wc -l)
if [ $icount = 0 ]; then
/etc/init.d/passwall restart
exit 0
fi
fi
#haproxy

View File

@ -2,30 +2,23 @@
CONFIG=passwall
LOG_FILE=/var/log/$CONFIG.log
url_main="https://raw.githubusercontent.com/hq450/fancyss/master/rules"
SS_PATH=/usr/share/$CONFIG
DNSMASQ_PATH=$SS_PATH/dnsmasq.d
RULE_PATH=$SS_PATH/rule
RULE_PATH=/etc/config/${CONFIG}_rule
Date=$(date "+%Y-%m-%d %H:%M:%S")
url_main="https://raw.githubusercontent.com/hq450/fancyss/master/rules"
update=$1
gfwlist_update=0
chnroute_update=0
Pcap_Routing_update=0
Pcap_WhiteList_update=0
if [ -n "$update" ]; then
[ -n "$(echo $update | grep "gfwlist_update")" ] && gfwlist_update=1
[ -n "$(echo $update | grep "chnroute_update")" ] && chnroute_update=1
[ -n "$(echo $update | grep "Pcap_Routing_update")" ] && Pcap_Routing_update=1
[ -n "$(echo $update | grep "Pcap_WhiteList_update")" ] && Pcap_WhiteList_update=1
else
gfwlist_update=$(uci get $CONFIG.@global_rules[0].gfwlist_update)
chnroute_update=$(uci get $CONFIG.@global_rules[0].chnroute_update)
Pcap_Routing_update=$(uci get $CONFIG.@global_rules[0].Pcap_Routing_update)
Pcap_WhiteList_update=$(uci get $CONFIG.@global_rules[0].Pcap_WhiteList_update)
fi
if [ "$gfwlist_update" == 0 -a "$chnroute_update" == 0 -a "$Pcap_Routing_update" == 0 -a "$Pcap_WhiteList_update" == 0 ]; then
if [ "$gfwlist_update" == 0 -a "$chnroute_update" == 0 ]; then
exit
fi
@ -38,13 +31,9 @@ uci_get_by_type() {
echo ${ret:=$3}
}
# detect ss version
#ss_basic_version_web1=`curl -s https://raw.githubusercontent.com/monokoo/koolshare.github.io/acelan_softcenter_ui/shadowsocks/version | sed -n 1p`
# rule update
echo $Date: 开始更新规则,请等待... >$LOG_FILE
#wget -q --no-check-certificate --timeout=15 https://raw.githubusercontent.com/monokoo/koolshare.github.io/acelan_softcenter_ui/maintain_files/version1 -O /tmp/version1
#旧接口https://raw.githubusercontent.com/monokoo/koolshare.github.io/acelan_softcenter_ui/maintain_files/version1
status1=$(curl -w %{http_code} --connect-timeout 10 $url_main/version1 --silent -o /tmp/version1)
if [ -z "$status1" ] || [ "$status1" == "404" ]; then
echo $Date: 无法访问更新接口,请更新接口! >>$LOG_FILE
@ -62,14 +51,13 @@ if [ "$gfwlist_update" == 1 ]; then
gfwlist=$(cat /tmp/version1 | sed -n 1p)
version_gfwlist2=$(echo $gfwlist | sed 's/ /\n/g' | sed -n 1p)
md5sum_gfwlist2=$(echo $gfwlist | sed 's/ /\n/g' | tail -n 2 | head -n 1)
local_md5sum_gfwlist=$(md5sum $DNSMASQ_PATH/gfwlist.conf | awk '{print $1}')
local_md5sum_gfwlist=$(md5sum $RULE_PATH/gfwlist.conf | awk '{print $1}')
if [ ! -z "$version_gfwlist2" ]; then
version_gfwlist1=$(uci_get_by_type global_rules gfwlist_version)
if [ "$version_gfwlist1" != "$version_gfwlist2" -o "$md5sum_gfwlist2" != "$local_md5sum_gfwlist" ]; then
echo $Date: 检测到新版本gfwlist开始更新... >>$LOG_FILE
echo $Date: 下载gfwlist到临时文件... >>$LOG_FILE
#wget --no-check-certificate --timeout=15 -q https://raw.githubusercontent.com/monokoo/koolshare.github.io/acelan_softcenter_ui/maintain_files/gfwlist.conf -O /tmp/gfwlist.conf
#旧接口https://raw.githubusercontent.com/monokoo/koolshare.github.io/acelan_softcenter_ui/maintain_files/gfwlist.conf
status2=$(curl -w %{http_code} --connect-timeout 10 $url_main/gfwlist.conf --silent -o /tmp/gfwlist.conf)
if [ -z "$status2" ] || [ "$status2" == "404" ]; then
echo $Date: 无法访问更新接口,请更新接口! >>$LOG_FILE
@ -78,7 +66,7 @@ if [ "$gfwlist_update" == 1 ]; then
md5sum_gfwlist1=$(md5sum /tmp/gfwlist.conf | sed 's/ /\n/g' | sed -n 1p)
if [ "$md5sum_gfwlist1"x = "$md5sum_gfwlist2"x ]; then
echo $Date: 下载完成校验通过将临时文件覆盖到原始gfwlist文件 >>$LOG_FILE
mv /tmp/gfwlist.conf $DNSMASQ_PATH/gfwlist.conf
mv /tmp/gfwlist.conf $RULE_PATH/gfwlist.conf
uci set $CONFIG.@global_rules[0].gfwlist_version=$version_gfwlist2
rm -rf /tmp/dnsmasq.d/gfwlist.conf
reboot="1"
@ -107,7 +95,6 @@ if [ "$chnroute_update" == 1 ]; then
echo $Date: 检测到新版本chnroute开始更新... >>$LOG_FILE
echo $Date: 下载chnroute到临时文件... >>$LOG_FILE
#wget --no-check-certificate --timeout=15 -q https://raw.githubusercontent.com/monokoo/koolshare.github.io/acelan_softcenter_ui/maintain_files/chnroute.txt -O /tmp/chnroute
#旧接口https://raw.githubusercontent.com/monokoo/koolshare.github.io/acelan_softcenter_ui/maintain_files/chnroute.txt
status3=$(curl -w %{http_code} --connect-timeout 10 $url_main/chnroute.txt --silent -o /tmp/chnroute)
if [ -z "$status3" ] || [ "$status3" == "404" ]; then
echo $Date: 无法访问更新接口,请更新接口! >>$LOG_FILE
@ -134,86 +121,11 @@ if [ "$chnroute_update" == 1 ]; then
rm -rf /tmp/chnroute
fi
# update Routing
if [ "$Pcap_Routing_update" == 1 ]; then
Routing=$(cat /tmp/version1 | sed -n 5p)
version_Routing2=$(echo $Routing | sed 's/ /\n/g' | sed -n 1p)
md5sum_Routing2=$(echo $Routing | sed 's/ /\n/g' | tail -n 2 | head -n 1)
local_md5sum_Routing=$(md5sum /etc/pcap-dnsproxy/Routing.txt | awk '{print $1}')
if [ ! -z "$version_Routing2" ]; then
version_Routing1=$(uci_get_by_type global_rules pcap_Routing_version)
if [ "$version_Routing1" != "$version_Routing2" -o "$md5sum_Routing2" != "$local_md5sum_Routing" ]; then
echo $Date: 检测到新版本Routing开始更新... >>$LOG_FILE
echo $Date: 下载Routing到临时文件... >>$LOG_FILE
status4=$(curl -w %{http_code} --connect-timeout 10 $url_main/Routing.txt --silent -o /tmp/Routing.txt)
if [ -z "$status4" ] || [ "$status4" == "404" ]; then
echo $Date: 无法访问更新接口,请更新接口! >>$LOG_FILE
exit
fi
md5sum_Routing1=$(md5sum /tmp/Routing.txt | sed 's/ /\n/g' | sed -n 1p)
if [ "$md5sum_Routing1"x = "$md5sum_Routing2"x ]; then
echo $Date: 下载完成校验通过将临时文件覆盖到原始Routing文件 >>$LOG_FILE
mkdir -p /etc/pcap-dnsproxy
mv /tmp/Routing.txt /etc/pcap-dnsproxy/Routing.txt
uci set $CONFIG.@global_rules[0].pcap_Routing_version=$version_Routing2
reboot="1"
echo $Date: 你的Routing已经更新到最新了哦~ >>$LOG_FILE
else
echo $Date: 下载完成,但是校验没有通过! >>$LOG_FILE
fi
else
echo $Date: 检测到Routing本地版本号和在线版本号相同不用更新! >>$LOG_FILE
fi
else
echo $Date: Routing文件下载失败 >>$LOG_FILE
fi
rm -rf /tmp/Routing.txt
fi
# update WhiteList
if [ "$Pcap_WhiteList_update" == 1 ]; then
WhiteList=$(cat /tmp/version1 | sed -n 7p)
version_WhiteList2=$(echo $WhiteList | sed 's/ /\n/g' | sed -n 1p)
md5sum_WhiteList2=$(echo $WhiteList | sed 's/ /\n/g' | tail -n 2 | head -n 1)
local_md5sum_WhiteList=$(md5sum /etc/pcap-dnsproxy/WhiteList.txt | awk '{print $1}')
if [ ! -z "$version_WhiteList2" ]; then
version_WhiteList1=$(uci_get_by_type global_rules pcap_WhiteList_version)
if [ "$version_WhiteList1" != "$version_WhiteList2" -o "$md5sum_WhiteList2" != "$local_md5sum_WhiteList" ]; then
echo $Date: 检测到新版本WhiteList开始更新... >>$LOG_FILE
echo $Date: 下载WhiteList到临时文件... >>$LOG_FILE
status4=$(curl -w %{http_code} --connect-timeout 10 $url_main/WhiteList_new.txt --silent -o /tmp/WhiteList.txt)
if [ -z "$status4" ] || [ "$status4" == "404" ]; then
echo $Date: 无法访问更新接口,请更新接口! >>$LOG_FILE
exit
fi
#wget --no-check-certificate --timeout=10 -qO - $url_main/WhiteList_new.txt > /tmp/WhiteList.txt
md5sum_WhiteList1=$(md5sum /tmp/WhiteList.txt | sed 's/ /\n/g' | sed -n 1p)
if [ "$md5sum_WhiteList1"x = "$md5sum_WhiteList2"x ]; then
echo $Date: 下载完成校验通过将临时文件覆盖到原始WhiteList文件 >>$LOG_FILE
mkdir -p /etc/pcap-dnsproxy
mv /tmp/WhiteList.txt /etc/pcap-dnsproxy/WhiteList.txt
uci set $CONFIG.@global_rules[0].pcap_WhiteList_version=$version_WhiteList2
reboot="1"
echo $Date: 你的WhiteList已经更新到最新了哦~ >>$LOG_FILE
else
echo $Date: 下载完成,但是校验没有通过! >>$LOG_FILE
fi
else
echo $Date: 检测到WhiteList本地版本号和在线版本号相同不用更新! >>$LOG_FILE
fi
else
echo $Date: WhiteList文件下载失败 >>$LOG_FILE
fi
rm -rf /tmp/WhiteList.txt
fi
echo $Date: 更新进程运行完毕! >>$LOG_FILE
rm -rf /tmp/version1
# write number
uci set $CONFIG.@global_rules[0].gfwlist_update=$gfwlist_update
uci set $CONFIG.@global_rules[0].chnroute_update=$chnroute_update
uci set $CONFIG.@global_rules[0].Pcap_Routing_update=$Pcap_Routing_update
uci set $CONFIG.@global_rules[0].Pcap_WhiteList_update=$Pcap_WhiteList_update
uci commit
# reboot ss
if [ "$reboot" == "1" ]; then

View File

@ -104,6 +104,12 @@ get_remote_config(){
remarks="${json_ps}"
node_address=$json_node_address
elif [ "$1" == "trojan" ]; then
link="$2"
node_password=$(echo "$link" | sed 's/trojan:\/\///g' | awk -F '@' '{print $1}')
node_address=$(echo "$link" | sed 's/trojan:\/\///g' | awk -F '@' '{print $2}' | awk -F ':' '{print $1}')
node_port=$(echo "$link" | sed 's/trojan:\/\///g' | awk -F '@' '{print $2}' | awk -F ':' '{print $2}')
remarks="${node_address}:${node_port}"
fi
# 把全部服务器节点写入文件 /usr/share/${CONFIG}/sub/all_onlinenodes
@ -186,6 +192,20 @@ add_nodes(){
let updatenum_v2ray+=1
fi
elif [ "$2" == "trojan" ]; then
${uci_set}add_mode="$add_mode"
${uci_set}remarks="$remarks"
${uci_set}type="Trojan"
${uci_set}address="$node_address"
${uci_set}port="$node_port"
${uci_set}password="$node_password"
if [ "$1" == "add" ]; then
let addnum_trojan+=1
elif [ "$1" == "update" ]; then
let updatenum_trojan+=1
fi
fi
uci commit $CONFIG
}
@ -222,6 +242,8 @@ del_config(){
let delnum_ssr+=1 #删除该节点
elif [ "$del_type" == "V2ray" ]; then
let delnum_v2ray+=1 #删除该节点
elif [ "$del_type" == "Trojan" ]; then
let delnum_trojan=1 #删除该节点
fi
done
@ -252,6 +274,7 @@ add() {
mkdir -p /usr/share/${CONFIG}/sub && rm -f /usr/share/${CONFIG}/sub/*
for link in $LINKS
do
is_decode=1
if expr "$link" : "ss://";then
link_type="ss"
new_link=$(echo -n "$link" | sed 's/ssr:\/\///g')
@ -261,10 +284,14 @@ add() {
elif expr "$link" : "vmess://";then
link_type="v2ray"
new_link=$(echo -n "$link" | sed 's/vmess:\/\///g')
elif expr "$link" : "trojan://";then
link_type="trojan"
new_link=$(echo -n "$link" | sed 's/trojan:\/\///g')
is_decode=0
fi
[ -z "$link_type" ] && continue
decode_link=$(decode_url_link $new_link 1)
get_remote_config "$link_type" "$decode_link" 1
[ "$is_decode" == 1 ] && new_link=$(decode_url_link $new_link 1)
get_remote_config "$link_type" "$new_link" 1
update_config
done
[ -f "/usr/share/${CONFIG}/sub/all_onlinenodes" ] && rm -f /usr/share/${CONFIG}/sub/all_onlinenodes
@ -287,13 +314,17 @@ start() {
addnum_v2ray=0
updatenum_v2ray=0
delnum_v2ray=0
addnum_trojan=0
updatenum_trojan=0
delnum_trojan=0
subscribe_url=$(uci get $CONFIG.@global_subscribe[0].subscribe_url) # 订阅地址
[ -z "$subscribe_url" ] && echo "$Date: 订阅地址为空,订阅失败!" >> $LOG_FILE && rm -f "$LOCK_FILE" && exit 0
echo "$Date: 开始订阅..." >> $LOG_FILE
mkdir -p /var/${CONFIG}_sub && rm -f /var/${CONFIG}_sub/*
/usr/bin/wget --no-check-certificate --timeout=8 -t 2 $subscribe_url -P /var/${CONFIG}_sub
[ ! -d "/var/${CONFIG}_sub" ] || [ "$(ls /var/${CONFIG}_sub | wc -l)" -eq 0 ] && echo "$Date: 订阅链接下载失败,请重试!" >> $LOG_FILE && rm -f "$LOCK_FILE" && exit 0
#/usr/bin/wget --no-check-certificate --timeout=8 -t 2 $subscribe_url -P /var/${CONFIG}_sub
status=$(curl -w %{http_code} --connect-timeout 10 $subscribe_url --silent -o /var/${CONFIG}_sub/sub)
[ -z "$status" ] || [ "$status" == "404" ] || [ ! -d "/var/${CONFIG}_sub" ] || [ "$(ls /var/${CONFIG}_sub | wc -l)" -eq 0 ] && echo "$Date: 订阅链接下载失败,请重试!" >> $LOG_FILE && rm -f "$LOCK_FILE" && exit 0
mkdir -p /usr/share/${CONFIG}/sub && rm -f /usr/share/${CONFIG}/sub/*
get_local_nodes
@ -311,19 +342,24 @@ start() {
[ -z "$decode_link" ] && continue
for link in $decode_link
do
is_decode=1
if expr "$link" : "ss://";then
link_type="ss"
link=$(echo -n "$link" | sed 's/ssr:\/\///g')
new_link=$(echo -n "$link" | sed 's/ssr:\/\///g')
elif expr "$link" : "ssr://";then
link_type="ssr"
link=$(echo -n "$link" | sed 's/ssr:\/\///g')
new_link=$(echo -n "$link" | sed 's/ssr:\/\///g')
elif expr "$link" : "vmess://";then
link_type="v2ray"
link=$(echo -n "$link" | sed 's/vmess:\/\///g')
new_link=$(echo -n "$link" | sed 's/vmess:\/\///g')
elif expr "$link" : "trojan://";then
link_type="trojan"
new_link=$(echo -n "$link" | sed 's/trojan:\/\///g')
is_decode=0
fi
[ -z "$link_type" ] && continue
decode_link2=$(decode_url_link $link 1)
get_remote_config "$link_type" "$decode_link2"
[ "$is_decode" == 1 ] && new_link=$(decode_url_link $new_link 1)
get_remote_config "$link_type" "$new_link"
update_config
done
done
@ -331,6 +367,7 @@ start() {
echo "$Date: 本次更新SS新增服务器节点 $addnum_ss 个,修改 $updatenum_ss 个,删除 $delnum_ss 个。" >> $LOG_FILE
echo "$Date: 本次更新SSR新增服务器节点 $addnum_ssr 个,修改 $updatenum_ssr 个,删除 $delnum_ssr 个。" >> $LOG_FILE
echo "$Date: 本次更新V2ray新增服务器节点 $addnum_v2ray 个,修改 $updatenum_v2ray 个,删除 $delnum_v2ray 个。" >> $LOG_FILE
echo "$Date: 本次更新Trojan新增服务器节点 $addnum_trojan 个,修改 $updatenum_trojan 个,删除 $delnum_trojan 个。" >> $LOG_FILE
echo "$Date: 订阅完毕..." >> $LOG_FILE
rm -f "$LOCK_FILE"
exit 0

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=Argon Magic Change Theme
LUCI_DEPENDS:=
PKG_VERSION:=1.3
PKG_RELEASE:=02-20191119
PKG_RELEASE:=03-20191206
include $(TOPDIR)/feeds/luci/luci.mk

View File

@ -2949,7 +2949,7 @@ header > .container > .pull-right > * {
border-radius: 60px;
border: #fff 3px solid;
background-image:url(../img/head-icon.png);
background-image:url(../logo.png);
background-size:cover;
box-shadow: 0 4px 20px 0px rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(156, 39, 176, 0.4);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

View File

@ -0,0 +1,15 @@
# Copyright (C) 2018-2019 Lienol <lawlienol@gmail.com>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=Bootstrap Magic Change Theme By Lienol
LUCI_DEPENDS:=
PKG_VERSION:=1.0
PKG_RELEASE:=39-20191207
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,3 @@
// HTML5 Shiv v3 | @jon_neal @afarkas @rem | MIT/GPL2 Licensed
// Uncompressed source: https://github.com/aFarkas/html5shiv
(function(a,b){function f(a){var c,d,e,f;b.documentMode>7?(c=b.createElement("font"),c.setAttribute("data-html5shiv",a.nodeName.toLowerCase())):c=b.createElement("shiv:"+a.nodeName);while(a.firstChild)c.appendChild(a.childNodes[0]);for(d=a.attributes,e=d.length,f=0;f<e;++f)d[f].specified&&c.setAttribute(d[f].nodeName,d[f].nodeValue);c.style.cssText=a.style.cssText,a.parentNode.replaceChild(c,a),c.originalElement=a}function g(a){var b=a.originalElement;while(a.childNodes.length)b.appendChild(a.childNodes[0]);a.parentNode.replaceChild(b,a)}function h(a,b){b=b||"all";var c=-1,d=[],e=a.length,f,g;while(++c<e){f=a[c],g=f.media||b;if(f.disabled||!/print|all/.test(g))continue;d.push(h(f.imports,g),f.cssText)}return d.join("")}function i(c){var d=new RegExp("(^|[\\s,{}])("+a.html5.elements.join("|")+")","gi"),e=c.split("{"),f=e.length,g=-1;while(++g<f)e[g]=e[g].split("}"),b.documentMode>7?e[g][e[g].length-1]=e[g][e[g].length-1].replace(d,'$1font[data-html5shiv="$2"]'):e[g][e[g].length-1]=e[g][e[g].length-1].replace(d,"$1shiv\\:$2"),e[g]=e[g].join("}");return e.join("{")}var c=function(a){return a.innerHTML="<x-element></x-element>",a.childNodes.length===1}(b.createElement("a")),d=function(a,b,c){return b.appendChild(a),(c=(c?c(a):a.currentStyle).display)&&b.removeChild(a)&&c==="block"}(b.createElement("nav"),b.documentElement,a.getComputedStyle),e={elements:"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video".split(" "),shivDocument:function(a){a=a||b;if(a.documentShived)return;a.documentShived=!0;var f=a.createElement,g=a.createDocumentFragment,h=a.getElementsByTagName("head")[0],i=function(a){f(a)};c||(e.elements.join(" ").replace(/\w+/g,i),a.createElement=function(a){var b=f(a);return b.canHaveChildren&&e.shivDocument(b.document),b},a.createDocumentFragment=function(){return e.shivDocument(g())});if(!d&&h){var j=f("div");j.innerHTML=["x<style>","article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}","audio{display:none}","canvas,video{display:inline-block;*display:inline;*zoom:1}","[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}","mark{background:#FF0;color:#000}","</style>"].join(""),h.insertBefore(j.lastChild,h.firstChild)}return a}};e.shivDocument(b),a.html5=e;if(c||!a.attachEvent)return;a.attachEvent("onbeforeprint",function(){if(a.html5.supportsXElement||!b.namespaces)return;b.namespaces.shiv||b.namespaces.add("shiv");var c=-1,d=new RegExp("^("+a.html5.elements.join("|")+")$","i"),e=b.getElementsByTagName("*"),g=e.length,j,k=i(h(function(a,b){var c=[],d=a.length;while(d)c.unshift(a[--d]);d=b.length;while(d)c.unshift(b[--d]);c.sort(function(a,b){return a.sourceIndex-b.sourceIndex}),d=c.length;while(d)c[--d]=c[d].styleSheet;return c}(b.getElementsByTagName("style"),b.getElementsByTagName("link"))));while(++c<g)j=e[c],d.test(j.nodeName)&&f(j);b.appendChild(b._shivedStyleSheet=b.createElement("style")).styleSheet.cssText=k}),a.attachEvent("onafterprint",function(){if(a.html5.supportsXElement||!b.namespaces)return;var c=-1,d=b.getElementsByTagName("*"),e=d.length,f;while(++c<e)f=d[c],f.originalElement&&g(f);b._shivedStyleSheet&&b._shivedStyleSheet.parentNode.removeChild(b._shivedStyleSheet)})})(this,document)

View File

@ -0,0 +1,82 @@
header h3 a, header .brand {
display:none !important;
}
@media screen and (max-device-width: 1600px) {
.container>.pull-right>* {
position: absolute;
top: 1rem;
right: 0.5rem;
cursor: pointer;
}
}
@media screen and (max-width: 480px) {
body {
font-size: 12px;
}
header {
font-size: 13px;
}
legend {
font-size: 14px;
}
.dropdown-menu a {
font-size: 13px;
min-width: 130px;
padding: 0 15px;
}
.mobile-hide {
display: none;
}
#maincontent.container {
padding: 0px 10px;
}
div.cbi-section, fieldset {
min-width: inherit;
overflow-x: auto;
overflow-y: hidden;
}
.cbi-value {
}
.cbi-value-title {
width: 30%;
min-width: 0rem !important;
margin-right: 1em;
/* text-align: left;
padding-left: 1em; */
}
.cbi-value-field {
width: 55%;
}
.cbi-value-description {
width: 75%;
display: inline-table;
padding: 1px 1.2rem;
background-position-y: 3px;
}
.cbi-value-field .cbi-input-select,
.cbi-value input[type="password"],
.cbi-value input[type="text"] {
min-width: unset;
/* width: 95%; */
}
}
@media screen and (max-device-width: 600px) {
#maincontent.container {
margin-top: 30px;
}
}
@media screen and (max-device-width: 360px) {
#maincontent.container {
margin-top: 30px;
}
}
@media screen and (max-device-width: 200px) {
#maincontent.container {
margin-top: 30px;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,3 @@
// HTML5 Shiv v3 | @jon_neal @afarkas @rem | MIT/GPL2 Licensed
// Uncompressed source: https://github.com/aFarkas/html5shiv
(function(a,b){function f(a){var c,d,e,f;b.documentMode>7?(c=b.createElement("font"),c.setAttribute("data-html5shiv",a.nodeName.toLowerCase())):c=b.createElement("shiv:"+a.nodeName);while(a.firstChild)c.appendChild(a.childNodes[0]);for(d=a.attributes,e=d.length,f=0;f<e;++f)d[f].specified&&c.setAttribute(d[f].nodeName,d[f].nodeValue);c.style.cssText=a.style.cssText,a.parentNode.replaceChild(c,a),c.originalElement=a}function g(a){var b=a.originalElement;while(a.childNodes.length)b.appendChild(a.childNodes[0]);a.parentNode.replaceChild(b,a)}function h(a,b){b=b||"all";var c=-1,d=[],e=a.length,f,g;while(++c<e){f=a[c],g=f.media||b;if(f.disabled||!/print|all/.test(g))continue;d.push(h(f.imports,g),f.cssText)}return d.join("")}function i(c){var d=new RegExp("(^|[\\s,{}])("+a.html5.elements.join("|")+")","gi"),e=c.split("{"),f=e.length,g=-1;while(++g<f)e[g]=e[g].split("}"),b.documentMode>7?e[g][e[g].length-1]=e[g][e[g].length-1].replace(d,'$1font[data-html5shiv="$2"]'):e[g][e[g].length-1]=e[g][e[g].length-1].replace(d,"$1shiv\\:$2"),e[g]=e[g].join("}");return e.join("{")}var c=function(a){return a.innerHTML="<x-element></x-element>",a.childNodes.length===1}(b.createElement("a")),d=function(a,b,c){return b.appendChild(a),(c=(c?c(a):a.currentStyle).display)&&b.removeChild(a)&&c==="block"}(b.createElement("nav"),b.documentElement,a.getComputedStyle),e={elements:"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video".split(" "),shivDocument:function(a){a=a||b;if(a.documentShived)return;a.documentShived=!0;var f=a.createElement,g=a.createDocumentFragment,h=a.getElementsByTagName("head")[0],i=function(a){f(a)};c||(e.elements.join(" ").replace(/\w+/g,i),a.createElement=function(a){var b=f(a);return b.canHaveChildren&&e.shivDocument(b.document),b},a.createDocumentFragment=function(){return e.shivDocument(g())});if(!d&&h){var j=f("div");j.innerHTML=["x<style>","article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}","audio{display:none}","canvas,video{display:inline-block;*display:inline;*zoom:1}","[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}","mark{background:#FF0;color:#000}","</style>"].join(""),h.insertBefore(j.lastChild,h.firstChild)}return a}};e.shivDocument(b),a.html5=e;if(c||!a.attachEvent)return;a.attachEvent("onbeforeprint",function(){if(a.html5.supportsXElement||!b.namespaces)return;b.namespaces.shiv||b.namespaces.add("shiv");var c=-1,d=new RegExp("^("+a.html5.elements.join("|")+")$","i"),e=b.getElementsByTagName("*"),g=e.length,j,k=i(h(function(a,b){var c=[],d=a.length;while(d)c.unshift(a[--d]);d=b.length;while(d)c.unshift(b[--d]);c.sort(function(a,b){return a.sourceIndex-b.sourceIndex}),d=c.length;while(d)c[--d]=c[d].styleSheet;return c}(b.getElementsByTagName("style"),b.getElementsByTagName("link"))));while(++c<g)j=e[c],d.test(j.nodeName)&&f(j);b.appendChild(b._shivedStyleSheet=b.createElement("style")).styleSheet.cssText=k}),a.attachEvent("onafterprint",function(){if(a.html5.supportsXElement||!b.namespaces)return;var c=-1,d=b.getElementsByTagName("*"),e=d.length,f;while(++c<e)f=d[c],f.originalElement&&g(f);b._shivedStyleSheet&&b._shivedStyleSheet.parentNode.removeChild(b._shivedStyleSheet)})})(this,document)

View File

@ -0,0 +1,82 @@
header h3 a, header .brand {
display:none !important;
}
@media screen and (max-device-width: 1600px) {
.container>.pull-right>* {
position: absolute;
top: 1rem;
right: 0.5rem;
cursor: pointer;
}
}
@media screen and (max-width: 480px) {
body {
font-size: 12px;
}
header {
font-size: 13px;
}
legend {
font-size: 14px;
}
.dropdown-menu a {
font-size: 13px;
min-width: 130px;
padding: 0 15px;
}
.mobile-hide {
display: none;
}
#maincontent.container {
padding: 0px 10px;
}
div.cbi-section, fieldset {
min-width: inherit;
overflow-x: auto;
overflow-y: hidden;
}
.cbi-value {
}
.cbi-value-title {
width: 30%;
min-width: 0rem !important;
margin-right: 1em;
/* text-align: left;
padding-left: 1em; */
}
.cbi-value-field {
width: 55%;
}
.cbi-value-description {
width: 75%;
display: inline-table;
padding: 1px 1.2rem;
background-position-y: 3px;
}
.cbi-value-field .cbi-input-select,
.cbi-value input[type="password"],
.cbi-value input[type="text"] {
min-width: unset;
/* width: 95%; */
}
}
@media screen and (max-device-width: 600px) {
#maincontent.container {
margin-top: 30px;
}
}
@media screen and (max-device-width: 360px) {
#maincontent.container {
margin-top: 30px;
}
}
@media screen and (max-device-width: 200px) {
#maincontent.container {
margin-top: 30px;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,56 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
Copyright 2012 David Menting <david@nut-bolt.nl>
Copyright 2018 Lienol <lawlienol@gmail.com>
Licensed to the public under the Apache License 2.0.
-%>
<%
local ver = require "luci.version"
local disp = require "luci.dispatcher"
local request = disp.context.path
local category = request[1]
local tree = disp.node()
local categories = disp.node_childs(tree)
%>
<footer>
<a href="https://github.com/openwrt/luci">Powered by <%= ver.luciname %></a> / <%= ver.distversion %>
<% if #categories > 1 then %>
<ul class="breadcrumb pull-right" id="modemenu">
<% for i, r in ipairs(categories) do %>
<li<% if request[1] == r then %> class="active"<%end%>><a href="<%=controller%>/<%=r%>/"><%=striptags(translate(tree.nodes[r].title))%></a> <span class="divider">|</span></li>
<% end %>
</ul>
<% end %>
</footer>
</div>
</div>
</body>
<script>
window.onload = function(){
var content = document.getElementsByName("content");
var luci_username = document.getElementsByName("luci_username");
var luci_password = document.getElementsByName("luci_password");
if (content.length == 1 && luci_username.length == 1 && luci_password.length == 1) {
//需要登录
document.body.classList.add('node-main-login');
luci_username[0].parentElement.parentElement.classList.add('luci_username_div');
luci_username[0].parentElement.parentElement.children[0].style.display = "none";
luci_password[0].parentElement.parentElement.classList.add('luci_password_div');
luci_password[0].parentElement.parentElement.children[0].style.display = "none";
var errorbox = document.getElementsByClassName("errorbox");
if (errorbox.length == 1) {
var tips = document.getElementsByClassName("cbi-map-descr");
if (tips.length == 1) {
tips[0].innerHTML = errorbox[0].innerHTML;
tips[0].classList.add('errorbox');
errorbox[0].style.display = "none";
}
}
}
}
</script>
</html>

View File

@ -0,0 +1,214 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
Copyright 2012 David Menting <david@nut-bolt.nl>
Copyright 2018 Lienol <lawlienol@gmail.com>
Licensed to the public under the Apache License 2.0.
-%>
<%
local sys = require "luci.sys"
local util = require "luci.util"
local http = require "luci.http"
local disp = require "luci.dispatcher"
local boardinfo = util.ubus("system", "board")
local request = disp.context.path
local request2 = disp.context.request
local category = request[1]
local cattree = category and disp.node(category)
local leaf = request2[#request2]
local tree = disp.node()
local node = disp.context.dispatched
local categories = disp.node_childs(tree)
local c = tree
local i, r
-- tag all nodes leading to this page
for i, r in ipairs(request) do
if c.nodes and c.nodes[r] then
c = c.nodes[r]
c._menu_selected = true
end
end
-- send as HTML5
http.prepare_content("text/html")
local function nodeurl(prefix, name, query)
local u = url(prefix, name)
if query then
u = u .. http.build_querystring(query)
end
return pcdata(u)
end
local function render_tabmenu(prefix, node, level)
if not level then
level = 1
end
local childs = disp.node_childs(node)
if #childs > 0 then
if level > 2 then
write('<ul class="tabs">')
end
local selected_node
local selected_name
local i, v
for i, v in ipairs(childs) do
local nnode = node.nodes[v]
if nnode._menu_selected then
selected_node = nnode
selected_name = v
end
if level > 2 then
write('<li class="tabmenu-item-%s %s"><a href="%s">%s</a></li>' %{
v, (nnode._menu_selected or (node.leaf and v == leaf)) and 'active' or '',
nodeurl(prefix, v, nnode.query),
striptags(translate(nnode.title))
})
end
end
if level > 2 then
write('</ul>')
end
if selected_node then
render_tabmenu(prefix .. "/" .. selected_name, selected_node, level + 1)
end
end
end
local function render_submenu(prefix, node)
local childs = disp.node_childs(node)
if #childs > 0 then
write('<ul class="dropdown-menu">')
for i, r in ipairs(childs) do
local nnode = node.nodes[r]
write('<li><a href="%s">%s</a></li>' %{
nodeurl(prefix, r, nnode.query),
pcdata(striptags(translate(nnode.title)))
})
end
write('</ul>')
end
end
local function render_topmenu()
local childs = disp.node_childs(cattree)
if #childs > 0 then
write('<ul class="nav">')
for i, r in ipairs(childs) do
local nnode = cattree.nodes[r]
local grandchildren = disp.node_childs(nnode)
if #grandchildren > 0 then
write('<li class="dropdown"><a class="menu" href="#">%s</a>' % pcdata(striptags(translate(nnode.title))))
render_submenu(category .. "/" .. r, nnode)
write('</li>')
else
write('<li><a href="%s">%s</a></li>' %{
nodeurl(category, r, nnode.query),
pcdata(striptags(translate(nnode.title)))
})
end
end
write('</ul>')
end
end
local function render_changes()
-- calculate the number of unsaved changes
if tree.nodes[category] and tree.nodes[category].ucidata then
local ucichanges = 0
for i, j in pairs(require("luci.model.uci").cursor():changes()) do
for k, l in pairs(j) do
for m, n in pairs(l) do
ucichanges = ucichanges + 1;
end
end
end
if ucichanges > 0 then
write('<a class="uci_change_indicator label notice" href="%s?redir=%s">%s: %d</a>' %{
url(category, 'uci/changes'),
http.urlencode(http.formvalue('redir') or table.concat(disp.context.request, "/")),
translate('Unsaved Changes'),
ucichanges
})
end
end
end
-%>
<!DOCTYPE html>
<html lang="<%=luci.i18n.context.lang%>">
<head>
<meta charset="utf-8">
<title><%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI</title>
<!--[if lt IE 9]><script src="<%=media%>/html5.js?v=git-18.138.53009-80cb4fe"></script><![endif]-->
<meta name="viewport" content="initial-scale=1.0">
<link rel="stylesheet" href="<%=media%>/cascade.css?v=git-18.138.53009-80cb4fe">
<link rel="stylesheet" media="only screen and (max-device-width: 854px)" href="<%=media%>/mobile.css?v=git-18.138.53009-80cb4fe" type="text/css" />
<link rel="shortcut icon" href="<%=media%>/favicon.ico">
<% if node and node.css then %>
<link rel="stylesheet" href="<%=resource%>/<%=node.css%>">
<% end -%>
<% if css then %>
<style title="text/css"><%= css %></style>
<% end -%>
<script src="<%=resource%>/cbi.js?v=git-19.060.34677-e62cc32"></script>
<script src="<%=resource%>/xhr.js?v=git-18.138.53009-80cb4fe"></script>
</head>
<body class="lang_<%=luci.i18n.context.lang%> <%- if node then %><%= striptags( node.title ) %><%- end %>">
<header>
<div class="fill">
<div class="container">
<a class="brand" href="#"><%=boardinfo.hostname or "?"%></a>
<% render_topmenu() %>
<div class="pull-right">
<% render_changes() %>
<span id="xhr_poll_status" style="display:none" onclick="XHR.running() ? XHR.halt() : XHR.run()">
<span class="label success" id="xhr_poll_status_on"><span class="mobile-hide"><%:Auto Refresh%> </span><%:on%></span>
<span class="label" id="xhr_poll_status_off" style="display:none"><span class="mobile-hide"><%:Auto Refresh%> </span><%:off%></span>
</span>
</div>
</div>
</div>
</header>
<%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") then -%>
<div class="container">
<div class="alert-message warning">
<h4><%:No password set!%></h4>
<%:There is no password set on this router. Please configure a root password to protect the web interface and enable SSH.%><br>
<a href="<%=pcdata(luci.dispatcher.build_url("admin/system/admin"))%>"><%:Go to password configuration...%></a>
</div>
</div>
<%- end -%>
<noscript>
<div class="alert-message warning">
<strong><%:JavaScript required!%></strong><br />
<%:You must enable JavaScript in your browser or LuCI will not work properly.%>
</div>
</noscript>
<div id="maincontent" class="container">
<% if category then render_tabmenu(category, cattree) end %>

View File

@ -0,0 +1,56 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
Copyright 2012 David Menting <david@nut-bolt.nl>
Copyright 2018 Lienol <lawlienol@gmail.com>
Licensed to the public under the Apache License 2.0.
-%>
<%
local ver = require "luci.version"
local disp = require "luci.dispatcher"
local request = disp.context.path
local category = request[1]
local tree = disp.node()
local categories = disp.node_childs(tree)
%>
<footer>
<a href="https://github.com/openwrt/luci">Powered by <%= ver.luciname %></a> / <%= ver.distversion %>
<% if #categories > 1 then %>
<ul class="breadcrumb pull-right" id="modemenu">
<% for i, r in ipairs(categories) do %>
<li<% if request[1] == r then %> class="active"<%end%>><a href="<%=controller%>/<%=r%>/"><%=striptags(translate(tree.nodes[r].title))%></a> <span class="divider">|</span></li>
<% end %>
</ul>
<% end %>
</footer>
</div>
</div>
</body>
<script>
window.onload = function(){
var content = document.getElementsByName("content");
var luci_username = document.getElementsByName("luci_username");
var luci_password = document.getElementsByName("luci_password");
if (content.length == 1 && luci_username.length == 1 && luci_password.length == 1) {
//需要登录
document.body.classList.add('node-main-login');
luci_username[0].parentElement.parentElement.classList.add('luci_username_div');
luci_username[0].parentElement.parentElement.children[0].style.display = "none";
luci_password[0].parentElement.parentElement.classList.add('luci_password_div');
luci_password[0].parentElement.parentElement.children[0].style.display = "none";
var errorbox = document.getElementsByClassName("errorbox");
if (errorbox.length == 1) {
var tips = document.getElementsByClassName("cbi-map-descr");
if (tips.length == 1) {
tips[0].innerHTML = errorbox[0].innerHTML;
tips[0].classList.add('errorbox');
errorbox[0].style.display = "none";
}
}
}
}
</script>
</html>

View File

@ -0,0 +1,214 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
Copyright 2012 David Menting <david@nut-bolt.nl>
Copyright 2018 Lienol <lawlienol@gmail.com>
Licensed to the public under the Apache License 2.0.
-%>
<%
local sys = require "luci.sys"
local util = require "luci.util"
local http = require "luci.http"
local disp = require "luci.dispatcher"
local boardinfo = util.ubus("system", "board")
local request = disp.context.path
local request2 = disp.context.request
local category = request[1]
local cattree = category and disp.node(category)
local leaf = request2[#request2]
local tree = disp.node()
local node = disp.context.dispatched
local categories = disp.node_childs(tree)
local c = tree
local i, r
-- tag all nodes leading to this page
for i, r in ipairs(request) do
if c.nodes and c.nodes[r] then
c = c.nodes[r]
c._menu_selected = true
end
end
-- send as HTML5
http.prepare_content("text/html")
local function nodeurl(prefix, name, query)
local u = url(prefix, name)
if query then
u = u .. http.build_querystring(query)
end
return pcdata(u)
end
local function render_tabmenu(prefix, node, level)
if not level then
level = 1
end
local childs = disp.node_childs(node)
if #childs > 0 then
if level > 2 then
write('<ul class="tabs">')
end
local selected_node
local selected_name
local i, v
for i, v in ipairs(childs) do
local nnode = node.nodes[v]
if nnode._menu_selected then
selected_node = nnode
selected_name = v
end
if level > 2 then
write('<li class="tabmenu-item-%s %s"><a href="%s">%s</a></li>' %{
v, (nnode._menu_selected or (node.leaf and v == leaf)) and 'active' or '',
nodeurl(prefix, v, nnode.query),
striptags(translate(nnode.title))
})
end
end
if level > 2 then
write('</ul>')
end
if selected_node then
render_tabmenu(prefix .. "/" .. selected_name, selected_node, level + 1)
end
end
end
local function render_submenu(prefix, node)
local childs = disp.node_childs(node)
if #childs > 0 then
write('<ul class="dropdown-menu">')
for i, r in ipairs(childs) do
local nnode = node.nodes[r]
write('<li><a href="%s">%s</a></li>' %{
nodeurl(prefix, r, nnode.query),
pcdata(striptags(translate(nnode.title)))
})
end
write('</ul>')
end
end
local function render_topmenu()
local childs = disp.node_childs(cattree)
if #childs > 0 then
write('<ul class="nav">')
for i, r in ipairs(childs) do
local nnode = cattree.nodes[r]
local grandchildren = disp.node_childs(nnode)
if #grandchildren > 0 then
write('<li class="dropdown"><a class="menu" href="#">%s</a>' % pcdata(striptags(translate(nnode.title))))
render_submenu(category .. "/" .. r, nnode)
write('</li>')
else
write('<li><a href="%s">%s</a></li>' %{
nodeurl(category, r, nnode.query),
pcdata(striptags(translate(nnode.title)))
})
end
end
write('</ul>')
end
end
local function render_changes()
-- calculate the number of unsaved changes
if tree.nodes[category] and tree.nodes[category].ucidata then
local ucichanges = 0
for i, j in pairs(require("luci.model.uci").cursor():changes()) do
for k, l in pairs(j) do
for m, n in pairs(l) do
ucichanges = ucichanges + 1;
end
end
end
if ucichanges > 0 then
write('<a class="uci_change_indicator label notice" href="%s?redir=%s">%s: %d</a>' %{
url(category, 'uci/changes'),
http.urlencode(http.formvalue('redir') or table.concat(disp.context.request, "/")),
translate('Unsaved Changes'),
ucichanges
})
end
end
end
-%>
<!DOCTYPE html>
<html lang="<%=luci.i18n.context.lang%>">
<head>
<meta charset="utf-8">
<title><%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI</title>
<!--[if lt IE 9]><script src="<%=media%>/html5.js?v=git-18.138.53009-80cb4fe"></script><![endif]-->
<meta name="viewport" content="initial-scale=1.0">
<link rel="stylesheet" href="<%=media%>/cascade.css?v=git-18.138.53009-80cb4fe">
<link rel="stylesheet" media="only screen and (max-device-width: 854px)" href="<%=media%>/mobile.css?v=git-18.138.53009-80cb4fe" type="text/css" />
<link rel="shortcut icon" href="<%=media%>/favicon.ico">
<% if node and node.css then %>
<link rel="stylesheet" href="<%=resource%>/<%=node.css%>">
<% end -%>
<% if css then %>
<style title="text/css"><%= css %></style>
<% end -%>
<script src="<%=resource%>/cbi.js?v=git-19.060.34677-e62cc32"></script>
<script src="<%=resource%>/xhr.js?v=git-18.138.53009-80cb4fe"></script>
</head>
<body class="lang_<%=luci.i18n.context.lang%> <%- if node then %><%= striptags( node.title ) %><%- end %>">
<header>
<div class="fill">
<div class="container">
<a class="brand" href="#"><%=boardinfo.hostname or "?"%></a>
<% render_topmenu() %>
<div class="pull-right">
<% render_changes() %>
<span id="xhr_poll_status" style="display:none" onclick="XHR.running() ? XHR.halt() : XHR.run()">
<span class="label success" id="xhr_poll_status_on"><span class="mobile-hide"><%:Auto Refresh%> </span><%:on%></span>
<span class="label" id="xhr_poll_status_off" style="display:none"><span class="mobile-hide"><%:Auto Refresh%> </span><%:off%></span>
</span>
</div>
</div>
</div>
</header>
<%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") then -%>
<div class="container">
<div class="alert-message warning">
<h4><%:No password set!%></h4>
<%:There is no password set on this router. Please configure a root password to protect the web interface and enable SSH.%><br>
<a href="<%=pcdata(luci.dispatcher.build_url("admin/system/admin"))%>"><%:Go to password configuration...%></a>
</div>
</div>
<%- end -%>
<noscript>
<div class="alert-message warning">
<strong><%:JavaScript required!%></strong><br />
<%:You must enable JavaScript in your browser or LuCI will not work properly.%>
</div>
</noscript>
<div id="maincontent" class="container">
<% if category then render_tabmenu(category, cattree) end %>

View File

@ -0,0 +1,7 @@
#!/bin/sh
uci batch <<-EOF
set luci.themes.Bootstrap_Blue=/luci-static/bootstrap_blue
set luci.themes.Bootstrap_Purple=/luci-static/bootstrap_purple
commit luci
EOF
exit 0

View File

@ -0,0 +1,42 @@
#
# Copyright (C) 2014 OpenWrt-dist
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=tcping
PKG_VERSION:=0.1
PKG_RELEASE:=2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/jlyo/tcping.git
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=79ef6f85d7147d33d0835fac060618ab136503c8
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
define Package/tcping
SECTION:=net
CATEGORY:=Network
TITLE:=tcping measures the latency of a tcp-connection
URL:=https://github.com/jlyo/tcping
endef
define Package/tcping/description
endef
define Package/tcping/conffiles
endef
define Package/tcping/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/tcping $(1)/usr/sbin
endef
$(eval $(call BuildPackage,tcping))