From d109fab03469cef0fbf364ffa12ba2e20b06a616 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 22 Mar 2026 08:48:09 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=88=20Sync=202026-03-22=2008:48:09?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- filebrowser/Makefile | 2 +- luci-app-socat/Makefile | 7 +- .../luci-static/resources/view/socat.js | 148 +++++++++++++++ luci-app-socat/luasrc/controller/socat.lua | 21 --- .../luasrc/model/cbi/socat/config.lua | 82 --------- .../luasrc/model/cbi/socat/index.lua | 78 -------- .../luasrc/view/socat/list_status.htm | 19 -- luci-app-socat/luasrc/view/socat/status.htm | 3 - luci-app-socat/po/templates/socat.pot | 108 +++++++++++ luci-app-socat/po/zh_Hans/socat.po | 98 +++++++--- luci-app-socat/root/etc/config/luci_socat | 4 + luci-app-socat/root/etc/init.d/luci_socat | 168 ++++++++++-------- .../root/etc/uci-defaults/luci-app-socat | 21 --- .../usr/share/luci/menu.d/luci-app-socat.json | 12 ++ .../usr/share/rpcd/acl.d/luci-app-socat.json | 3 + .../usr/share/ucitrack/luci-app-socat.json | 2 +- 16 files changed, 446 insertions(+), 330 deletions(-) create mode 100644 luci-app-socat/htdocs/luci-static/resources/view/socat.js delete mode 100644 luci-app-socat/luasrc/controller/socat.lua delete mode 100644 luci-app-socat/luasrc/model/cbi/socat/config.lua delete mode 100644 luci-app-socat/luasrc/model/cbi/socat/index.lua delete mode 100644 luci-app-socat/luasrc/view/socat/list_status.htm delete mode 100644 luci-app-socat/luasrc/view/socat/status.htm create mode 100644 luci-app-socat/po/templates/socat.pot create mode 100644 luci-app-socat/root/etc/config/luci_socat delete mode 100644 luci-app-socat/root/etc/uci-defaults/luci-app-socat create mode 100644 luci-app-socat/root/usr/share/luci/menu.d/luci-app-socat.json diff --git a/filebrowser/Makefile b/filebrowser/Makefile index 73db0e1a..3c420928 100644 --- a/filebrowser/Makefile +++ b/filebrowser/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=filebrowser -PKG_VERSION:=1.2.2-stable +PKG_VERSION:=1.2.3-stable PKG_RELEASE=1 ifeq ($(ARCH),aarch64) diff --git a/luci-app-socat/Makefile b/luci-app-socat/Makefile index 03c78b47..7c25cdb0 100644 --- a/luci-app-socat/Makefile +++ b/luci-app-socat/Makefile @@ -6,10 +6,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-socat -PKG_VERSION:=1.0 -PKG_RELEASE:=1 +PKG_VERSION:=1.1 +PKG_RELEASE:=2 -PKG_MAINTAINER:=Lienol +PKG_MAINTAINER:=Lienol \ + sbwml LUCI_TITLE:=LuCI support for Socat LUCI_DEPENDS:=+socat diff --git a/luci-app-socat/htdocs/luci-static/resources/view/socat.js b/luci-app-socat/htdocs/luci-static/resources/view/socat.js new file mode 100644 index 00000000..07c1fcd6 --- /dev/null +++ b/luci-app-socat/htdocs/luci-static/resources/view/socat.js @@ -0,0 +1,148 @@ +'use strict'; +'require view'; +'require form'; +'require rpc'; +'require uci'; +'require poll'; +'require network'; + +var callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: ['name'], + expect: { '': {} } +}); + +return view.extend({ + load: function () { + return Promise.all([ + network.getHostHints() + ]); + }, + + render: function (data) { + var m, s, o; + var hostHints = data[0]; + + m = new form.Map('luci_socat', _('Socat'), _('Socat is a relay for bidirectional data transfer between two independent data channels.')); + + s = m.section(form.NamedSection, 'global', 'global', _('Global Settings')); + s.addremove = false; + + o = s.option(form.Flag, 'enable', _('Enabled')); + o.rmempty = true; + + s = m.section(form.GridSection, 'config', _('Port Forwarding')); + s.addremove = true; + s.anonymous = true; + s.sortable = true; + s.nodescriptions = true; + + var super_handleAdd = s.handleAdd; + s.handleAdd = function (ev) { + var uuid = Array.from({length: 32}, () => Math.floor(Math.random() * 16).toString(16)).join(''); + return super_handleAdd.call(this, ev, uuid); + }; + + s.modaltitle = function (section_id) { + return _('Socat Configuration'); + }; + + o = s.option(form.Flag, 'enable', _('Enabled')); + o.editable = true; + o.default = '1'; + o.rmempty = false; + + o = s.option(form.DummyValue, '_status', _('Status')); + o.modalonly = false; + o.cfgvalue = function() { + return '-'; + }; + + poll.add(function () { + return callServiceList('luci_socat').then(function (res) { + var instances = (res && res.luci_socat && res.luci_socat.instances) ? res.luci_socat.instances : {}; + + document.querySelectorAll('tr[data-sid]').forEach(function (row) { + var sid = row.getAttribute('data-sid'); + if (!sid) return; + sid = sid.trim(); + + var cell = row.querySelector('td[data-name="_status"]'); + if (!cell) return; + + var isRunning = !!instances[sid]; + + cell.innerHTML = isRunning ? '🟢' : '🔴'; + }); + }); + }); + + o = s.option(form.Value, 'remarks', _('Remarks')); + + o = s.option(form.ListValue, "protocol", _("Protocol Type")); + o.value("port_forwards", _("Port Forwarding")); + o.modalonly = true; + + o = s.option(form.ListValue, "family", _("Listen Address Family")); + o.value("", _("IPv4 and IPv6")); + o.value("4", _("IPv4 Only")); + o.value("6", _("IPv6 Only")); + o.depends("protocol", "port_forwards"); + o.modalonly = true; + + o = s.option(form.ListValue, "proto", _("Listen Protocol")); + o.value("tcp", "TCP"); + o.value("udp", "UDP"); + o.depends("protocol", "port_forwards"); + o.textvalue = function (section_id) { + var family_val = uci.get('luci_socat', section_id, 'family'); + var proto_val = uci.get('luci_socat', section_id, 'proto'); + if (proto_val) { + if (family_val === '4') return 'IPv4-' + proto_val.toUpperCase(); + if (family_val === '6') return 'IPv6-' + proto_val.toUpperCase(); + return 'ALL-' + proto_val.toUpperCase(); + } + }; + + o = s.option(form.Value, "listen_port", _("Listen Port")); + o.datatype = "portrange"; + o.rmempty = false; + o.depends("protocol", "port_forwards"); + + o = s.option(form.Flag, "reuseaddr", _("Reuse Port"), _("Allow binding to the port even when previous connections are in TIME_WAIT, preventing restart failures.")); + o.default = "1"; + o.rmempty = false; + o.modalonly = true; + + o = s.option(form.ListValue, "dest_proto", _("Destination Protocol")); + o.value("tcp4", "IPv4-TCP"); + o.value("udp4", "IPv4-UDP"); + o.value("tcp6", "IPv6-TCP"); + o.value("udp6", "IPv6-UDP"); + o.depends("protocol", "port_forwards"); + + o = s.option(form.Value, 'dest_ip', _('Destination Address')); + o.rmempty = false; + o.depends("protocol", "port_forwards"); + o.value('127.0.0.1', ('127.0.0.1 (localhost)')); + hostHints.getMACHints().forEach(function (entry) { + var mac = entry[0]; + var hint = entry[1] || mac; + var ip = hostHints.getIPAddrByMACAddr(mac); + if (ip) + o.value(ip, '%s (%s)'.format(ip, hint)); + }); + + o = s.option(form.Value, "dest_port", _("Destination Port")); + o.datatype = "portrange"; + o.rmempty = false; + + o = s.option(form.Flag, "firewall_accept", _("Open Firewall Port")); + o.editable = true; + o.default = "0"; + o.rmempty = false; + + return m.render(); + } +}); diff --git a/luci-app-socat/luasrc/controller/socat.lua b/luci-app-socat/luasrc/controller/socat.lua deleted file mode 100644 index db4482bc..00000000 --- a/luci-app-socat/luasrc/controller/socat.lua +++ /dev/null @@ -1,21 +0,0 @@ --- Copyright 2020 Lienol -module("luci.controller.socat", package.seeall) - -function index() - if not nixio.fs.access("/etc/config/socat") then - return - end - - entry({"admin", "network", "socat"}, alias("admin", "network", "socat", "index"), _("Socat"), 100).dependent = true - entry({"admin", "network", "socat", "index"}, cbi("socat/index")).leaf = true - entry({"admin", "network", "socat", "config"}, cbi("socat/config")).leaf = true - entry({"admin", "network", "socat", "status"}, call("act_status")).leaf = true -end - -function act_status() - local e = {} - e.index = luci.http.formvalue("index") - e.status = luci.sys.call(string.format("busybox ps -w | grep -v 'grep' | grep '/var/etc/socat/%s' >/dev/null", luci.http.formvalue("id"))) == 0 - luci.http.prepare_content("application/json") - luci.http.write_json(e) -end diff --git a/luci-app-socat/luasrc/model/cbi/socat/config.lua b/luci-app-socat/luasrc/model/cbi/socat/config.lua deleted file mode 100644 index 0a04ce6c..00000000 --- a/luci-app-socat/luasrc/model/cbi/socat/config.lua +++ /dev/null @@ -1,82 +0,0 @@ -local d = require "luci.dispatcher" - -m = Map("socat", translate("Socat Config")) -m.redirect = d.build_url("admin", "network", "socat") - -s = m:section(NamedSection, arg[1], "config", "") -s.addremove = false -s.dynamic = false - -o = s:option(Flag, "enable", translate("Enable")) -o.default = "1" -o.rmempty = false - -o = s:option(Value, "remarks", translate("Remarks")) -o.default = translate("Remarks") -o.rmempty = false - -o = s:option(ListValue, "protocol", translate("Protocol")) -o:value("port_forwards", translate("Port Forwards")) - -o = s:option(ListValue, "family", translate("Restrict to address family")) -o:value("", translate("IPv4 and IPv6")) -o:value("4", translate("IPv4 only")) -o:value("6", translate("IPv6 only")) -o:depends("protocol", "port_forwards") - -o = s:option(ListValue, "proto", translate("Protocol")) -o:value("tcp", "TCP") -o:value("udp", "UDP") -o:depends("protocol", "port_forwards") - -o = s:option(Value, "listen_port", translate("Listen port")) -o.datatype = "portrange" -o.rmempty = false -o:depends("protocol", "port_forwards") - -o = s:option(Flag, "reuseaddr", translate("REUSEADDR"), translate("Bind to a port local")) -o.default = "1" -o.rmempty = false - -o = s:option(ListValue, "dest_proto", translate("Destination Protocol")) -o:value("tcp4", "IPv4-TCP") -o:value("udp4", "IPv4-UDP") -o:value("tcp6", "IPv6-TCP") -o:value("udp6", "IPv6-UDP") -o:depends("protocol", "port_forwards") - -dest_ipv4 = s:option(Value, "dest_ipv4", translate("Destination address")) -luci.sys.net.ipv4_hints(function(ip, name) - dest_ipv4:value(ip, "%s (%s)" %{ ip, name }) -end) -function dest_ipv4.cfgvalue(self, section) - return m:get(section, "dest_ip") -end -function dest_ipv4.write(self, section, value) - m:set(section, "dest_ip", value) -end -dest_ipv4:depends("dest_proto", "tcp4") -dest_ipv4:depends("dest_proto", "udp4") - -dest_ipv6 = s:option(Value, "dest_ipv6", translate("Destination address")) -luci.sys.net.ipv6_hints(function(ip, name) - dest_ipv6:value(ip, "%s (%s)" %{ ip, name }) -end) -function dest_ipv6.cfgvalue(self, section) - return m:get(section, "dest_ip") -end -function dest_ipv6.write(self, section, value) - m:set(section, "dest_ip", value) -end -dest_ipv6:depends("dest_proto", "tcp6") -dest_ipv6:depends("dest_proto", "udp6") - -o = s:option(Value, "dest_port", translate("Destination port")) -o.datatype = "portrange" -o.rmempty = false - -o = s:option(Flag, "firewall_accept", translate("Open firewall port")) -o.default = "1" -o.rmempty = false - -return m diff --git a/luci-app-socat/luasrc/model/cbi/socat/index.lua b/luci-app-socat/luasrc/model/cbi/socat/index.lua deleted file mode 100644 index d44d197c..00000000 --- a/luci-app-socat/luasrc/model/cbi/socat/index.lua +++ /dev/null @@ -1,78 +0,0 @@ -local d = require "luci.dispatcher" -local e = luci.model.uci.cursor() - -m = Map("socat") -m.title = translate("Socat") -m.description = translate("Socat is a relay for bidirectional data transfer between two independent data channels.") - -s = m:section(NamedSection, "global", "global") -s.anonymous = true -s.addremove = false - -o = s:option(Flag, "enable", translate("Enable")) -o.rmempty = false - -s = m:section(TypedSection, "config", translate("Port Forwards")) -s.anonymous = true -s.addremove = true -s.template = "cbi/tblsection" -s.extedit = d.build_url("admin", "network", "socat", "config", "%s") -function s.filter(e, t) - if m:get(t, "protocol") == "port_forwards" then - return true - end -end -function s.create(e, t) - local uuid = string.gsub(luci.sys.exec("echo -n $(cat /proc/sys/kernel/random/uuid)"), "-", "") - t = uuid - TypedSection.create(e, t) - luci.http.redirect(e.extedit:format(t)) -end -function s.remove(e, t) - e.map.proceed = true - e.map:del(t) - luci.http.redirect(d.build_url("admin", "network", "socat")) -end - -o = s:option(Flag, "enable", translate("Enable")) -o.width = "5%" -o.rmempty = false - -o = s:option(DummyValue, "status", translate("Status")) -o.template = "socat/status" -o.value = translate("Collecting data...") - -o = s:option(DummyValue, "remarks", translate("Remarks")) - -o = s:option(DummyValue, "family", translate("Listen Protocol")) -o.cfgvalue = function(t, n) - local listen = Value.cfgvalue(t, n) or "" - local protocol = (m:get(n, "proto") or ""):upper() - if listen == "" then - return protocol - else - return "IPv" .. listen .. "-" .. protocol - end -end - -o = s:option(DummyValue, "listen_port", translate("Listen port")) - -o = s:option(DummyValue, "dest_proto", translate("Destination Protocol")) -o.cfgvalue = function(t, n) - local listen = Value.cfgvalue(t, n) - local protocol = listen:sub(0, #listen - 1):upper() - local ip_type = "IPv" .. listen:sub(#listen) - return ip_type .. "-" .. protocol -end - -o = s:option(DummyValue, "dest_ip", translate("Destination address")) - -o = s:option(DummyValue, "dest_port", translate("Destination port")) - -o = s:option(Flag, "firewall_accept", translate("Open firewall port")) -o.default = "1" -o.rmempty = false - -m:append(Template("socat/list_status")) - -return m diff --git a/luci-app-socat/luasrc/view/socat/list_status.htm b/luci-app-socat/luasrc/view/socat/list_status.htm deleted file mode 100644 index 4da041ed..00000000 --- a/luci-app-socat/luasrc/view/socat/list_status.htm +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/luci-app-socat/luasrc/view/socat/status.htm b/luci-app-socat/luasrc/view/socat/status.htm deleted file mode 100644 index 241baaec..00000000 --- a/luci-app-socat/luasrc/view/socat/status.htm +++ /dev/null @@ -1,3 +0,0 @@ -<%+cbi/valueheader%> --- -<%+cbi/valuefooter%> diff --git a/luci-app-socat/po/templates/socat.pot b/luci-app-socat/po/templates/socat.pot new file mode 100644 index 00000000..da54eb68 --- /dev/null +++ b/luci-app-socat/po/templates/socat.pot @@ -0,0 +1,108 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-03-22 03:30+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: htdocs/luci-static/resources/view/socat.js:27 +msgid "Socat" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:27 +msgid "" +"Socat is a relay for bidirectional data transfer between two independent " +"data channels." +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:29 +msgid "Global Settings" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:32 +#: htdocs/luci-static/resources/view/socat.js:51 +msgid "Enabled" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:35 +#: htdocs/luci-static/resources/view/socat.js:84 +msgid "Port Forwarding" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:48 +msgid "Socat Configuration" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:56 +msgid "Status" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:81 +msgid "Remarks" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:83 +msgid "Protocol Type" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:87 +msgid "Listen Address Family" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:88 +msgid "IPv4 and IPv6" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:89 +msgid "IPv4 Only" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:90 +msgid "IPv6 Only" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:94 +msgid "Listen Protocol" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:108 +msgid "Listen Port" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:113 +msgid "Reuse Port" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:113 +msgid "" +"Allow binding to the port even when previous connections are in TIME_WAIT, " +"preventing restart failures." +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:118 +msgid "Destination Protocol" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:125 +msgid "Destination Address" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:137 +msgid "Destination Port" +msgstr "" + +#: htdocs/luci-static/resources/view/socat.js:141 +msgid "Open Firewall Port" +msgstr "" diff --git a/luci-app-socat/po/zh_Hans/socat.po b/luci-app-socat/po/zh_Hans/socat.po index f92b0d48..dba7f362 100644 --- a/luci-app-socat/po/zh_Hans/socat.po +++ b/luci-app-socat/po/zh_Hans/socat.po @@ -1,53 +1,103 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-03-22 03:12+0800\n" +"PO-Revision-Date: 2026-03-22 03:13+0800\n" +"Last-Translator: sbwml \n" +"Language-Team: Chinese\n" +"Language: zh_Hans\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: htdocs/luci-static/resources/view/socat.js:27 +#: root/usr/share/luci/menu.d/luci-app-socat.json:3 msgid "Socat" -msgstr "Socat" +msgstr "" -msgid "Socat is a relay for bidirectional data transfer between two independent data channels." -msgstr "Socat 是用于在两个独立数据通道之间进行双向数据传输的中继器。" +#: htdocs/luci-static/resources/view/socat.js:27 +msgid "" +"Socat is a relay for bidirectional data transfer between two independent " +"data channels." +msgstr "Socat 是一个在两个独立数据通道之间进行双向数据转发的工具。" -msgid "Socat Config" -msgstr "Socat 配置" - -msgid "Status" -msgstr "状态" +#: htdocs/luci-static/resources/view/socat.js:29 +msgid "Global Settings" +msgstr "全局设置" +#: htdocs/luci-static/resources/view/socat.js:32 +#: htdocs/luci-static/resources/view/socat.js:51 msgid "Enabled" msgstr "启用" +#: htdocs/luci-static/resources/view/socat.js:35 +#: htdocs/luci-static/resources/view/socat.js:84 +msgid "Port Forwarding" +msgstr "端口转发" + +#: htdocs/luci-static/resources/view/socat.js:48 +msgid "Socat Configuration" +msgstr "Socat 配置" + +#: htdocs/luci-static/resources/view/socat.js:56 +msgid "Status" +msgstr "状态" + +#: htdocs/luci-static/resources/view/socat.js:81 msgid "Remarks" msgstr "备注" -msgid "Protocol" -msgstr "协议" +#: htdocs/luci-static/resources/view/socat.js:83 +msgid "Protocol Type" +msgstr "协议类型" +#: htdocs/luci-static/resources/view/socat.js:87 +msgid "Listen Address Family" +msgstr "监听地址族" + +#: htdocs/luci-static/resources/view/socat.js:88 +msgid "IPv4 and IPv6" +msgstr "IPv4 和 IPv6" + +#: htdocs/luci-static/resources/view/socat.js:89 +msgid "IPv4 Only" +msgstr "仅 IPv4" + +#: htdocs/luci-static/resources/view/socat.js:90 msgid "IPv6 Only" msgstr "仅 IPv6" -msgid "When checked, only IPv6 ports are listen for, otherwise IPv4 will also be listened for." -msgstr "当勾选时,仅监听 IPv6,否则将会同时监听 IPv4。" - -msgid "Port Forwards" -msgstr "端口转发" - +#: htdocs/luci-static/resources/view/socat.js:94 msgid "Listen Protocol" msgstr "监听协议" -msgid "Listen port" +#: htdocs/luci-static/resources/view/socat.js:108 +msgid "Listen Port" msgstr "监听端口" -msgid "REUSEADDR" -msgstr "地址重用" +#: htdocs/luci-static/resources/view/socat.js:113 +msgid "Reuse Port" +msgstr "重用端口" -msgid "Bind to a port local" -msgstr "绑定到本地端口" +#: htdocs/luci-static/resources/view/socat.js:113 +msgid "" +"Allow binding to the port even when previous connections are in TIME_WAIT, " +"preventing restart failures." +msgstr "允许在端口处于 TIME_WAIT 状态时立即重新绑定,避免服务重启失败。" +#: htdocs/luci-static/resources/view/socat.js:118 msgid "Destination Protocol" msgstr "目标协议" -msgid "Destination address" +#: htdocs/luci-static/resources/view/socat.js:125 +msgid "Destination Address" msgstr "目标地址" -msgid "Destination port" +#: htdocs/luci-static/resources/view/socat.js:137 +msgid "Destination Port" msgstr "目标端口" -msgid "Open firewall port" +#: htdocs/luci-static/resources/view/socat.js:141 +msgid "Open Firewall Port" msgstr "打开防火墙端口" diff --git a/luci-app-socat/root/etc/config/luci_socat b/luci-app-socat/root/etc/config/luci_socat new file mode 100644 index 00000000..9c4c6d2a --- /dev/null +++ b/luci-app-socat/root/etc/config/luci_socat @@ -0,0 +1,4 @@ + +config global 'global' + option enable '1' + diff --git a/luci-app-socat/root/etc/init.d/luci_socat b/luci-app-socat/root/etc/init.d/luci_socat index 98df330c..64aef77b 100755 --- a/luci-app-socat/root/etc/init.d/luci_socat +++ b/luci-app-socat/root/etc/init.d/luci_socat @@ -1,100 +1,114 @@ #!/bin/sh /etc/rc.common # Copyright (C) 2020 Lienol +# Copyright (C) 2026 sbwml +USE_PROCD=1 START=99 +STOP=10 -CONFIG=socat -CONFIG_PATH=/var/etc/$CONFIG +CONFIG="socat" +CONFIG_PATH="/var/etc/${CONFIG}" -add_rule() { - accept_port=$(cat /var/etc/$CONFIG.port | tr "\n" " ") - if [ "$accept_port" ]; then - uci -q delete firewall.socat - uci set firewall.socat=rule - uci set firewall.socat.name="socat" - uci set firewall.socat.target="ACCEPT" - uci set firewall.socat.src="wan" - uci set firewall.socat.dest_port="$accept_port" - uci set firewall.socat.enabled="1" - uci commit firewall - /etc/init.d/firewall reload >/dev/null 2>&1 - else - del_rule - fi -} +firewall_add_rule() { + local ports="$1" + + [ -z "$ports" ] && return 1 -del_rule() { uci -q delete firewall.socat + uci set firewall.socat=rule + uci set firewall.socat.name="socat" + uci set firewall.socat.target="ACCEPT" + uci set firewall.socat.src="wan" + uci set firewall.socat.dest_port="$ports" + uci set firewall.socat.enabled="1" uci commit firewall /etc/init.d/firewall reload >/dev/null 2>&1 } -run_service() { - config_get enable $1 enable - [ "$enable" = "0" ] && return 0 - config_get remarks $1 remarks - config_get protocol $1 protocol - config_get family $1 family - config_get proto $1 proto - config_get listen_port $1 listen_port - config_get reuseaddr $1 reuseaddr - config_get dest_proto $1 dest_proto - config_get dest_ip $1 dest_ip - config_get dest_port $1 dest_port - config_get firewall_accept $1 firewall_accept - ln -s /usr/bin/socat ${CONFIG_PATH}/$1 - - if [ "$reuseaddr" == "1" ]; then - reuseaddr=",reuseaddr" - else - reuseaddr="" +firewall_del_rule() { + uci -q delete firewall.socat + uci commit firewall 2>/dev/null + /etc/init.d/firewall reload >/dev/null 2>&1 +} + +start_instance() { + local cfg="$1" + local enable remarks protocol family proto listen_port reuseaddr + local dest_proto dest_ip dest_port firewall_accept listen socat_opts + + config_get_bool enable "$cfg" "enable" 0 + [ "$enable" -eq 0 ] && return 0 + + config_get remarks "$cfg" "remarks" "" + config_get protocol "$cfg" "protocol" "" + config_get family "$cfg" "family" "" + config_get proto "$cfg" "proto" "" + config_get listen_port "$cfg" "listen_port" "" + config_get_bool reuseaddr "$cfg" "reuseaddr" 0 + config_get dest_proto "$cfg" "dest_proto" "" + config_get dest_ip "$cfg" "dest_ip" "" + config_get dest_port "$cfg" "dest_port" "" + config_get_bool firewall_accept "$cfg" "firewall_accept" 0 + + if [ -z "$listen_port" ] || [ -z "$dest_ip" ] || [ -z "$dest_port" ]; then + return 1 fi - - if [ "$family" == "6" ]; then - ipv6only_params=",ipv6-v6only" - else - ipv6only_params="" + + ln -sf /usr/bin/socat "${CONFIG_PATH}/${cfg}" + + socat_opts="" + [ "$reuseaddr" -eq 1 ] && socat_opts="${socat_opts},reuseaddr" + [ "$family" = "6" ] && socat_opts="${socat_opts},ipv6-v6only" + socat_opts="${socat_opts},fork" + + if [ "$protocol" = "port_forwards" ]; then + listen="${proto}${family}" + [ -z "$family" ] && listen="${proto}6" + + procd_open_instance "$cfg" + procd_set_param command "${CONFIG_PATH}/${cfg}" + procd_append_param command "${listen}-listen:${listen_port}${socat_opts}" + procd_append_param command "${dest_proto}:${dest_ip}:${dest_port}" + procd_set_param respawn 3600 5 3 + procd_set_param stdout 0 + procd_set_param stderr 0 + procd_close_instance + + if [ "$firewall_accept" -eq 1 ]; then + echo "$listen_port" >> "/var/etc/${CONFIG}.port" + fi fi - - # 端口转发 - if [ "$protocol" == "port_forwards" ]; then - listen=${proto}${family} - [ "$family" == "" ] && listen=${proto}6 - ${CONFIG_PATH}/$1 ${listen}-listen:${listen_port}${ipv6only_params}${reuseaddr},fork ${dest_proto}:${dest_ip}:${dest_port} >/dev/null 2>&1 & +} + +start_service() { + local global_enable accept_ports + + config_load "luci_socat" + config_get_bool global_enable "global" "enable" 0 + + if [ "$global_enable" -eq 0 ]; then + return 0 + fi + + mkdir -p "$CONFIG_PATH" + rm -f "/var/etc/${CONFIG}.port" + + config_foreach start_instance "config" + + accept_ports=$(cat "/var/etc/${CONFIG}.port" 2>/dev/null | tr '\n' ' ') + + if [ -n "$accept_ports" ]; then + firewall_add_rule "$accept_ports" fi - - [ "$firewall_accept" == "1" ] && { - echo $listen_port >> /var/etc/$CONFIG.port - } } stop_service() { - busybox ps -w | grep "$CONFIG_PATH/" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 & - del_rule - rm -rf $CONFIG_PATH /var/etc/$CONFIG.port + firewall_del_rule + rm -rf "$CONFIG_PATH" "/var/etc/${CONFIG}.port" } -start() { - [ -f "/etc/config/socat" ] && [ $(grep -c global /etc/config/socat) -eq 0 ] && { - uci add socat global - uci rename socat.@global[0]='global' - uci set socat.global.enable="$(grep -q "enable '1'" /etc/config/socat && echo '1' || echo '0')" - uci commit socat - } - enable=$(uci -q get $CONFIG.@global[0].enable) - if [ "$enable" = "0" ];then - stop_service - else - mkdir -p $CONFIG_PATH - rm -f /var/etc/$CONFIG.port - config_load $CONFIG - config_foreach run_service "config" - add_rule - fi -} - -stop() { - stop_service +service_triggers() { + procd_add_reload_trigger "luci_socat" } reload_service() { diff --git a/luci-app-socat/root/etc/uci-defaults/luci-app-socat b/luci-app-socat/root/etc/uci-defaults/luci-app-socat deleted file mode 100644 index eec9f584..00000000 --- a/luci-app-socat/root/etc/uci-defaults/luci-app-socat +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -[ ! -f "/usr/share/ucitrack/luci-app-socat.json" ] && { - cat > /usr/share/ucitrack/luci-app-socat.json << EEOF -{ - "config": "socat", - "init": "socat" -} -EEOF -} - -[ -f "/etc/config/ucitrack" ] && { -uci -q batch <<-EOF >/dev/null - delete ucitrack.@socat[-1] - add ucitrack socat - set ucitrack.@socat[-1].init=luci_socat - commit ucitrack -EOF -} - -rm -rf /tmp/luci-*cache* -exit 0 diff --git a/luci-app-socat/root/usr/share/luci/menu.d/luci-app-socat.json b/luci-app-socat/root/usr/share/luci/menu.d/luci-app-socat.json new file mode 100644 index 00000000..c4e53084 --- /dev/null +++ b/luci-app-socat/root/usr/share/luci/menu.d/luci-app-socat.json @@ -0,0 +1,12 @@ +{ + "admin/services/socat": { + "title": "Socat", + "action": { + "type": "view", + "path": "socat" + }, + "depends": { + "acl": [ "luci-app-socat" ] + } + } +} diff --git a/luci-app-socat/root/usr/share/rpcd/acl.d/luci-app-socat.json b/luci-app-socat/root/usr/share/rpcd/acl.d/luci-app-socat.json index a79e14a5..0969c8dd 100644 --- a/luci-app-socat/root/usr/share/rpcd/acl.d/luci-app-socat.json +++ b/luci-app-socat/root/usr/share/rpcd/acl.d/luci-app-socat.json @@ -2,6 +2,9 @@ "luci-app-socat": { "description": "Grant UCI access for luci-app-socat", "read": { + "ubus": { + "service": [ "list" ] + }, "uci": [ "socat" ] }, "write": { diff --git a/luci-app-socat/root/usr/share/ucitrack/luci-app-socat.json b/luci-app-socat/root/usr/share/ucitrack/luci-app-socat.json index c43834e7..d80e815a 100644 --- a/luci-app-socat/root/usr/share/ucitrack/luci-app-socat.json +++ b/luci-app-socat/root/usr/share/ucitrack/luci-app-socat.json @@ -1,4 +1,4 @@ { - "config": "socat", + "config": "luci_socat", "init": "luci_socat" }