🍕 Sync 2024-03-16 00:25

This commit is contained in:
github-actions[bot] 2024-03-16 00:25:25 +08:00
parent 67d0e57449
commit 258f11ed72
45 changed files with 1050 additions and 598 deletions

View File

@ -8,14 +8,14 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=ddns-go PKG_NAME:=ddns-go
KG_VERSION:=6.1.2 KG_VERSION:=6.2.1
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/jeessy2/ddns-go.git PKG_SOURCE_URL:=https://github.com/jeessy2/ddns-go.git
PKG_MIRROR_HASH:=d5868e26981a31e9fb5f772c713e91fe38a7270a9bbf089e641f754bc6b06010 PKG_MIRROR_HASH:=8ec2af48833b5e17ccc21b017121dcbfecdc92e44c730773a248022e03cded79
PKG_SOURCE_VERSION:=52ef2b7fbf854df52a2996d926b869524a003326 PKG_SOURCE_VERSION:=9aee04b58764fc48687b5b3448ac45dc34de1335
PKG_LICENSE:=AGPL-3.0-only PKG_LICENSE:=AGPL-3.0-only
PKG_LICENSE_FILES:=LICENSE PKG_LICENSE_FILES:=LICENSE

View File

@ -7,13 +7,18 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
THEME_NAME:=eqosplus
PKG_NAME:=luci-app-$(THEME_NAME)
PKG_LICENSE:=Apache-2.0
LUCI_TITLE:=LuCI support for eqosplus. LUCI_TITLE:=LuCI support for eqosplus.
LUCI_DESCRIPTION:=LuCI support for Easy eqosplus(Support speed limit based on IP address). LUCI_DESCRIPTION:=LuCI support for Easy eqosplus(Support speed limit based on IP address).
LUCI_DEPENDS:=+bash +tc +kmod-sched-core +kmod-ifb +kmod-sched +iptables-mod-filter +iptables-mod-nat-extra LUCI_DEPENDS:=+bash +tc +kmod-sched-core +kmod-ifb +kmod-sched +iptables-mod-filter +iptables-mod-nat-extra
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
PKG_VERSION:=1.2.2 PKG_VERSION:=1.2.5
PKG_RELEASE:=20230719 PKG_RELEASE:=20231205
PKG_MAINTAINER:=sirpdboy <herboy2008@gmail.com> PKG_MAINTAINER:=sirpdboy <herboy2008@gmail.com>
define Package/$(PKG_NAME)/conffiles define Package/$(PKG_NAME)/conffiles

View File

@ -3,14 +3,17 @@ module("luci.controller.eqosplus", package.seeall)
function index() function index()
if not nixio.fs.access("/etc/config/eqosplus") then return end if not nixio.fs.access("/etc/config/eqosplus") then return end
entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false
entry({"admin", "control", "eqosplus"}, cbi("eqosplus"), _("Eqosplus"), 10).dependent =true
local e = entry({"admin", "control", "eqosplus"}, cbi("eqosplus"), _("Eqosplus"), 10)
e.dependent=false
e.acl_depends = { "luci-app-eqosplus" }
entry({"admin", "control", "eqosplus", "status"}, call("act_status")).leaf = true entry({"admin", "control", "eqosplus", "status"}, call("act_status")).leaf = true
end end
function act_status() function act_status()
local sys = require "luci.sys" local sys = require "luci.sys"
local e = {} local e = {}
e.status = sys.call(" tc qdisc show | grep 'default' >/dev/null ") == 0 e.status = sys.call(" busybox ps -w | grep eqosplus | grep -v grep >/dev/null ") == 0
luci.http.prepare_content("application/json") luci.http.prepare_content("application/json")
luci.http.write_json(e) luci.http.write_json(e)
end end

View File

@ -34,6 +34,9 @@ t.template = "cbi/tblsection"
t.anonymous = true t.anonymous = true
t.addremove = true t.addremove = true
comment = t:option(Value, "comment", translate("Comment"))
comment.size = 8
e = t:option(Flag, "enable", translate("Enabled")) e = t:option(Flag, "enable", translate("Enabled"))
e.rmempty = false e.rmempty = false
e.size = 4 e.size = 4
@ -99,7 +102,5 @@ week:value('1,2,3,4,5',translate("Workday"))
week:value('6,7',translate("Rest Day")) week:value('6,7',translate("Rest Day"))
week.default='0' week.default='0'
week.size = 6 week.size = 6
comment = t:option(Value, "comment", translate("Comment"))
comment.size = 8
return a return a

View File

@ -1 +0,0 @@
zh-cn

View File

@ -0,0 +1,61 @@
msgid "Eqosplus"
msgstr "定时限速"
msgid "Network speed limit"
msgstr "定时网速限制"
msgid "Running state"
msgstr "运行状态"
msgid "Not running"
msgstr "未运行"
msgid "Running"
msgstr "已运行"
msgid "Users can limit the network speed for uploading/downloading through MAC, IP.The speed unit is MB/second."
msgstr "可以通过MACIP限制用户上传/下载的网速。速度单位为<font color=\"red\"><b> MB/秒 </b></font>。"
msgid "MAC/IP"
msgstr "MAC/IP"
msgid "Downloads"
msgstr "下载速度"
msgid "Uploads"
msgstr "上传速度"
msgid "Comment"
msgstr "备注"
msgid "Upload bandwidth(Mbit/s)"
msgstr "上传总带宽(Mbit/s)"
msgid "Download bandwidth(Mbit/s)"
msgstr "下载总带宽(Mbit/s)"
msgid "Start control time"
msgstr "起控时间"
msgid "Stop control time"
msgstr "停控时间"
msgid "Week Day(1~7)"
msgstr "星期(1~7)"
msgid "Suggested feedback:"
msgstr "建议反馈:"
msgid "Set the interface used for restriction, use pppoe-wan for dialing, use WAN hardware interface for DHCP mode (such as eth1), and use br-lan for bypass mode"
msgstr "设定用来限制网络速度的接口,拨号使用pppoe-wan,DHCP模式使用WAN口的硬件接口(如:eth1),通用使用br-lan接口"
msgid "Rest Day"
msgstr "休息日"
msgid "Workday"
msgstr "工作日"
msgid "Automatic settings"
msgstr "自动设置"

View File

@ -7,7 +7,6 @@ config eqosplus
config device config device
option timestart '00:00' option timestart '00:00'
option week '0' option week '0'
option download '1' option download '1'
option timeend '23:55' option timeend '23:55'
@ -19,7 +18,6 @@ config device
option mac '192.168.10.10/24' option mac '192.168.10.10/24'
option timestart '00:00' option timestart '00:00'
option timeend '00:00' option timeend '00:00'
option week '0' option week '0'
option download '0.1' option download '0.1'
option upload '0.1' option upload '0.1'

View File

@ -12,7 +12,7 @@ CR=/etc/crontabs/root
start_instance() { start_instance() {
procd_open_instance procd_open_instance
procd_set_param command /usr/sbin/eqosplusctrl procd_set_param command /usr/bin/eqosplusctrl
procd_set_param respawn procd_set_param respawn
procd_set_param stderr 1 procd_set_param stderr 1
procd_close_instance procd_close_instance

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
chmod +x /etc/init.d/eqosplus /usr/bin/eqosplus chmod +x /etc/init.d/eqosplus /usr/bin/eqosplus*
uci -q batch <<-EOF >/dev/null uci -q batch <<-EOF >/dev/null
delete ucitrack.@eqosplus[-1] delete ucitrack.@eqosplus[-1]
add ucitrack eqosplus add ucitrack eqosplus

View File

@ -10,9 +10,13 @@ IDLIST="/var/$NAME.idlist"
LOCK="/var/lock/$NAME.lock" LOCK="/var/lock/$NAME.lock"
TMPID="/var/$NAME.tmpid" TMPID="/var/$NAME.tmpid"
if [ x$(uci get $NAME.@$NAME[0].ifname) = 'x1' ] ;then if [ x$(uci get $NAME.@$NAME[0].ifname) = 'x1' ] ;then
dev=`ifconfig | grep "Point-to-Point" | cut -d " " -f1` # dev=`ifconfig | grep "Point-to-Point" | cut -d " " -f1`
# [ ! ${dev} ] && dev=` uci -q get network.wan.ifname ` || dev=` uci -q get network.wan.device ` ifname=$(uci -q get network.lan.ifname )
[ "x$ifname" = "x" ] && ifname="device" || ifname="ifname"
[ ! ${dev} ] && dev=` uci -q get network.wan.$ifname `
[ ! ${dev} ] && dev=br-lan [ ! ${dev} ] && dev=br-lan
dev=br-lan
#ALL_DEVICES=$(echo $(ifconfig | grep 'Point-to-Point' | cut -d ' ' -f1) $(uci -q get network.wan.$ifname) $(ports_for_device $(uci -q get network.wan.device)) | tr ' ' '\n' | sort -u)
else else
dev=`uci -q get $NAME.@$NAME[0].ifname ` dev=`uci -q get $NAME.@$NAME[0].ifname `
fi fi
@ -20,32 +24,27 @@ fi
bin_iptables=$(which iptables) bin_iptables=$(which iptables)
bin_ip6tables=$(which ip6tables) bin_ip6tables=$(which ip6tables)
bin_tc=$(which tc) bin_tc=$(which tc)
bin_ebtables=$(which ebtables)
bin_ip=$(which ip) bin_ip=$(which ip)
# Uncomment this to debug commands # Uncomment this to debug commands
DEBUG=1 DEBUG=0
## End ## End
# Debug functions - echo + run # Debug functions - echo + run
dbg_iptables() { dbg_iptables() {
[ "${DEBUG:-0}" -eq 0 ] || echo "D: iptables $@" [ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: iptables $*"
$bin_iptables "$@" $bin_iptables "$*"
} }
dbg_ip6tables() { dbg_ip6tables() {
[ "${DEBUG:-0}" -eq 0 ] || echo "D: ip6tables $@" [ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: ip6tables $*"
$bin_ip6tables "$@" $bin_ip6tables "$*"
} }
dbg_tc() { dbg_tc() {
[ "${DEBUG:-0}" -eq 0 ] || echo "D: tc $@" [ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: tc $*"
$bin_tc "$@" $bin_tc $*
}
dbg_ebtables() {
[ "${DEBUG:-0}" -eq 0 ] || echo "D: ebtables $@"
$bin_ebtables "$@"
} }
dbg_ip() { dbg_ip() {
[ "${DEBUG:-0}" -eq 0 ] || echo "D: ip $@" [ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: ip $*"
$bin_ip "$@" $bin_ip $*
} }
is_macaddr() { is_macaddr() {
ret=1 ret=1
@ -60,17 +59,17 @@ iptables="dbg_iptables"
ip6tables="dbg_ip6tables" ip6tables="dbg_ip6tables"
tc="dbg_tc" tc="dbg_tc"
ip="dbg_ip" ip="dbg_ip"
ebt="dbg_ebtables"
ipt=$iptables ipt=$iptables
ipt6=$ip6tables ipt6=$ip6tables
ipt(){ ipt(){
$iptables $@ $iptables $*
$ip6tables $@ $ip6tables $*
} }
iptm(){ iptm(){
$iptables "-t mangle $@" $iptables "-t mangle $*"
$ip6tables "-t mangle $@" $ip6tables "-t mangle $*"
} }
stop_qos() { stop_qos() {
@ -88,7 +87,7 @@ stop_qos() {
} }
init_qosplus() { init_qosplus() {
insmod sch_htb 2> /dev/null
$ip link add dev ${dev}_ifb name ${dev}_ifb type ifb $ip link add dev ${dev}_ifb name ${dev}_ifb type ifb
$ip link set dev ${dev}_ifb up $ip link set dev ${dev}_ifb up
$tc qdisc add dev ${dev} root handle 1:0 htb default 1 $tc qdisc add dev ${dev} root handle 1:0 htb default 1
@ -106,49 +105,55 @@ init_qosplus() {
} }
del_id() { del_id() {
id=`expr $1 + 11 ` id=`expr $1 + 11 `
[ "${DEBUG:-0}" -eq 0 ] || echo "D: del_id $@" "--$id --$mac" [ "${DEBUG:-0}" -eq 0 ] || echo "D: del_id $@" "--$id --$mac"
$tc qd del dev ${dev} parent 1:$id $tc qd del dev ${dev} parent 1:$id 2>/dev/null
$tc qd del dev ${dev}_ifb parent 1:$id $tc qd del dev ${dev}_ifb parent 1:$id 2>/dev/null
$tc class del dev ${dev} parent 1:1 classid 1:$id $tc class del dev ${dev} parent 1:1 classid 1:$id 2>/dev/null
$tc class del dev ${dev}_ifb parent 1:1 classid 1:$id $tc class del dev ${dev}_ifb parent 1:1 classid 1:$id 2>/dev/null
$tc filter del dev ${dev}_ifb pref $id $tc filter del dev ${dev}_ifb pref $id 2>/dev/null
$tc filter del dev ${dev} pref $id $tc filter del dev ${dev} pref $id 2>/dev/null
$tc filter del dev ${dev}_ifb pref 6 $tc filter del dev ${dev}_ifb pref 6 2>/dev/null
$tc filter del dev ${dev} pref 6 $tc filter del dev ${dev} pref 6 2>/dev/null
$tc filter del dev ${dev}_ifb pref 5 $tc filter del dev ${dev}_ifb pref 5 2>/dev/null
$tc filter del dev ${dev} pref 5 $tc filter del dev ${dev} pref 5 2>/dev/null
} }
### https://openwrt.org/docs/guide-user/network/traffic-shaping/packet.scheduler.example5
filter_mac() {
M=`echo $mac | awk -F '[-:]' '{print $1$2}'`
M0=$(echo $1 | cut -d : -f 1)$(echo $1 | cut -d : -f 2)
M1=$(echo $1 | cut -d : -f 3)$(echo $1 | cut -d : -f 4)
M2=$(echo $1 | cut -d : -f 5)$(echo $1 | cut -d : -f 6)
TCF="${tc} filter add dev $3 parent 1: protocol ip prio 5 u32 match u16 0x0800 0xFFFF at -2"
$TCF match u16 0x${M2} 0xFFFF at -4 match u32 0x${M0}${M1} 0xFFFFFFFF at -8 flowid $2
$TCF match u32 0x${M1}${M2} 0xFFFFFFFF at -12 match u16 0x${M0} 0xFFFF at -14 flowid $2
}
add_mac() { add_mac() {
id=`expr $1 + 11 ` id=`expr $1 + 11 `
A=`echo $mac | awk -F '[-:]' '{print $1$2}'` M0=$(echo $mac | cut -d : -f 1)$(echo $mac | cut -d : -f 2)
B=`echo $mac | awk -F '[-:]' '{print $3$4$5$6}'` M1=$(echo $mac | cut -d : -f 3)$(echo $mac | cut -d : -f 4)
C=`echo $mac | awk -F '[-:]' '{print $1$2$3$4}'` M2=$(echo $mac | cut -d : -f 5)$(echo $mac | cut -d : -f 6)
D=`echo $mac | awk -F '[-:]' '{print $5$6}'` [ "${DEBUG:-0}" -eq 0 ] || echo "D: add_mac $@ --id:$id --mac:$mac M012--$M0-$M1-$M2"
[ "${DEBUG:-0}" -eq 0 ] || echo "D: add_mac $@ --id:$id --mac:$mac ABCD--$A-$B-$C-$D"
if [ "$UL" -gt 0 ]; then if [ "$UL" -gt 0 ]; then
$tc class add dev ${dev}_ifb parent 1:1 classid 1:$id htb rate "$UL"kbit ceil "$UL"kbit prio $id quantum 1500 $tc class add dev ${dev}_ifb parent 1:1 classid 1:$id htb rate "$UL"kbit ceil "$UL"kbit prio $id quantum 1500
$tc qdisc add dev ${dev}_ifb parent 1:"$id" handle "$id": sfq perturb 1 $tc qdisc add dev ${dev}_ifb parent 1:"$id" handle "$id": sfq perturb 1
# $tc filter add dev ${dev}_ifb parent 1:0 protocol ip prio $id u32 match u16 0x0800 0xffff at -2 match u16 0x"$D" 0xffff at -4 match u32 0x"$C" 0xffffffff at -8 flowid 1:$id $tc filter add dev ${dev}_ifb parent 1: protocol ip prio $id u32 match u16 0x0800 0xFFFF at -2 match u16 0x"${M2}" 0xFFFF at -4 match u32 0x"${M0}${M1}" 0xFFFFFFFF at -8 flowid 1:$id
# $tc filter add dev ${dev}_ifb parent 1: protocol ip prio $id u32 match u16 0x0800 0xFFFF at -2 match u32 0x"$C" 0xFFFFFFFF at -12 flowid 1:$id # filter_mac $mac 1:$id ${dev}_ifb
$tc filter add dev ${dev}_ifb parent 1: protocol ip prio 1 u32 match u16 0xAAAA at 6 match u32 0x"$C" 0x"$B" police rate "$UL"kbit burst 10k drop flowid 1:$id
elif [ "$UL" == 0 ]; then elif [ "$UL" == 0 ]; then
$tc filter add dev ${dev}_ifb parent 1:0 protocol ip prio 5 u32 match u16 0x0800 0xffff at -2 match u16 0x"$D" 0xffff at -4 match u32 0x"$C" 0xffffffff at -8 flowid 1:1 $tc filter add dev ${dev}_ifb parent 1: protocol ip prio 5 u32 match u16 0x0800 0xFFFF at -2 match u16 0x"${M2}" 0xFFFF at -4 match u32 0x"${M0}${M1}" 0xFFFFFFFF at -8 flowid 1:1
fi fi
if [ "$DL" -gt 0 ]; then if [ "$DL" -gt 0 ]; then
$tc class add dev ${dev} parent 1:1 classid 1:$id htb rate "$DL"kbit ceil "$DL"kbit prio $id quantum 1500 $tc class add dev ${dev} parent 1:1 classid 1:$id htb rate "$DL"kbit ceil "$DL"kbit prio $id quantum 1500
$tc qdisc add dev ${dev} parent 1:"$id" handle "$id": sfq perturb 1 $tc qdisc add dev ${dev} parent 1:"$id" handle "$id": sfq perturb 1
#$tc filter add dev ${dev} parent 1:0 protocol ip prio $id u32 match u16 0x0800 0xffff at -2 match u32 0x"$B" 0xffffffff at -12 match u16 0x"$A" 0xffff at -14 flowid 1:$id # filter_mac $mac 1:$id ${dev}
# $tc filter add dev ${dev} parent 1: protocol ip prio $id u32 match u16 0x0800 0xFFFF at -2 match u32 0x"$C" 0xFFFFFFFF at -12 flowid 1:$id $tc filter add dev ${dev} parent 1: protocol ip prio $id u32 match u16 0x0800 0xFFFF at -2 match u32 0x${M1}${M2} 0xFFFFFFFF at -12 match u16 0x${M0} 0xFFFF at -14 flowid 1:$id
$tc filter add dev ${dev} parent 1: protocol ip prio 1 u32 match u16 0xAAAA at 6 match u32 0x"$C" 0x"$B" police rate "$DL"kbit burst 10k drop flowid 1:$id
elif [ "$DL" == 0 ]; then elif [ "$DL" == 0 ]; then
$tc filter add dev ${dev} parent 1:0 protocol ip prio 5 u32 match u16 0x0800 0xffff at -2 match u32 0x"$B" 0xffffffff at -12 match u16 0x"$A" 0xffff at -14 flowid 1:1 $tc filter add dev ${dev} parent 1: protocol ip prio 5 u32 match u16 0x0800 0xFFFF at -2 match u32 0x"${M1}${M2}" 0xFFFFFFFF at -12 match u16 0x"${M0}" 0xFFFF at -14 flowid 1:1
fi fi
} }
add_ip() { add_ip() {
id=`expr $1 + 11 ` id=`expr $1 + 11 `
# id=printf "%x\n" "$1" # id=printf "%x\n" "$1"
@ -196,20 +201,19 @@ check_list() {
case "$crrun" in case "$crrun" in
"stop") "stop")
stop_qos stop_qos
echo '' >$IDLIST touch $IDLIST
;; ;;
"start") "start")
idlist=`uci show $NAME | grep "enable='1'" | grep "device" | grep -oE '\[.*?\]' | grep -o '[0-9]' | sed -e 's/^/!/g' -e 's/$/!/g' > $IDLIST ;cat $IDLIST | sed -e 's/!//g' ` idlist=`uci show $NAME | grep "enable='1'" | grep "device" | grep -oE '\[.*?\]' | grep -o '[0-9]' | sed -e 's/^/!/g' -e 's/$/!/g' > $IDLIST ;cat $IDLIST | sed -e 's/!//g' `
# [ $idlist ] || /etc/init.d/eqosplus stop # [ $idlist ] || /etc/init.d/eqosplus stop
cat $IDLIST
init_qosplus init_qosplus
checki='0' checki='0'
for list in `echo $idlist | sed -e 's/!//g' ` ;do for list in `echo $idlist | sed -e 's/!//g' ` ;do
check_list $list check_list $list
if [ $checki == '1' ] ; then if [ $checki == '1' ] ; then
mac=$(uci -q get $NAME.@device[$list].mac ) mac=$(uci -q get $NAME.@device[$list].mac )
DL=$(uci -q get $NAME.@device[$list].download 2>/dev/null | awk '{print $1*10^3/2}') DL=$(uci -q get $NAME.@device[$list].download 2>/dev/null | awk '{print $1*8*10^3}')
UL=$(uci -q get $NAME.@device[$list].upload 2>/dev/null | awk '{print $1*10^3/2}') UL=$(uci -q get $NAME.@device[$list].upload 2>/dev/null | awk '{print $1*8*10^3}')
if is_macaddr $mac; then if is_macaddr $mac; then
add_mac $list add_mac $list
else else
@ -226,8 +230,8 @@ case "$crrun" in
"add") "add")
for list in `echo $crid | sed -e 's/!//g' | sed 's/,/ /g' ` ;do for list in `echo $crid | sed -e 's/!//g' | sed 's/,/ /g' ` ;do
mac=$(uci -q get $NAME.@device[$list].mac ) mac=$(uci -q get $NAME.@device[$list].mac )
DL=$(uci -q get $NAME.@device[$list].download 2>/dev/null | awk '{print $1*10^3/2}') DL=$(uci -q get $NAME.@device[$list].download 2>/dev/null | awk '{print $1*8*10^3}')
UL=$(uci -q get $NAME.@device[$list].upload 2>/dev/null | awk '{print $1*10^3/2}') UL=$(uci -q get $NAME.@device[$list].upload 2>/dev/null | awk '{print $1*8*10^3}')
if is_macaddr $mac; then if is_macaddr $mac; then
add_mac $list add_mac $list
else else
@ -236,7 +240,25 @@ case "$crrun" in
done done
;; ;;
"del") "del")
for list in `echo $crid | sed -e 's/!//g' | sed 's/,/ /g' ` ;do del_id $list; sed -i "/!$list!/d" $IDLIST >/dev/null 2>&1; done for list in `echo $crid | sed -e 's/!//g' | sed 's/,/ /g' ` ;do del_id $list; done
;;
"status")
echo "### Statistics $dev ###"
echo "# qdiscs #"
tc -s qdisc show dev $dev
echo "# class #"
tc -s class show dev $dev
echo "# filter #"
tc -s filter show dev $dev root
tc -s filter show dev $dev parent 1:
echo "### Statistics ${dev}_ifb ###"
echo "# qdiscs #"
tc -s qdisc show dev ${dev}_ifb
echo "# class #"
tc -s class show dev ${dev}_ifb
echo "# filter #"
tc -s filter show dev ${dev}_ifb root
tc -s filter show dev ${dev}_ifb parent 1:
;; ;;
esac esac

View File

@ -0,0 +1,63 @@
#!/bin/sh
# Copyright (C) 2006 OpenWrt.org
# Copyright 2022-2023 sirpdboy <herboy2008@gmail.com>
NAME=eqosplus
IDLIST="/var/$NAME.idlist"
TMPID="/var/$NAME.tmpid"
idlist=`uci show $NAME | grep "enable='1'" | grep "device" | grep -oE '\[.*?\]' | grep -o '[0-9]' `
check_list() {
i=$1
checki='0'
start_time=$(uci -q get $NAME.@device[$i].timestart 2>/dev/null)
end_time=$(uci -q get $NAME.@device[$i].timeend 2>/dev/null)
wweek=`uci -q get $NAME.@device[$i].week `
current_time=$(date +%H:%M)
current_weekday=$(date +%u)
for ww in `echo $wweek | sed 's/,/ /g' `; do
if [ $current_weekday = $ww ] || [ 'x0' = x$ww ] ;then
[ "$start_time" = "$end_time" ] && checki='1' || {
if [ "$start_time" \< "$end_time" ]; then
if [ "$current_time" \> "$start_time" ] && [ "$current_time" \< "$end_time" ] ; then
checki='1'
fi
else
if [ "$start_time" \> "$end_time" ] ; then
if [ "$current_time" \< "$start_time" ] && [ "$current_time" \> "$end_time" ] ; then
checki='1'
fi
fi
fi
}
fi
done
return
}
idlistusr(){
checki='0'
[ -s $IDLIST ] || touch $IDLIST
for list in $idlist ;do
check_list $list
if [ $checki == '1' ] ; then
[ `cat $IDLIST 2>/dev/null | grep "!${list}!" | wc -l ` -gt 0 ] || {
eqosplus add $list
echo "!${list}!" >> $IDLIST ; cat $IDLIST | sort | uniq > $TMPID ;cat $TMPID >$IDLIST ;rm -rf $TMPID
}
else
[ `cat $IDLIST 2>/dev/null | grep "!${list}!" | wc -l ` -gt 0 ] && {
eqosplus del $list
sed -i "/!$list!/d" $IDLIST >/dev/null 2>&1
}
fi
done
}
while :;do
sleep 30
idlistusr
sleep 30
done

View File

@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-netspeedtest PKG_NAME:=luci-app-netspeedtest
PKG_VERSION:=2.2.2 PKG_VERSION:=2.2.3
PKG_RELEASE:=20240311 PKG_RELEASE:=20240315
LUCI_TITLE:=LuCI Support for netspeedtest LUCI_TITLE:=LuCI Support for netspeedtest
LUCI_DEPENDS:=+python3 +iperf3-ssl +homebox LUCI_DEPENDS:=+python3 +iperf3-ssl +homebox

View File

@ -50,28 +50,32 @@ wantest() {
# echone "\n BINTEMP: $BINTEMP " # echone "\n BINTEMP: $BINTEMP "
case $TESTMODE in case $TESTMODE in
0) 0)
echone "\n —————ookla-speedtest测速$TESTMODE—————" echo -ne "\n —————ookla-speedtest测速$TESTMODE—————" >> $LOG
info=$($BINTEMP > $TMP_T ) info=$($BINTEMP > $TMP_T 2>&1 )
#$BINTEMP > $TMP_T RESULT=$(echo "$TMP_T" | grep "URL" | awk '{print $NF}')
echo -ne "\n 测服信息:`cat $TMP_T | grep 'Server'| cut -c10- | awk -F: '{printf $2$3}'` 线路:`cat $TMP_T | grep 'ISP' | awk -F: '{printf $2}' ` 延时:`cat $TMP_T | grep 'Latency' | awk -F: '{printf $2}' | awk -F '(' '{printf $1}'`" >> $LOG if [ -n "$RESULT" ] ;then
echo -ne "\n 下行速率:`cat $TMP_T | grep 'Download' |awk -F: '{printf $2}' | awk -F '(' '{printf $1}'` --" >> $LOG echo -ne "\n 测服信息:`cat $TMP_T | grep 'Server'| cut -c10- | awk -F: '{printf $2$3}'` 线路:`cat $TMP_T | grep 'ISP' | awk -F: '{printf $2}' ` 延时:`cat $TMP_T | grep 'Latency' | awk -F: '{printf $2}' | awk -F '(' '{printf $1}'`" >> $LOG
echo -ne "\n 下行速率:`cat $TMP_T | grep 'Download' |awk -F: '{printf $2}' | awk -F '(' '{printf $1}'` --" >> $LOG
echo -ne "-- 上行速率:`cat $TMP_T | grep 'Upload' |awk -F: '{printf $2}' | awk -F '(' '{printf $1}'`" >> $LOG echo -ne "-- 上行速率:`cat $TMP_T | grep 'Upload' |awk -F: '{printf $2}' | awk -F '(' '{printf $1}'`" >> $LOG
echo -ne "\n 测速结果图片链接:`cat $TMP_T | grep 'URL' | cut -c15-`" >> $LOG echo -ne "\n 测速结果图片链接:`cat $TMP_T | grep 'URL' | cut -c15-`" >> $LOG
echo -ne "\n 测试时间: `date +%Y-%m-%d' '%H:%M:%S`" >> $LOG echo -ne "$RESULT"
echo -ne "\n ————————————————————\n" >> $LOG else
# cat $TMP_T | grep 'URL' | cut -c15- > /var/speedtesturl.tmp echo -ne "\n 因客户端在LUCI状态下无法执行测试失败" >> $LOG
echo -ne "`cat $TMP_T | grep 'URL' | cut -c15- `" echo -ne "\n 请SSH登陆后输入 /etc/init.d/netspeedtest wantest 0 然后等完成后,刷新后查看记录!" >> $LOG
fi
echo -ne "\n 测试时间: `date +%Y-%m-%d' '%H:%M:%S`" >> $LOG
echo -ne "\n ————————————————————\n" >> $LOG
;; ;;
*) *)
echo -ne "\n —————python3-speedtest测速$TESTMODE—————" >> $LOG echo -ne "\n —————python3-speedtest测速$TESTMODE—————" >> $LOG
$BINTEMP > $TMP_T info=$($BINTEMP > $TMP_T 2>&1 )
echo -ne "\n 测服信息:$(cat $TMP_T | grep 'Hosted by'| cut -c10- | awk -F: '{printf $1}') 延时:$(cat $TMP_T | grep 'Hosted by' | awk -F: '{printf $2}')" >> $LOG echo -ne "\n 测服信息:$(cat $TMP_T | grep 'Hosted by'| cut -c10- | awk -F: '{printf $1}') 延时:$(cat $TMP_T | grep 'Hosted by' | awk -F: '{printf $2}')" >> $LOG
echo -ne "\n 下行速率:$(cat $TMP_T | grep 'Download:' |awk -F: '{printf $2}' )" >> $LOG echo -ne "\n 下行速率:$(cat $TMP_T | grep 'Download:' |awk -F: '{printf $2}' )" >> $LOG
echo -ne " ---- 上行速率:$(cat $TMP_T | grep 'Upload:' |awk -F: '{printf $2}' )" >> $LOG echo -ne " ---- 上行速率:$(cat $TMP_T | grep 'Upload:' |awk -F: '{printf $2}' )" >> $LOG
echo -ne "\n 测试结果图片链接:$(cat $TMP_T | grep 'results:' | cut -c16- )" >> $LOG echo -ne "\n 测试结果图片链接:$(cat $TMP_T | grep 'results:' | cut -c16- )" >> $LOG
echo -ne "\n 测试时间:`date +%Y-%m-%d" "%H:%M:%S`" >> $LOG echo -ne "\n 测试时间:`date +%Y-%m-%d" "%H:%M:%S`" >> $LOG
echo -ne "\n ————————————————————\n" >> $LOG echo -ne "\n ————————————————————\n" >> $LOG
echo -ne $(cat $TMP_T | grep 'results:' | cut -c16- ) echo -ne $(cat $TMP_T | grep 'results:' | awk '{print $NF}')
;; ;;
esac esac

View File

@ -0,0 +1,10 @@
#!/bin/sh
chmod +x /etc/init.d/partexp >/dev/null 2>&1
[ `uci -q get partexp.global` ] && uci set partexp.global=global
[ `uci -q get netspeedtest.netspeedtest` ] || uci set netspeedtest.netspeedtest=netspeedtest
[ `uci -q get netspeedtest.speedtestiperf3` ] || uci set netspeedtest.speedtestiperf3=speedtestiperf3
[ `uci -q get netspeedtest.speedtestport` ] || uci set netspeedtest.speedtestport=speedtestport
[ `uci -q get netspeedtest.speedtestwan` ] || uci set netspeedtest.speedtestport=speedtestwan
rm -rf /tmp/luci-modulecache /tmp/luci-indexcache*
exit 0

View File

@ -1,18 +1,24 @@
# Copyright (C) 2016 Openwrt.org #
# Copyright 2019-2024 sirpdboy
# #
# This is free software, licensed under the Apache License, Version 2.0 . # This is free software, licensed under the Apache License, Version 2.0 .
# #
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
NAME:=parentcontrol
PKG_NAME:=luci-app-parentcontrol PKG_NAME:=luci-app-$(NAME)
PKG_VERSION:=1.5 PKG_VERSION:=1.7.1
PKG_RELEASE:=20230115 PKG_RELEASE:=20230909
PKG_LICENSE:=Apache-2.0 PKG_LICENSE:=Apache-2.0
LUCI_TITLE:=LuCI support for Parent Control LUCI_TITLE:=LuCI support for Parent Control
LUCI_DEPENDS:=+iptables-mod-filter +kmod-ipt-filter LUCI_DEPENDS:=+iptables-mod-filter +kmod-ipt-filter
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
define Package/$(PKG_NAME)/conffiles
/etc/config/parentcontrol
endef
include $(TOPDIR)/feeds/luci/luci.mk include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature # call BuildPackage - OpenWrt buildroot signature

View File

@ -3,9 +3,10 @@ module("luci.controller.parentcontrol", package.seeall)
function index() function index()
if not nixio.fs.access("/etc/config/parentcontrol") then return end if not nixio.fs.access("/etc/config/parentcontrol") then return end
entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false
local e=entry({"admin","control","parentcontrol"},firstchild(),_("Parent Control"),2) local e = entry({"admin","control","parentcontrol"},firstchild(),_("Parent Control"),2)
e.dependent=false e.dependent=false
e.acl_depends = { "luci-app-parentcontrol" }
entry({"admin","control","parentcontrol","time"},cbi("parentcontrol/time"),_("Time Control"),1).leaf=true entry({"admin","control","parentcontrol","time"},cbi("parentcontrol/time"),_("Time Control"),1).leaf=true
entry({"admin", "control", "parentcontrol","weburl"}, cbi("parentcontrol/weburl"), _("Weburl Control"), 20).leaf = true entry({"admin", "control", "parentcontrol","weburl"}, cbi("parentcontrol/weburl"), _("Weburl Control"), 20).leaf = true
entry({"admin", "control", "parentcontrol","protocol"}, cbi("parentcontrol/protocol"), _("Protocol Control"), 30).leaf = true entry({"admin", "control", "parentcontrol","protocol"}, cbi("parentcontrol/protocol"), _("Protocol Control"), 30).leaf = true
@ -14,8 +15,7 @@ end
function status() function status()
local e = {} local e = {}
e.status = luci.sys.call("iptables -L FORWARD|grep PARENTCONTROL >/dev/null") == 0 e.status = luci.sys.call("iptables -L FORWARD | grep PARENTCONTROL >/dev/null || iptables -L INPUT | grep PARENTCONTROL >/dev/null || iptables -L OUTPUT | grep PARENTCONTROL >/dev/null") == 0
-- e.status=luci.sys.call("[ `iptables -L FORWARD 2>/dev/null|grep -c '^PARENTCONTROL' 2>/dev/null` -gt 0 ] > /dev/null") == 0
luci.http.prepare_content("application/json") luci.http.prepare_content("application/json")
luci.http.write_json(e) luci.http.write_json(e)
end end

View File

@ -5,11 +5,13 @@ local net = require "luci.model.network".init()
local sys = require "luci.sys" local sys = require "luci.sys"
local a, t, e local a, t, e
a = Map("parentcontrol", translate("Parent Control"), translate("<b><font color=\"green\">利用iptables来管控数据包过滤以禁止符合设定条件的用户连接互联网的工具软件。</font> </b></br>\ a = Map("parentcontrol", translate("Parent Control"), translate("<b><font color=\"green\">利用iptables来管控数据包过滤以禁止符合设定条件的用户连接互联网的工具软件。</font> </b></br>\
MAC机器是否使用指定协议端口IPV4和IPV65000:51005100,5110,5001:5002,440:443</br>MAC就是代表限制所有机器," )) MAC机器是否使用指定协议端口IPV4和IPV65000:51005100,5110,5001:5002,440:443</br>MAC就是代表限制所有机器,1-71,5" ))
a.template = "parentcontrol/index" a.template = "parentcontrol/index"
t = a:section(TypedSection, "basic", translate("")) t = a:section(TypedSection, "basic", translate(""))
t.anonymous = true t.anonymous = true
e = t:option(DummyValue, "parentcontrol_status", translate("当前状态")) e = t:option(DummyValue, "parentcontrol_status", translate("当前状态"))
e.template = "parentcontrol/parentcontrol" e.template = "parentcontrol/parentcontrol"
e.value = translate("Collecting data...") e.value = translate("Collecting data...")
@ -17,33 +19,37 @@ e.value = translate("Collecting data...")
e = t:option(Flag, "enabled", translate("开启")) e = t:option(Flag, "enabled", translate("开启"))
e.rmempty = false e.rmempty = false
e = t:option(ListValue, "algos", translate("过滤力度")) e = t:option(ListValue, "control_mode",translate("管控强度"), translate("普通管控:管控国内网站端口,出国插件的国外端口无法管控!"))
e:value("bm", "一般过滤")
e:value("kmp", "强效过滤")
e.default = "kmp"
e = t:option(ListValue, "control_mode",translate("限制模式"), translate("黑名单模式,列表中的客户端设置将被禁止;白名单模式:仅有列表中的客户端设置允许。"))
e.rmempty = false e.rmempty = false
e:value("white_mode", "白名单") e:value("0", "普通管控")
e:value("black_mode", "黑名单") e.default = "0"
e.default = "black_mode"
t = a:section(TypedSection, "protocol", translate("协议过滤")) t = a:section(TypedSection, "protocol", translate("协议过滤列表"))
t.template = "cbi/tblsection" t.template = "cbi/tblsection"
t.anonymous = true t.anonymous = true
t.addremove = true t.addremove = true
e = t:option(Value, "mac", translate("MAC地址<font color=\"green\">(留空则过滤全部客户端)</font>"))
e = t:option(Value, 'remarks', translate('Remarks'))
e = t:option(Flag, "enable", translate("开启"))
e.rmempty = false
e.default = '1'
e = t:option(Value, "mac", translate("MAC地址<font color=\"green\">(留空为全部客户端)</font>"))
e.placeholder = "ALL" e.placeholder = "ALL"
e.rmempty = true e.rmempty = true
o.net.mac_hints(function(t, a) e:value(t, "%s (%s)" % {t, a}) end) o.net.mac_hints(function(t, a) e:value(t, "%s (%s)" % {t, a}) end)
e = t:option(ListValue, "proto", translate("<font color=\"gray\">端口协议</font>")) e = t:option(ListValue, "proto", translate("<font color=\"gray\">端口协议</font>"))
e.rmempty = false e.rmempty = false
e.default = 'tcp' e.default = 'tcp'
e:value("tcp", translate("TCP")) e:value("tcp", translate("TCP"))
e:value("udp", translate("UDP")) e:value("udp", translate("UDP"))
e:value("icmp", translate("ICMP")) e:value("icmp", translate("ICMP"))
e = t:option(Value, "ports", translate("<font color=\"gray\">源端口</font>")) e = t:option(Value, "ports", translate("<font color=\"gray\">源端口</font>"))
e.rmempty = true e.rmempty = true
e = t:option(Value, "portd", translate("<font color=\"gray\">目的端口</font>")) e = t:option(Value, "portd", translate("<font color=\"gray\">目的端口</font>"))
e:value("",translate("ICMP")) e:value("",translate("ICMP"))
e:value("80", "TCP-HTTP") e:value("80", "TCP-HTTP")
@ -73,18 +79,20 @@ e.rmempty = true
return nil, "时间格式必须为 HH:MM 或者留空" return nil, "时间格式必须为 HH:MM 或者留空"
end end
end end
e = t:option(Value, "timestart", translate("起控时间")) e = t:option(Value, "timestart", translate("起控时间"))
e.placeholder = '00:00' e.placeholder = '00:00'
e.default = '00:00' e.default = '00:00'
e.validate = validate_time e.validate = validate_time
e.rmempty = true e.rmempty = true
e = t:option(Value, "timeend", translate("停控时间")) e = t:option(Value, "timeend", translate("停控时间"))
e.placeholder = '00:00' e.placeholder = '00:00'
e.default = '00:00' e.default = '00:00'
e.validate = validate_time e.validate = validate_time
e.rmempty = true e.rmempty = true
week=t:option(ListValue,"week",translate("Week Day")) week=t:option(Value,"week",translate("Week Day"))
week.rmempty = true week.rmempty = true
week:value('*',translate("Everyday")) week:value('*',translate("Everyday"))
week:value(7,translate("Sunday")) week:value(7,translate("Sunday"))
@ -97,15 +105,6 @@ week:value(6,translate("Saturday"))
week.default='*' week.default='*'
e = t:option(Flag, "enable", translate("开启"))
e.rmempty = false
e.default = '1'
a.apply_on_parse = true
a.on_after_apply = function(self,map)
luci.sys.exec("/etc/init.d/parentcontrol restart")
end
return a return a

View File

@ -5,11 +5,12 @@ local net = require "luci.model.network".init()
local sys = require "luci.sys" local sys = require "luci.sys"
local a, t, e local a, t, e
a = Map("parentcontrol", translate("Parent Control"), translate("<b><font color=\"green\">利用iptables来管控数据包过滤以禁止符合设定条件的用户连接互联网的工具软件。</font> </b></br>\ a = Map("parentcontrol", translate("Parent Control"), translate("<b><font color=\"green\">利用iptables来管控数据包过滤以禁止符合设定条件的用户连接互联网的工具软件。</font> </b></br>\
:MAC地址机器是否联网.IPV4和IPV6</br>MAC就是代表限制所有机器," )) :MAC地址机器是否联网.IPV4和IPV6</br>MAC就是代表限制所有机器,1-71,5" ))
a.template = "parentcontrol/index" a.template = "parentcontrol/index"
t = a:section(TypedSection, "basic", translate("")) t = a:section(TypedSection, "basic", translate(""))
t.anonymous = true t.anonymous = true
e = t:option(DummyValue, "parentcontrol_status", translate("当前状态")) e = t:option(DummyValue, "parentcontrol_status", translate("当前状态"))
e.template = "parentcontrol/parentcontrol" e.template = "parentcontrol/parentcontrol"
e.value = translate("Collecting data...") e.value = translate("Collecting data...")
@ -17,23 +18,25 @@ e.value = translate("Collecting data...")
e = t:option(Flag, "enabled", translate("开启")) e = t:option(Flag, "enabled", translate("开启"))
e.rmempty = false e.rmempty = false
e = t:option(ListValue, "algos", translate("过滤力度")) e = t:option(ListValue, "control_mode",translate("管控强度"), translate("普通管控:管控国内网站,出国插件的国外网站无法管控。强力管控:国内国外都可管控,注意:被管控的机器将无法连接上软路由后台!"))
e:value("bm", "一般过滤")
e:value("kmp", "强效过滤")
e.default = "kmp"
e = t:option(ListValue, "control_mode",translate("限制模式"), translate("黑名单模式,列表中的客户端设置将被禁止;白名单模式:仅有列表中的客户端设置允许。"))
e.rmempty = false e.rmempty = false
e:value("white_mode", "白名单") e:value("0", "普通管控")
e:value("black_mode", "黑名单") e:value("1", "强力管控")
e.default = "black_mode" e.default = "0"
t = a:section(TypedSection, "time", translate("时间限制")) t = a:section(TypedSection, "time", translate("时间限制列表"))
t.template = "cbi/tblsection" t.template = "cbi/tblsection"
t.anonymous = true t.anonymous = true
t.addremove = true t.addremove = true
e = t:option(Value, "mac", translate("<font color=\"green\">MAC地址*</font>")) e = t:option(Value, 'remarks', translate('Remarks'))
e = t:option(Flag, "enable", translate("开启"))
e.rmempty = false
e.default = '1'
e = t:option(Value, "mac", translate("MAC地址<font color=\"green\">(留空为全部客户端)</font>"))
e.rmempty = true e.rmempty = true
o.net.mac_hints(function(t, a) e:value(t, "%s (%s)" % {t, a}) end) o.net.mac_hints(function(t, a) e:value(t, "%s (%s)" % {t, a}) end)
@ -48,18 +51,20 @@ o.net.mac_hints(function(t, a) e:value(t, "%s (%s)" % {t, a}) end)
return nil, "时间格式必须为 HH:MM 或者留空" return nil, "时间格式必须为 HH:MM 或者留空"
end end
end end
e = t:option(Value, "timestart", translate("起控时间")) e = t:option(Value, "timestart", translate("起控时间"))
e.placeholder = '00:00' e.placeholder = '00:00'
e.default = '00:00' e.default = '00:00'
e.validate = validate_time e.validate = validate_time
e.rmempty = true e.rmempty = true
e = t:option(Value, "timeend", translate("停控时间")) e = t:option(Value, "timeend", translate("停控时间"))
e.placeholder = '00:00' e.placeholder = '00:00'
e.default = '00:00' e.default = '00:00'
e.validate = validate_time e.validate = validate_time
e.rmempty = true e.rmempty = true
week=t:option(ListValue,"week",translate("Week Day")) week=t:option(Value,"week",translate("Week Day"))
week.rmempty = true week.rmempty = true
week:value('*',translate("Everyday")) week:value('*',translate("Everyday"))
week:value(7,translate("Sunday")) week:value(7,translate("Sunday"))
@ -71,16 +76,6 @@ week:value(5,translate("Friday"))
week:value(6,translate("Saturday")) week:value(6,translate("Saturday"))
week.default='*' week.default='*'
e = t:option(Flag, "enable", translate("开启"))
e.rmempty = false
e.default = '1'
a.apply_on_parse = true
a.on_after_apply = function(self,map)
luci.sys.exec("/etc/init.d/parentcontrol restart")
end
return a return a

View File

@ -6,12 +6,13 @@ local sys = require "luci.sys"
local a, t, e local a, t, e
a = Map("parentcontrol", translate("Parent Control"), translate("<b><font color=\"green\">利用iptables来管控数据包过滤以禁止符合设定条件的用户连接互联网的工具软件。</font> </b></br>\ a = Map("parentcontrol", translate("Parent Control"), translate("<b><font color=\"green\">利用iptables来管控数据包过滤以禁止符合设定条件的用户连接互联网的工具软件。</font> </b></br>\
/URL,.IPV4和IPV6</br>MAC就是代表控制所有机器," )) /URL,.IPV4和IPV6</br>MAC就是代表限制所有机器,1-71,5" ))
a.template = "parentcontrol/index" a.template = "parentcontrol/index"
t = a:section(TypedSection, "basic", translate("")) t = a:section(TypedSection, "basic", translate(""))
t.anonymous = true t.anonymous = true
e = t:option(DummyValue, "parentcontrol_status", translate("当前状态")) e = t:option(DummyValue, "parentcontrol_status", translate("当前状态"))
e.template = "parentcontrol/parentcontrol" e.template = "parentcontrol/parentcontrol"
e.value = translate("Collecting data...") e.value = translate("Collecting data...")
@ -24,20 +25,26 @@ e:value("bm", "一般过滤")
e:value("kmp", "强效过滤") e:value("kmp", "强效过滤")
e.default = "kmp" e.default = "kmp"
e = t:option(ListValue, "control_mode",translate("限制模式"), translate("黑名单模式,列表中的客户端设置将被禁止;白名单模式:仅有列表中的客户端设置允许。")) e = t:option(ListValue, "control_mode",translate("管控强度"), translate("普通管控:管控国内网站,出国插件的国外网站无法管控"))
e.rmempty = false e.rmempty = false
e:value("white_mode", "白名单") e:value("0", "普通管控")
e:value("black_mode", "黑名单") e.default = "0"
e.default = "black_mode"
t = a:section(TypedSection, "weburl", translate("网址过滤")) t = a:section(TypedSection, "weburl", translate("网址过滤列表"))
t.template = "cbi/tblsection" t.template = "cbi/tblsection"
t.anonymous = true t.anonymous = true
t.addremove = true t.addremove = true
e = t:option(Value, "mac", translate("MAC地址<font color=\"green\">(留空则过滤全部客户端)</font>")) remarks = t:option(Value, 'remarks', translate('Remarks'))
e = t:option(Flag, "enable", translate("开启"))
e.rmempty = false
e.default = '1'
e = t:option(Value, "mac", translate("MAC地址<font color=\"green\">(必指定客户端)</font>"))
e.rmempty = true e.rmempty = true
o.net.mac_hints(function(t, a) e:value(t, "%s (%s)" % {t, a}) end) o.net.mac_hints(function(t, a) e:value(t, "%s (%s)" % {t, a}) end)
e = t:option( Value, "word", translate("关键词/URL<font color=\"green\">(可留空)</font>")) e = t:option( Value, "word", translate("关键词/URL<font color=\"green\">(可留空)</font>"))
e.rmempty = true e.rmempty = true
function validate_time(self, value, section) function validate_time(self, value, section)
@ -51,19 +58,22 @@ e.rmempty = true
return nil, "时间格式必须为 HH:MM 或者留空" return nil, "时间格式必须为 HH:MM 或者留空"
end end
end end
e = t:option(Value, "timestart", translate("起控时间")) e = t:option(Value, "timestart", translate("起控时间"))
e.placeholder = '00:00' e.placeholder = '00:00'
e.default = '00:00' e.default = '00:00'
e.validate = validate_time e.validate = validate_time
e.rmempty = true e.rmempty = true
e = t:option(Value, "timeend", translate("停控时间")) e = t:option(Value, "timeend", translate("停控时间"))
e.placeholder = '00:00' e.placeholder = '00:00'
e.default = '00:00' e.default = '00:00'
e.validate = validate_time e.validate = validate_time
e.rmempty = true e.rmempty = true
week=t:option(ListValue,"week",translate("Week Day")) week=t:option(Value,"week",translate("Week Day"))
week.rmempty = true week.rmempty = false
week.optional = false
week:value('*',translate("Everyday")) week:value('*',translate("Everyday"))
week:value(7,translate("Sunday")) week:value(7,translate("Sunday"))
week:value(1,translate("Monday")) week:value(1,translate("Monday"))
@ -74,16 +84,7 @@ week:value(5,translate("Friday"))
week:value(6,translate("Saturday")) week:value(6,translate("Saturday"))
week.default='*' week.default='*'
e = t:option(Flag, "enable", translate("开启"))
e.rmempty = false
e.default = '1'
a.apply_on_parse = true
a.on_after_apply = function(self,map)
luci.sys.exec("/etc/init.d/parentcontrol restart")
end
return a return a

View File

@ -1 +0,0 @@
zh-cn

View File

@ -0,0 +1,23 @@
msgid "Control"
msgstr "管控"
msgid "Parent Control"
msgstr "家长控制"
msgid "Time Control"
msgstr "时间限制"
msgid "Weburl Control"
msgstr "网址过滤"
msgid "Protocol Control"
msgstr "协议过滤"
msgid "feature Control"
msgstr "配置过滤库"
msgid "Week Day"
msgstr "设定星期"
msgid "Everyday"
msgstr "每天"

View File

@ -1,49 +1,54 @@
config basic config basic
option algos 'kmp' option algos 'kmp'
option control_mode 'black_mode' option control_mode '0'
option enabled '0' option enabled '0'
config weburl
option word 'baidu'
option timestart '00:00'
option timeend '00:00'
option week '*'
option enable '0'
config weburl
option timestart '00:00'
option timeend '00:00'
option word 'youtube'
option week '1,2,3,4,5'
option enable '0'
config protocol
option proto 'tcp'
option timestart '00:00'
option week '*'
option timeend '23:00'
option portd '80'
option enable '0'
config protocol
option proto 'tcp'
option timestart '00:00'
option week '*'
option portd '443'
option timeend '23:00'
option enable '0'
config protocol
option proto 'tcp'
option timestart '00:00'
option timeend '00:00'
option week '1,2,3,4,5'
option enable '0'
config time config time
option timeoff '00:00' option timestart '00:00'
option timeon '00:00' option week '*'
option daysofweek 'Monday Tuesday Wednesday Thursday Friday Saturday Sunday' option timeend '23:59'
option enable '0' option enable '0'
config time
config weburl option timestart '00:00'
option timeon '00:00'
option timeoff '00:00'
option daysofweek 'Monday Tuesday Wednesday Thursday Friday Saturday Sunday'
option keyword 'baidu'
option enable '0' option enable '0'
option week '1,2,3,4,5'
option timeend '23:59'
config weburl
option timeon '00:00'
option timeoff '00:00'
option daysofweek 'Monday Tuesday Wednesday Thursday Friday Saturday Sunday'
option keyword 'www'
option enable '0'
config protocol
option timeon '00:00'
option daysofweek 'Monday Tuesday Wednesday Thursday Friday Saturday Sunday'
option proto 'tcp'
option timeoff '00:00'
option enable '0'
option dport '80'
config protocol
option proto 'tcp'
option timeon '00:00'
option timeoff '00:00'
option daysofweek 'Monday Tuesday Wednesday Thursday Friday Saturday Sunday'
option enable '0'
option dport '443'
config protocol
option proto 'tcp'
option timeon '00:00'
option timeoff '00:00'
option daysofweek 'Monday Tuesday Wednesday Thursday Friday Saturday Sunday'
option enable '0'
option dport '22'

View File

@ -0,0 +1,7 @@
#!/bin/sh
CONFIG=parentcontrol
[ "$ACTION" = ifup ] || exit 0
[ "$(`uci -q get $CONFIG.@basic[0].enabled`)" == 1 ] || exit 0
/etc/init.d/parentcontrol start

View File

@ -1,103 +1,155 @@
#!/bin/sh /etc/rc.common #!/bin/sh /etc/rc.common
# sirpdboy at 2021-2022 , <herboy2008@gmail.com> # sirpdboy at 2021-2023 , <herboy2008@gmail.com>
DIR="$(cd "$(dirname "$0")" && pwd)"
MY_PATH=$DIR/iptables.sh
START=98 START=98
LOCK=/var/lock/parentcontrol CONFIG=parentcontrol
LOG_FILE=/tmp/log/$CONFIG.log
LOCK_DIR=/tmp/lock
LOCK=/tmp/lock/${CONFIG}.lock
ipt=$(command -v iptables-legacy || command -v iptables)
ipt6=$(command -v ip6tables-legacy || command -v ip6tables)
TAG="PARENTCONTROL_TIME"
TAGP="PARENTCONTROL_PROTOCOL"
TAGW="PARENTCONTROL_WEBURL"
FWI="/var/etc/$CONFIG.include"
elog() {
local d="$(date "+%Y-%m-%d %H:%M:%S")"
echo -e "$d: $*" >>$LOG_FILE
}
clean_log() {
[ `cat $LOG_FILE | wc -l ` -gt 500 ] && {
elog "clear log ."
}
}
set_rules() { set_rules() {
mmode=$1 mmode=$1
rulessum=$(grep -c $mmode /etc/config/parentcontrol) case $mmode in
for i in $(seq 0 $((rulessum-1))) time)
do controlmode=`uci -q get $CONFIG.@basic[0].control_mode`
enable=$(uci -q get parentcontrol.@$mmode[$i].enable ) [ "x$controlmode" == 'x1' ] && chain=INPUT || chain=FORWARD
if [ "$enable" == 1 ]; then for ip in "$ipt" "$ipt6" ; do
mac=$(uci -q get parentcontrol.@$mmode[$i].mac ) && MAC="-m mac --mac-source $mac" || MAC="" $ip -N $TAG 2>/dev/null || $i -F $TAG 2>/dev/null
word=$(uci -q get parentcontrol.@$mmode[$i].word ) && STR="-m string --string ${word} --algo ${algos}" || STR="" $ip -C $chain -j $TAG 2>/dev/null || $ip -I $chain -j $TAG 2>/dev/null
proto=$(uci -q get parentcontrol.@$mmode[$i].proto ) || proto="tcp" done
ports=$(uci -q get parentcontrol.@$mmode[$i].ports ) && SPO="--sport ${ports}" || SPO="" ;;
portd=$(uci -q get parentcontrol.@$mmode[$i].portd ) && DPO="--dport ${portd}" || DPO="" protocol)
mMPT=`echo "$sport"|grep ","` && mSPO="-m multiport" || mSPO="" chain=FORWARD
mMPT=`echo "$dport"|grep ","` && mDPO="-m multiport" || mDPO="" for ip in "$ipt" "$ipt6" ; do
[ -z "$sport" -a -z "$dport" ] && PTO="" || PTO="-p ${proto} ${mSPOT} ${SPO} ${mDPO} ${DPO}" $ip -N $TAGP 2>/dev/null || $i -F $TAGP 2>/dev/null
timestart=$(uci get parentcontrol.@$mmode[$i].timestart 2>/dev/null) || timestart="00:00" $ip -C $chain -j $TAGP 2>/dev/null || $ip -I $chain -j $TAGP 2>/dev/null
timeend=$(uci get parentcontrol.@$mmode[$i].timeend 2>/dev/null) || timeend="00:00" done
week=$(uci get parentcontrol.@$mmode[$i].week |sed 's/ /,/g' 2>/dev/null)
[ -z "$timestart" -o -z "$timeend" -o "$timestart" = "$timeend" ] && TIME="" || TIME="--timestart ${timestart} --timestop ${timeend}"
[ -z "$week" -o "$week" = "*" ] && WEEK="" || WEEK="--weekdays ${week}"
[ -n "$TIME" -o -n "$WEEK" ] && WT="-m time --kerneltz ${TIME} ${WEEK}" || WT=""
logger "PARENTCONTROL:WT${WT} PTO${PTO} MAC${MAC} STR${STR} " ;;
if [ -n "$STR" -a "x$word" = "x!" ] ; then weburl)
iptables -I PARENTCONTROL ${WT} ${PTO} ${MAC} -j ${mode_reo} 2>/dev/null chain=OUTPUT
ip6tables -I PARENTCONTROL ${WT} ${PTO} ${MAC} -j ${mode_reo} 2>/dev/null algos=`uci -q get $CONFIG.@basic[0].algos`
logger "PARENTCONTROL1:WT${WT} PTO${PTO} MAC${MAC} STR${STR} ${mode_reo}" for ip in "$ipt" "$ipt6" ; do
elif [ -z "$STR" ] ; then $ip -N $TAGW 2>/dev/null || $i -F $TAGW 2>/dev/null
iptables -A PARENTCONTROL ${WT} ${PTO} ${MAC} -j ${mode_rej} 2>/dev/null $ip -C $chain -j $TAGW 2>/dev/null || $ip -I $chain -j $TAGW 2>/dev/null
ip6tables -A PARENTCONTROL ${WT} ${PTO} ${MAC} -j ${mode_rej} 2>/dev/null done
logger "PARENTCONTROL2:WT${WT} PTO${PTO} MAC${MAC} STR${STR} ${mode_rej}"
fi ;;
if [ $control_mode == "white_mode" -o -n "$STR" ]; then esac
iptables -I PARENTCONTROL ${STR} ${WT} ${MAC} -j ${mode_reo} 2>/dev/null idlist=`uci show $CONFIG | grep "enable='1'" | grep "$mmode" | grep -oE '\[.*?\]' | grep -o '[0-9]'`
ip6tables -I PARENTCONTROL ${STR} ${WT} ${MAC} -j ${mode_reo} 2>/dev/null elog "set_rules:$mmode"
logger "PARENTCONTROL3:WT${WT} PTO${PTO} MAC${MAC} STR${STR} ${mode_reo} " for i in $idlist ;do
elif [ -n "$STR" ] ; then mac=$(uci -q get $CONFIG.@$mmode[$i].mac ) && MAC="-m mac --mac-source $mac" || MAC=""
iptables -I PARENTCONTROL ${STR} ${WT} ${MAC} -j ${mode_rej} 2>/dev/null timestart=$(uci get $CONFIG.@$mmode[$i].timestart 2>/dev/null) || timestart="00:00"
ip6tables -I PARENTCONTROL ${STR} ${WT} ${MAC} -j ${mode_rej} 2>/dev/null timeend=$(uci get $CONFIG.@$mmode[$i].timeend 2>/dev/null) || timeend="00:00"
logger "PARENTCONTROL4:WT${WT} PTO${PTO} MAC${MAC} STR${STR} ${mode_rej}" wweek=$(uci get $CONFIG.@$mmode[$i].week |sed 's/ /,/g' 2>/dev/null)
fi for ww in `echo $wweek | sed 's/,/ /g' `; do
unset STR MAC WT PTO [ "$ww" == "1" ] && local Z1="Mon,"
fi [ "$ww" == "2" ] && local Z2="Tue,"
[ "$ww" == "3" ] && local Z3="Wed,"
[ "$ww" == "4" ] && local Z4="Thu,"
[ "$ww" == "5" ] && local Z5="Fri,"
[ "$ww" == "6" ] && local Z6="Sat,"
[ "$ww" == "7" ] && local Z7="Sun"
done
[ -z "$timestart" -o -z "$timeend" -o "$timestart" = "$timeend" ] && TIME="" || TIME="--timestart ${timestart} --timestop ${timeend}"
[ -z "$wweek" -o "$wweek" = "*" ] && WEEK="" || WEEK="--weekdays $Z1$Z2$Z3$Z4$Z5$Z6$Z7"
[ -n "$TIME" -o -n "$WEEK" ] && WT="-m time --kerneltz ${TIME} ${WEEK}" || WT=""
case $mmode in
time)
for pt in "$ipt" "$ipt6" ; do
$pt -I $TAG ${MAC} ${WT} -j REJECT 2>/dev/null
elog "$mmode:$pt -- ${MAC} -- ${WT} "
done
;;
protocol)
proto=$(uci -q get $CONFIG.@$mmode[$i].proto ) || proto="tcp"
ports=$(uci -q get $CONFIG.@$mmode[$i].ports ) && SPO="--sport ${ports}" || SPO=""
portd=$(uci -q get $CONFIG.@$mmode[$i].portd ) && DPO="--dport ${portd}" || DPO=""
mMPT=`echo "$ports"|grep ","` && mSPO="-m multiport" || mSPO=""
mMPT=`echo "$portd"|grep ","` && mDPO="-m multiport" || mDPO=""
[ -z "$ports" -a -z "$portd" ] && PTO="" || PTO="-p ${proto} ${mSPO} ${SPO} ${mDPO} ${DPO}"
for pt in "$ipt" "$ipt6" ; do
$pt -I $TAGP ${MAC} ${WT} ${PTO} -j REJECT 2>/dev/null
elog "$mmode: $pt -- ${MAC} -- ${WT} -- ${PTO}"
done
;;
weburl)
word=$(uci -q get $CONFIG.@$mmode[$i].word ) && STR="-m string --algo ${algos} --string ${word}" || STR=""
word2=$(uci -q get $CONFIG.@$mmode[$i].word ) && STR2="-m string --algo ${algos} --hex-string ${word2}" || STR2=""
for pt in "$ipt" "$ipt6" ; do
$pt -I $TAGW -p UDP --dport 53 ${MAC} ${WT} ${STR} -j DROP 2>/dev/null
$pt -I $TAGW -p UDP --dport 53 ${MAC} ${WT} ${STR2} -j DROP 2>/dev/null
$pt -I $TAGW -p TCP --dport 853 ${MAC} ${WT} ${STR} -j DROP 2>/dev/null
$pt -I $TAGW -p TCP --dport 853 ${MAC} ${WT} ${STR2} -j DROP 2>/dev/null
elog "$mmode: $pt -- ${MAC} -- ${WT} -- ${STR}"
done
;;
*) ;;
esac
unset STR MAC WT PTO
done done
} }
flush_include() {
echo '#!/bin/sh' >$FWI
}
del_rule() {
for ip in "$ipt" "$ipt6" ; do
for ta in "$TAG" "$TAGW" "$TAGP" ; do
for chain in "PREROUTING" "FORWARD" "OUTPUT" "INPUT" ; do
$ip -D $chain -j $ta 2>/dev/null
elog "delrule: $ip -- $ta -- ${chain} "
done
$ip -F $ta 2>/dev/null
$ip -X $ta 2>/dev/null
done
done
}
start(){ start(){
[ -f $LOCK ] && exit [ -f $LOCK ] && exit 1
iptables -C FORWARD -j PARENTCONTROL 2>/dev/null && stop del_rule
enabled=`uci -q get parentcontrol.@basic[0].enabled ` enabled=`uci -q get $CONFIG.@basic[0].enabled`
[ "p$enabled" == "p1" ] || exit 1 [ "x$enabled" == "x1" ] || exit 1
allsum=`grep -c 'enable .1.' /etc/config/$CONFIG`
Ssum=`grep -c 'enable .1.' /etc/config/parentcontrol` [ "$allsum" -gt 0 ] && {
if [ "$Ssum" -gt 0 ]; then touch $LOCK
touch $LOCK set_rules time
algos=`uci -q get parentcontrol.@basic[0].algos `
iptables -N PARENTCONTROL 2>/dev/null || iptables -F PARENTCONTROL 2>/dev/null
ip6tables -N PARENTCONTROL 2>/dev/null || ip6tables -F PARENTCONTROL 2>/dev/null
iptables -C FORWARD -j PARENTCONTROL 2>/dev/null || iptables -I FORWARD -j PARENTCONTROL 2>/dev/null
ip6tables -C FORWARD -j PARENTCONTROL 2>/dev/null || ip6tables -I FORWARD -j PARENTCONTROL 2>/dev/null
control_mode=`uci -q get parentcontrol.@basic[0].control_mode `
if [ $control_mode == "black_mode" ]; then
mode_rej=REJECT
mode_reo=RETURN
else
mode_rej=RETURN
mode_reo=REJECT
fi
set_rules time
set_rules protocol set_rules protocol
set_rules weburl set_rules weburl
if [ $control_mode == "white_mode" ]; then }
iptables -A PARENTCONTROL -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN 2>/dev/null clean_log
ip6tables -A PARENTCONTROL -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN 2>/dev/null rm -f $LOCK 2>/dev/null
iptables -A PARENTCONTROL -j REJECT 2>/dev/null
ip6tables -A PARENTCONTROL -j REJECT 2>/dev/null
fi
# iptables -C FORWARD -j PARENTCONTROL 2>/dev/null && ip6tables -C FORWARD -j PARENTCONTROL 2>/dev/null
rm -f $LOCK 2>/dev/null
fi
} }
stop(){ stop(){
del_rule
iptables -D FORWARD -j PARENTCONTROL 2>/dev/null rm -f $LOCK 2>/dev/null
ip6tables -D FORWARD -j PARENTCONTROL 2>/dev/null
iptables -F PARENTCONTROL 2>/dev/null
ip6tables -F PARENTCONTROL 2>/dev/null
iptables -X PARENTCONTROL 2>/dev/null
ip6tables -X PARENTCONTROL 2>/dev/null
} }

View File

@ -7,11 +7,11 @@ uci -q batch <<-EOF >/dev/null
commit ucitrack commit ucitrack
EOF EOF
uci delete firewall.parentcontrol uci -q delete firewall.parentcontrol
uci set firewall.parentcontrol=include uci -q set firewall.parentcontrol=include
uci set firewall.parentcontrol.type=script uci -q set firewall.parentcontrol.type=script
uci set firewall.parentcontrol.path=/etc/parentcontrol.include uci -q set firewall.parentcontrol.path=/etc/parentcontrol.include
uci set firewall.parentcontrol.reload=1 uci -q set firewall.parentcontrol.reload=1
uci commit firewall uci commit firewall
rm -f /tmp/luci-indexcache rm -f /tmp/luci-indexcache
exit 0 exit 0

View File

@ -7,8 +7,8 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-partexp PKG_NAME:=luci-app-partexp
PKG_VERSION:=0.1.9 PKG_VERSION:=1.1.0
PKG_RELEASE:=20221201 PKG_RELEASE:=20240314
PKG_LICENSE:=Apache-2.0 PKG_LICENSE:=Apache-2.0
PKG_MAINTAINER:=Sirpdboy <herboy2008@gmail.com> PKG_MAINTAINER:=Sirpdboy <herboy2008@gmail.com>

View File

@ -1,80 +1,49 @@
--[[ --[[
LuCI - Lua Configuration Partition Expansion LuCI - Lua Configuration Partition Expansion
Copyright (C) 2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/luci-app-partexp Copyright (C) 2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/partexp
]]-- ]]--
require "luci.util"
local fs = require "nixio.fs"
local http = require "luci.http"
local uci = require"luci.model.uci".cursor()
local name = 'partexp' local name = 'partexp'
module("luci.controller.partexp", package.seeall) module("luci.controller.partexp", package.seeall)
function index() function index()
entry({"admin","system","partexp"},alias("admin", "system", "partexp", "global"),_("Partition Expansion"), 54) local e = entry({"admin","system","partexp"},alias("admin", "system", "partexp", "global"),_("Partition Expansion"), 54)
-- entry({"admin", "system", "partexp", "global"}, form("partexp/global"), nil).leaf = true e.dependent = false
e.acl_depends = { "luci-app-partexp" }
entry({"admin", "system", "partexp", "global"}, cbi('partexp/global', {hideapplybtn = true, hidesavebtn = true, hideresetbtn = true}), _('Partition Expansion'), 10).leaf = true entry({"admin", "system", "partexp", "global"}, cbi('partexp/global', {hideapplybtn = true, hidesavebtn = true, hideresetbtn = true}), _('Partition Expansion'), 10).leaf = true
entry({"admin", "system", "partexp","partexprun"}, call("partexprun")).leaf = true entry({"admin", "system", "partexp","partexprun"}, call("partexprun"))
entry({"admin", "system", "partexp", "check"}, call("act_check"))
end
function act_check()
http.prepare_content("text/plain; charset=utf-8")
local f=io.open("/etc/partexp/partexp.log", "r+")
local fdp=fs.readfile("/etc/partexp/lucilogpos") or 0
f:seek("set",fdp)
local a=f:read(2048000) or ""
fdp=f:seek()
fs.writefile("/etc/partexp/lucilogpos",tostring(fdp))
f:close()
http.write(a)
end end
function get_log()
local e = {}
e.running = luci.sys.call("busybox ps -w | grep partexp | grep -v grep >/dev/null") == 0
e.log = fs.readfile("/etc/partexp/partexp.log") or ""
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function partexprun() function partexprun()
local uci = luci.model.uci.cursor() local kconfig = http.formvalue('kconfig')
local keep_config = luci.http.formvalue('keep_config') local aformat = http.formvalue('aformat')
local auto_format = luci.http.formvalue('auto_format') local targetf = http.formvalue('targetf')
local target_function = luci.http.formvalue('target_function') local targetd = http.formvalue('targetd')
local target_disk = luci.http.formvalue('target_disk') uci:set(name, 'global', 'target_disk', targetd)
--uci:delete(name, '@global[0]', global) uci:set(name, 'global', 'target_function', targetf)
uci:set(name, '@global[0]', 'target_disk', target_disk) uci:set(name, 'global', 'auto_format', aformat)
uci:set(name, '@global[0]', 'target_function', target_function) uci:set(name, 'global', 'keep_config', kconfig)
uci:set(name, '@global[0]', 'auto_format', auto_format)
uci:set(name, '@global[0]', 'keep_config', keep_config)
uci:commit(name) uci:commit(name)
-- e = nixio.exec("/bin/sh", "-c" ,"/etc/init.d/partexp autopart") fs.writefile("/etc/partexp/lucilogpos","0")
e = luci.sys.exec('/etc/init.d/partexp autopart') http.prepare_content("application/json")
http.write('')
luci.http.prepare_content('application/json') luci.sys.exec("/etc/init.d/partexp autopart > /etc/partexp/partexp.log 2>&1 &")
luci.http.write_json(e)
end
function outexec(cmd)
luci.http.prepare_content("text/plain")
local util = io.popen(cmd)
if util then
while true do
local ln = util:read("*l")
if not ln then break end
luci.http.write(ln)
luci.http.write("\n")
end
util:close()
end
end
function fork_exec(command)
local pid = nixio.fork()
if pid > 0 then
return
elseif pid == 0 then
-- change to root dir
nixio.chdir("/")
-- patch stdin, out, err to /dev/null
local null = nixio.open("/dev/null", "w+")
if null then
nixio.dup(null, nixio.stderr)
nixio.dup(null, nixio.stdout)
nixio.dup(null, nixio.stdin)
if null:fileno() > 2 then
null:close()
end
end
-- replace with target command
nixio.exec("/bin/sh", "-c", command)
end
end end

View File

@ -32,7 +32,7 @@ end
local m,t,e local m,t,e
m = Map("partexp", "<font color='green'>" .. translate("One click partition expansion mounting tool") .."</font>", m = Map("partexp", "<font color='green'>" .. translate("One click partition expansion mounting tool") .."</font>",
translate( "Automatically format and mount the target device partition. If there are multiple partitions, it is recommended to manually delete all partitions before using this tool.<br/>For specific usage, see:") ..translate("<a href=\'https://github.com/sirpdboy/luci-app-partexp.git' target=\'_blank\'>GitHub @sirpdboy</a>") ) translate( "Automatically format and mount the target device partition. If there are multiple partitions, it is recommended to manually delete all partitions before using this tool.<br/>For specific usage, see:") ..translate("<a href=\'https://github.com/sirpdboy/luci-app-partexp.git' target=\'_blank\'>GitHub @sirpdboy:luci-app-partexp</a>") )
t=m:section(TypedSection,"global") t=m:section(TypedSection,"global")
t.anonymous=true t.anonymous=true
@ -40,8 +40,10 @@ t.anonymous=true
e=t:option(ListValue,"target_function", translate("Select function"),translate("Select the function to be performed")) e=t:option(ListValue,"target_function", translate("Select function"),translate("Select the function to be performed"))
e:value("/overlay", translate("Expand application space overlay (/overlay)")) e:value("/overlay", translate("Expand application space overlay (/overlay)"))
-- e:value("/", translate("Use as root filesystem (/)")) -- e:value("/", translate("Use as root filesystem (/)"))
-- e:value("/lnoverlay", translate("Soft chain partition expansion(/overlay)"))
e:value("/opt", translate("Used as Docker data disk (/opt)")) e:value("/opt", translate("Used as Docker data disk (/opt)"))
e:value("/dev", translate("Normal mount and use by device name(/dev/x1)")) e:value("/dev", translate("Normal mount and use by device name(/dev/x1)"))
e.default="/opt"
e=t:option(ListValue,"target_disk", translate("Destination hard disk"),translate("Select the hard disk device to operate")) e=t:option(ListValue,"target_disk", translate("Destination hard disk"),translate("Select the hard disk device to operate"))
for i, d in ipairs(devices) do for i, d in ipairs(devices) do
@ -52,32 +54,18 @@ for i, d in ipairs(devices) do
end end
end end
o=t:option(Flag,"keep_config",translate("Keep configuration")) e=t:option(Flag,"keep_config",translate("Keep configuration"),translate("Tick means to retain the settings"))
o:depends("target_function", "/overlay") e:depends("target_function", "/overlay")
o.default=0 e.default=0
o=t:option(Flag,'auto_format', translate('Format before use')) e=t:option(Flag,'auto_format', translate('Format before use'),translate("Ticking indicates formatting"))
o:depends("target_function", "/opt") e:depends("target_function", "/opt")
o:depends("target_function", "/dev") e:depends("target_function", "/dev")
o.default=0 -- e:depends("target_function", "/lnoverlay")
e.default=0
o=t:option(DummyValue, '', '') e=t:option(Button, "restart", translate("Perform operation"))
o.rawhtml = true e.inputtitle=translate("Click to execute")
o.template ='partexp' e.template ='partexp'
e=t:option(TextValue,"log")
e.rows=15
e.wrap="on"
e.readonly=true
e.cfgvalue=function(t,t)
return fs.readfile("/etc/partexp/partexp.log")or""
end
e.write=function(e,e,e)
end
-- e =t:option(DummyValue, '', '')
-- e.rawhtml = true
-- e.template = 'partexplog'
return m return m

View File

@ -1,6 +1,6 @@
--[[ --[[
LuCI - Lua Configuration Interface LuCI - Lua Configuration Interface
Copyright (C) 2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/luci-app-partexp Copyright (C) 2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/partexp
]]-- ]]--
local fs = require "nixio.fs" local fs = require "nixio.fs"

View File

@ -1,106 +1,128 @@
<%# <%#
Copyright (C) 2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/luci-app-partexp Copyright (C) 2022-2024 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/partexp
-%> -%>
<%
local fs = require "nixio.fs"
%>
<%+cbi/valueheader%> <%+cbi/valueheader%>
<%local fs=require"nixio.fs"%>
<script src="/luci-static/vssr/jquery.min.js"></script> <input type="button" class="btn cbi-button cbi-button-apply" id="apply_run_button" value="<%:Click to execute%>" onclick=" return apply_run(this) "/>
<label class="cbi-value-title"><%= translate("Select the function to be performed") %></label> <div id="logview" style="display:none">
<div class="cbi-value-field"> <input type="checkbox" id="reversetag" value="reverse" onclick=" return reverselog()" style="vertical-align:middle;height: auto;"><%:reverse%></input>
<input class="cbi-button cbi-button-reload" id="go_partexprun" type="button" value="<%= translate("Perform operation") %>"> <textarea id="cbid.logview.1.conf" class="cbi-input-textarea" style="width: 100%;display:block;" data-update="change" rows="20" cols="80" readonly="readonly" > </textarea>
</div> </div>
<fieldset class="cbi-section" style="display:none"> <script type="text/javascript">//<![CDATA[
<legend id="partexprun-legend">
<%:Collecting data...%>
</legend>
<span id="partexprun-output"></span>
</fieldset>
<script type="text/javascript"> const PARTEXP_RUN_URL = '<%=luci.dispatcher.build_url("admin", "system", "partexp","partexprun")%>';
const PARTEXP_RUN_URL = '<%=luci.dispatcher.build_url("admin", "system", "partexp","partexprun")%>'; const PARTEXP_CHECK = '<%=luci.dispatcher.build_url("admin", "system", "partexp","check")%>';
const PARTEXP_URL = '<%=luci.dispatcher.build_url("admin", "system", "partexp","global")%>';
var legend = document.getElementById('partexprun-legend'); var checkbtn = document.getElementById('apply_run_button');
var output = document.getElementById('partexprun-output');
var islogreverse = false;
$(document).ready(function(){ function reverselog(){
// alert("hello"); var lv = document.getElementById('cbid.logview.1.conf');
function go_run() { lv.innerHTML=lv.innerHTML.split('\n').reverse().join('\n')
legend.style.display = 'none'; if (islogreverse){
output.innerHTML ='</p><%:After operation, restart the machine, please wait...%></p>'; islogreverse=false;
setTimeout(() => { window.location = PARTEXP_URL }, 6000); }else{
} islogreverse=true;
}
function go_err() { return
legend.style.display = 'none'; }
output.innerHTML ='</p><%:Please delete the partition or share and try again%></p>'; function apply_run(btn){
setTimeout(() => { window.location = PARTEXP_URL }, 6000);
} var sid='global'
$("#go_partexprun").click(function () { var opt={
if (confirm('<%:Restart the device to take effect. Confirm whether to continue?%>')) base:"cbid.partexp."+sid,
{ get:function(opt){
var id=this.base+'.'+opt;
prefix_array = $("#cbi-partexp .cbi-section-node").attr("id").split("-"); var obj=document.getElementsByName(id)[0] || document.getElementsByClassName(id)[0] || document.getElementById(id)
prefix_array[0] = "cbid"; if (obj){
prefix = prefix_array.join("."); return obj;
output.innerHTML = }else{
'<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> ' + return null;
'<%:Operation in progress, please wait...%>' }
; },
legend.parentNode.style.display = 'block'; getlist:function(opt){
legend.style.display = 'inline'; var id=this.base+'.'+opt;
var target_function = $("[name='" + prefix + ".target_function']").val(); var objs=document.getElementsByName(id) || document.getElementsByClassName(id);
if ($("[name='" + prefix + ".keep_config']").is(":checked")) { var ret=[];
var keep_config = "1"; if (objs){
} else { for (var i=0;i < objs.length;i++){
var keep_config = "0"; ret[i]=objs[i].value;
} }
var target_disk = $("[name='" + prefix + ".target_disk']").val(); }else{
alert("<%:Fatal on get option,please help in debug%>:"+opt);
if ($("[name='" + prefix + ".auto_format']").is(":checked")) { }
var auto_format = "1"; return ret;
} else { },
var auto_format = "0"; query:function(param,src,tval="1",fval="0"){
} var ret="&"+param+"=";
var obj=this.get(src);
if (obj){
var data = { if (obj.type=="checkbox"){
keep_config: keep_config, return ret+(obj.checked==true ? tval:fval);
target_disk: target_disk, }else{
auto_format: auto_format, return ret+encodeURIComponent(obj.value);
target_function: target_function }
} }
return ''
$.ajax({ }
type: "post",
url: PARTEXP_RUN_URL,
dataType: "json",
data: data,
success: function (d) {
if (d == 2) {
legend.style.display = 'none';
output.innerHTML ='</p><%:After operation, restart the machine, please wait...%></p>';
} else {
legend.style.display = 'none';
output.innerHTML ='</p> <%:Operation execution complete%></p>';
}
setTimeout(() => { window.location = PARTEXP_URL }, 5000);
}
});
return false;
} }
});
});
btn.value='<%:Waiting,(executing)...%>';
btn.disabled=true;
var targetf=opt.get("target_function").value;
var targetd=opt.get("target_disk").value;
if (opt.get("auto_format"))
var aformat = opt.get("auto_format").checked ? 1 : 0;
else
var aformat = 0;
if (opt.get("keep_config"))
var kconfig = opt.get("keep_config").checked ? 1 : 0;
else
var kconfig = 0;
console.log(kconfig);
XHR.get('<%=url([[admin]], [[system]], [[partexp]], [[partexprun]])%>',{
targetf: targetf,
kconfig: kconfig,
targetd: targetd,
aformat: aformat
},function(x){});
poll_check();
return
}
function poll_check(){
var tag = document.getElementById('logview');
tag.style.display="block"
XHR.poll(3, '<%=url([[admin]], [[system]], [[partexp]], [[check]])%>', null,
function(x, data) {
var lv = document.getElementById('cbid.logview.1.conf');
if (x.responseText && lv) {
if (x.responseText=="\u0000"){
for(j = 0,len=this.XHR._q.length; j < len; j++) {
if (this.XHR._q[j].url == '<%=url([[admin]], [[system]], [[partexp]], [[check]])%>'){
this.XHR._q.splice(j,1);
checkbtn.disabled = false;
checkbtn.value = '<%:Click to execute%>';
break;
}
}
return
}
if (islogreverse){
lv.innerHTML = x.responseText.split('\n').reverse().join('\n')+lv.innerHTML;
}else{
lv.innerHTML += x.responseText;
}
}
}
);}
//]]>
</script> </script>
<%+cbi/valuefooter%> <%+cbi/valuefooter%>

View File

@ -0,0 +1,16 @@
<%+cbi/valueheader%>
<textarea id="logview.list" class="cbi-input-textarea" style="width: 100%" rows="15" readonly="readonly"></textarea>
<script type="text/javascript">
const LOG_URL = '<%=luci.dispatcher.build_url("admin", "system", "partexp","realtime_log")%>';
XHR.poll(1, LOG_URL, null, (x, d) => {
let logview = document.getElementById("logview.list");
if (!d.running) {
XHR.halt();
}
logview.value = d.log;
logview.scrollTop = logview.scrollHeight;
});
</script>
<%+cbi/valuefooter%>

View File

@ -1,6 +1,6 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Copyright (C) 2022 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-partexp" "Copyright (C) 2022-2024 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-partexp"
"This is free software, licensed under the GNU General Public License v3." "This is free software, licensed under the GNU General Public License v3."
msgid "Partition Expansion" msgid "Partition Expansion"
@ -12,8 +12,8 @@ msgstr "一键分区扩容挂载工具"
msgid "Automatically format and mount the target device partition. If there are multiple partitions, it is recommended to manually delete all partitions before using this tool.<br/>For specific usage, see:" msgid "Automatically format and mount the target device partition. If there are multiple partitions, it is recommended to manually delete all partitions before using this tool.<br/>For specific usage, see:"
msgstr "自动对目标设备分区格式化挂载,如果有多分区建议手动删除所有分区再使用本工具.<br/>使用说明见:" msgstr "自动对目标设备分区格式化挂载,如果有多分区建议手动删除所有分区再使用本工具.<br/>使用说明见:"
msgid "Select the function to be performed" msgid "Waiting,(executing)..."
msgstr "选择需要执行的功能" msgstr "稍等,努力执行中"
msgid "Expand application space overlay (/overlay)" msgid "Expand application space overlay (/overlay)"
msgstr "用于overlay软件空间 (/overlay)" msgstr "用于overlay软件空间 (/overlay)"
@ -27,6 +27,9 @@ msgstr "用作Docker数据盘 (/opt)"
msgid "Normal mount and use by device name(/dev/x1)" msgid "Normal mount and use by device name(/dev/x1)"
msgstr "按设备名普通挂载使用(/dev/x1)" msgstr "按设备名普通挂载使用(/dev/x1)"
msgid "Soft chain partition expansion(/overlay)"
msgstr "分区软链扩容(/overlay)"
msgid "Destination hard disk" msgid "Destination hard disk"
msgstr "目标硬盘" msgstr "目标硬盘"
@ -42,6 +45,9 @@ msgstr "选择需要操作的硬盘设备"
msgid "Select function" msgid "Select function"
msgstr "选择功能" msgstr "选择功能"
msgid "Click to execute"
msgstr "点击执行"
msgid "Perform operation" msgid "Perform operation"
msgstr "执行操作" msgstr "执行操作"

View File

@ -1 +0,0 @@
zh-cn

View File

@ -0,0 +1,76 @@
msgid ""
msgstr ""
"Copyright (C) 2022-2024 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-partexp"
"This is free software, licensed under the GNU General Public License v3."
msgid "Partition Expansion"
msgstr "分区扩容"
msgid "One click partition expansion mounting tool"
msgstr "一键分区扩容挂载工具"
msgid "Automatically format and mount the target device partition. If there are multiple partitions, it is recommended to manually delete all partitions before using this tool.<br/>For specific usage, see:"
msgstr "自动对目标设备分区格式化挂载,如果有多分区建议手动删除所有分区再使用本工具.<br/>使用说明见:"
msgid "Waiting,(executing)..."
msgstr "稍等,努力执行中"
msgid "Expand application space overlay (/overlay)"
msgstr "用于overlay软件空间 (/overlay)"
msgid "Use as root filesystem (/)"
msgstr "用作根文件系统(/"
msgid "Used as Docker data disk (/opt)"
msgstr "用作Docker数据盘 (/opt)"
msgid "Normal mount and use by device name(/dev/x1)"
msgstr "按设备名普通挂载使用(/dev/x1)"
msgid "Soft chain partition expansion(/overlay)"
msgstr "分区软链扩容(/overlay)"
msgid "Destination hard disk"
msgstr "目标硬盘"
msgid "Keep configuration"
msgstr "保留配置"
msgid "Format before use"
msgstr "使用前格式化"
msgid "Select the hard disk device to operate"
msgstr "选择需要操作的硬盘设备"
msgid "Select function"
msgstr "选择功能"
msgid "Click to execute"
msgstr "点击执行"
msgid "Perform operation"
msgstr "执行操作"
msgid "To make the operation effective, the device will restart. Are you sure to execute?"
msgstr "警告:操作一旦确定无法取消,设备将会重启,是否确定执行?"
msgid "Operation in progress, please wait..."
msgstr "操作执行中,请稍候..."
msgid "After operation, restart the machine, please wait..."
msgstr "操作完毕,机器重启,请稍候..."
msgid "Please delete the partition or share and try again"
msgstr "错误,请检查是否有足够空间或是共享使用中。"
msgid "Restart the device to take effect. Confirm whether to continue?"
msgstr "重启设备操作才生效,确定是否继续执行?"
msgid "Operation execution complete"
msgstr "操作执行完毕"
msgid "Ticking indicates formatting"
msgstr "打勾选择表示格式化"
msgid "Tick means to retain the settings"
msgstr "打勾选择表示保留设置"

View File

@ -1,5 +1,5 @@
config global config global 'global'
option target_function '/overlay' option target_function '/overlay'
option target_disk '' option target_disk ''
option keep_config '1' option keep_config '0'
option auto_format '1' option auto_format '0'

View File

@ -1,7 +1,7 @@
#!/bin/sh /etc/rc.common #!/bin/sh /etc/rc.common
# #
# Copyright (C) 2021-2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/luci-app-partexp # Copyright (C) 2021-2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/partexp
# This is free software, licensed under the Apache License, Version 2.0 . # This is free software, licensed under the Apache License, Version 2.0 .
# #
@ -29,18 +29,17 @@ limit_log() {
init_env() { init_env() {
[ -d "$LOGD" ] || mkdir -p $LOGD [ -d "$LOGD" ] || mkdir -p $LOGD
[ ! -f "$LOG" ] && echo "" > $LOG [ ! -f "$LOG" ] && echo " " > $LOG
} }
gen_log()( gen_log()(
[ -s $LOG ] && echo " ---------------------------------------------------------------------- " >> $LOG log "---------------自动分区扩展挂载开始执行------------------ "
log "自动分区扩展挂载开始执行..."
) )
log(){ log(){
echo " $(date +'%Y-%m-%d %H:%M:%S') $*" >> $LOG echo -e " $(date +'%Y-%m-%d %H:%M:%S') $*"
} }
@ -50,6 +49,7 @@ get_config() {
config_get_bool keep_config $1 keep_config 1 config_get_bool keep_config $1 keep_config 1
config_get_bool auto_format $1 auto_format 1 config_get_bool auto_format $1 auto_format 1
} }
nfdisk(){ nfdisk(){
#Start partition #Start partition
fdisk /dev/$a << EOF >/dev/null 2> /dev/null fdisk /dev/$a << EOF >/dev/null 2> /dev/null
@ -63,118 +63,152 @@ EOF
} }
usamba(){
s=$1
s2=$2
[ -e "/etc/config/$s" ] && {
msum=$(grep -c "config sambashare" /etc/config/$s)
for i in $(seq 0 $((msum)))
do
pdev=`uci -q get $s.@sambashare[$i].path `
[ "$pdev" = "$s2" ] && {
uci delete $s.@sambashare[$i]
uci commit $s
log "分区/dev/$b被挂载$MOUNT共享使用删除$s共享成功"
sleep 5
/etc/init.d/$s restart
}
done
}
}
fdiskB(){ fdiskB(){
a=$1 a=$1
b=$2 b=$1$2
log "检测$a是否分区..." log "检测$a是否分区..."
isP=`fdisk -l /dev/$a |grep -v "bytes"|grep "/dev/$a$b" ` isP=`fdisk -l /dev/$a |grep -v "bytes"|grep "/dev/$b" `
sleep 2 sleep 2
isfdisk=0 isfdisk=0
if [ ! "$isP" ];then if [ ! "$isP" ];then
nfdisk nfdisk
sleep 2 sleep 2
isfdisk=1 isfdisk=1
else else
isfdisk=2 isfdisk=2
fi fi
isP=`fdisk -l /dev/$a |grep -v "bytes" | grep "/dev/$a$b"`
isP=`fdisk -l /dev/$a |grep -v "bytes" | grep "/dev/$b"`
if [ "$isP" -a "$isfdisk" = 1 ] ;then if [ "$isP" -a "$isfdisk" = 1 ] ;then
log "分区$a$b建立成功" log "分区$b建立成功"
elif [ "$isP" -a "$isfdisk" = 2 ] ;then elif [ "$isP" -a "$isfdisk" = 2 ] ;then
log "检测目标分区$a$b已存在." log "检测目标分区$b已存在."
else else
log "分区$a$b建立失败没有足够的空间操作失败" log "分区$b建立失败没有足够的空间操作失败"
expquit 1 expquit 1
fi fi
isD=`df -T | grep /dev/$a$b ` sleep 1
[ -e "/etc/config/dockerd" ] && /etc/init.d/dockerd stop >/dev/null 2> /dev/null
block detect > /etc/config/fstab
isD=` block info "/dev/$b" `
if [ "$isD" ];then if [ "$isD" ];then
eval $(block info "/dev/$a$b" | grep -o -e "MOUNT=\S*") MOUNT='';eval $(block info "/dev/$b" | grep -o -e "MOUNT=\S*")
log "检测$a$b是不是被共享..."
sleep 1
if [ "$MOUNT" ] ; then
msum=$(grep -c "config sambashare" /etc/config/samba4)
for i in $(seq 0 $((msum-1)))
do
dev=`uci -q get samba4.@sambashare[$i].device `
[ $? -ne 0 ] && break
[ "$dev" = "$a$b" ] && {
uci delete samba4.@sambashare[$i]
uci commit
/etc/init.d/samba4 restart &
sleep 5
} log "检测/dev/$b是不是被共享..."
done if [ "x$MOUNT" != 'x' ] ; then
block umount /dev/$a$b usamba samba4 $MOUNT
usamba samba $MOUNT
sleep 5 sleep 5
eval $(block info "/dev/$a$b" | grep -o -e "MOUNT=\S*") umount $MOUNT || block umount /dev/$b
if [ "$MOUNT" ] ;then sleep 5
log "分区$a$b被挂载$MOUNT共享使用删除共享失败请手动删除共享再重新操作" MOUNT='';eval $(block info "/dev/$b" | grep -o -e "MOUNT=\S*")
if [ "x$MOUNT" != 'x' ] ;then
log "分区/dev/$b挂载$MOUNT使用中,自动删除失败!请手动删除共享或者取消其它插件的占用权限再重试!"
expquit 1 expquit 1
else
log "分区$a$b被挂载$MOUNT共享使用自动删除共享成功"
fi fi
else else
log "检测目标硬盘$a$b未被共享..." log "检测目标设备$b未被共享..."
fi fi
fi fi
isD=`df -T | grep /dev/$a$b | awk '{print $2}'` #isD=`block info /dev/$b | awk -F 'TYPE=' '{print $2}'| sed 's,\",,g' `
TYPE='';eval $(block info "/dev/$b" | grep -o -e "TYPE=\S*")
if [ "$target_function" = "/" -o "$target_function" = "/overlay" ] ; then if [ "$target_function" = "/" -o "$target_function" = "/overlay" ] ; then
mkfs.ext4 -L extroot /dev/$a$b >/dev/null 2> /dev/null mkfs.ext4 -L extroot /dev/$b >/dev/null 2> /dev/null
log "硬盘/dev/$a$b格式化成功" log "设备/dev/$b格式化成功"
elif [ "$auto_format" = "1" -o "$isfdisk" = "1" - ! "$isD" ] ; then elif [ "$auto_format" = "1" -o "$isfdisk" = "1" ] ; then
mkfs.ext4 -F /dev/$a$b >/dev/null 2> /dev/null mkfs.ext4 -F /dev/$b >/dev/null 2> /dev/null
log "硬盘/dev/$a$b格式化成功" log "设备/dev/$b格式化成功"
elif [ "$TYPE" ];then
log "设备/dev/$b无需格式化"
else else
log "硬盘/dev/$a$b无需格式化" log "设备/dev/$b未格式化无法正常使用"
expquit 1
fi fi
eval $(block info /dev/$a$b | grep -o -e "UUID=\S*")
if [ "$UUID" = "" ] ; then [ -d "/mnt/$b" ] || mkdir -p /mnt/$b
log "获取/dev/$a$b分区信息失败" MOUNT='';eval $(block info "/dev/$b" | grep -o -e "MOUNT=\S*")
expquit 1 if [ "x$MOUNT" != 'x' ] ;then
else umount /mnt/$b || block umount /dev/$b
log "成功获取/dev/$a$b分区信息" MOUNT='';eval $(block info "/dev/$b" | grep -o -e "MOUNT=\S*")
fi
[ -d "/mnt/$a$b" ] || mkdir -p /mnt/$a$b
isM=`block info /dev/$a$b`
isD=`df -T | grep /dev/$a$b | awk '{print $2}'`
if [ "$isM" -a "$isD" ] ;then
umount /mnt/$a$b
eval $(block info "/dev/$a$b" | grep -o -e "MOUNT=\S*")
if [ "$MOUNT" ] ; then if [ "$MOUNT" ] ; then
log "检测设备/dev/$a$b挂载$MOUNT请取消读写权限再重试!" log "检测设备/dev/$b被占用,请检查设备硬件或中止其他插件等占用权限再重试!"
expquit 1 expquit 1
else
[ "$isD" == "ntfs" ] && mount -t ntfs-3g /dev/$a$b /mnt/$a$b || mount -o rw,noatime,discard /dev/$a$b /mnt/$a$b
fi fi
fi fi
log "检测设备/dev/$a$b分区是$isD格式" TYPE='';eval $(block info "/dev/$b" | grep -o -e "TYPE=\S*")
log "检测设备/dev/$b分区是$TYPE格式"
if [ "$TYPE" = "ntfs" ];then
if [ `which ntfs-3g ` ] ;then
mount -t ntfs-3g /dev/$b /mnt/$b >/dev/null 2> /dev/null
elif [ `which ntfs3 ` ] ;then
mount -t ntfs3 /dev/$b /mnt/$b >/dev/null 2> /dev/null
else
log "不支持NTFS分区挂载请安装ntfs-3g或者ntfs3支持服务"
expquit 1
fi
else
mount /dev/$b /mnt/$b >/dev/null 2> /dev/null
fi
UUID='';eval $(block info /dev/$b | grep -o -e "UUID=\S*")
if [ ! "$UUID" ] ; then
log "获取/dev/$b设备UUID信息失败"
expquit 1
else
log "获取/dev/$b设备UUID信息:$UUID成功"
fi
if [ "$target_function" = "/" ] ; then if [ "$target_function" = "/" ] ; then
mkdir -p /tmp/introot mkdir -p /tmp/introot
mount --bind / /tmp/introot mount --bind / /tmp/introot
tar -C /tmp/introot -cvf - . | tar -C /mnt/$a$b -xf - tar -C /tmp/introot -cvf - . | tar -C /mnt/$b -xf -
umount /tmp/introot umount /tmp/introot || block umount /tmp/introot
umount /mnt/$a$b umount /mnt/$b || block umount /dev/$b
block detect > /etc/config/fstab block detect > /etc/config/fstab
log "保留数据根目录扩展/dev/$a$b成功" OVERLAY=`uci -q get fstab.@mount[0].target `
uci set fstab.@global[0].delay_root="15" if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}" uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/' uci -q set fstab.@mount[0].target='/'
uci -q set fstab.@mount[0].enabled='1' uci -q set fstab.@mount[0].enabled='1'
uci commit fstab fi
log "保留数据根目录扩展/dev/$b成功"
seelp 5
log "设备重启才能生效"
expquit 2 expquit 2
elif [ "$target_function" = "/overlay" ] ; then elif [ "$target_function" = "/overlay" ] ; then
if [ "$keep_config" = "1" ] ; then if [ "$keep_config" = "1" ] ; then
# cp -a -f /overlay/* /mnt/$a$b/ || cp -a -f /rom/overlay/* /mnt/$a$b/ # cp -a -f /overlay/* /mnt/$b/ || cp -a -f /rom/overlay/* /mnt/$b/
tar -C /overlay -cvf - . | tar -C /mnt/$a$b/ -xf - || tar -C /rom/overlay -cvf - . | tar -C /mnt/$a$b/ -xf - tar -C /overlay -cvf - . | tar -C /mnt/$b/ -xf - || tar -C /rom/overlay -cvf - . | tar -C /mnt/$b/ -xf -
umount /mnt/$a$b umount /mnt/$b || block umount /dev/$b
block detect > /etc/config/fstab block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/overlay'
uci -q set fstab.@mount[0].enabled='0'
fi
msum=$(grep -c "'mount'" /etc/config/fstab) msum=$(grep -c "'mount'" /etc/config/fstab)
for i in $(seq 0 $((msum-1))) for i in $(seq 0 $((msum-1)))
do do
@ -187,16 +221,21 @@ fdiskB(){
done done
uci set fstab.@global[0].delay_root="15" uci set fstab.@global[0].delay_root="15"
uci commit fstab uci commit fstab
log "保留数据overlay扩展/dev/$a$b成功" log "保留数据overlay扩展/dev/$b成功"
log "设备重启才能生效,重启中..." seelp 5
log "设备重启才能生效"
expquit 2 expquit 2
else else
umount /mnt/$a$b umount /mnt/$b || block umount /dev/$b
block detect > /etc/config/fstab block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/overlay'
uci -q set fstab.@mount[0].enabled='0'
fi
msum=$(grep -c "'mount'" /etc/config/fstab) msum=$(grep -c "'mount'" /etc/config/fstab)
for i in $(seq 0 $((msum-1))) for i in $(seq 0 $((msum-1)))
do do
@ -209,12 +248,36 @@ fdiskB(){
done done
uci set fstab.@global[0].delay_root="15" uci set fstab.@global[0].delay_root="15"
uci commit fstab uci commit fstab
log "不保留数据overlay扩展/dev/$a$b成功" log "不保留数据overlay扩展/dev/$b成功"
log "设备重启才能生效,重启中..."
seelp 5
log "设备重启才能生效"
expquit 2 expquit 2
fi fi
elif [ "$target_function" = "/lnoverlay" ] ; then
umount /mnt/$b || block umount /dev/$b
block detect > /etc/config/fstab
mkdir -p $target_function
msum=$(grep -c "'mount'" /etc/config/fstab)
for i in $(seq 0 $((msum-1)))
do
zuuid=`uci -q get fstab.@mount[$i].uuid `
[ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then
uci -q set fstab.@mount[$i].target="/mnt/$b"
uci -q set fstab.@mount[$i].enabled='1'
fi
done
uci commit fstab
ln -sf /mnt/$b /overlay
log "设备/dev/$b挂载/mnt/$b软链到/overlay扩容成功"
log "设备重启才能生效"
expquit 2
else else
umount /mnt/$b || block umount /dev/$b
block detect > /etc/config/fstab block detect > /etc/config/fstab
mkdir -p $target_function mkdir -p $target_function
msum=$(grep -c "'mount'" /etc/config/fstab) msum=$(grep -c "'mount'" /etc/config/fstab)
@ -224,14 +287,14 @@ fdiskB(){
[ $? -ne 0 ] && break [ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then if [ "$zuuid" = "$UUID" ] ; then
[ "$target_function" = "/opt" ] && uci -q set fstab.@mount[$i].target="$target_function" || uci -q set fstab.@mount[$i].target="/mnt/$a$b" [ "$target_function" = "/opt" ] && uci -q set fstab.@mount[$i].target="$target_function" || uci -q set fstab.@mount[$i].target="/mnt/$b"
uci -q set fstab.@mount[$i].enabled='1' uci -q set fstab.@mount[$i].enabled='1'
fi fi
done done
uci commit fstab uci commit fstab
[ "$target_function" = "/opt" ] && log "挂载/dev/$a$b到$target_function成功" || log "挂载/dev/$a$b到/mnt/$a$b成功" [ "$target_function" = "/opt" ] && log "挂载/dev/$b到$target_function成功" || log "挂载/dev/$b到/mnt/$b成功"
log "设备重启才能生效,重启中..." log "设备重启才能生效"
expquit 2 expquit 2
fi fi
@ -242,24 +305,29 @@ autopart() {
config_load partexp config_load partexp
config_foreach get_config global config_foreach get_config global
init_env init_env
limit_log $LOG 500
# touch $LOCK # touch $LOCK
cat $LOG 2>/dev/null | sed -n '$p' | grep -q '自动分区扩展挂载开始执行...' || gen_log gen_log
log "此次执行操作功能:$target_function ,目标盘:/dev/$target_disk"
isB=`df -P|grep '/boot' | head -n1 | awk -F ' ' '{print $1}'`
isb=`fdisk -l | grep /dev/$target_disk | grep -v "bytes" | wc -l`
if [ "$isb" = 0 -o "$isb" = "" -o "$isb" = 1 ] ;then
isb=1
elif [ "$isb" = 3 -o "$isb" = 4 ] ;then
isb=3
fi
isP=`fdisk -l /dev/$target_disk |grep "Disk /dev/$target_disk"` isP=`fdisk -l /dev/$target_disk |grep "Disk /dev/$target_disk"`
if [ "$isP" = "" ];then if [ "$isP" = "" ];then
log "没有检测到/dev/$target_disk目标硬盘!操作失败!" log "没有检测到/dev/$target_disk目标设备操作失败"
expquit 1 expquit 1
else else
log "检测到操作目标硬盘:/dev/$target_disk$isb!" isB="$(sed -n -e "\|\s/boot\s.*$|{s///p;q}" /etc/mtab)"
isb=`fdisk -l | grep /dev/$target_disk | grep -v "bytes" | wc -l`
if [ "$isb" = 0 -o "$isb" = 1 ] ;then
isb=1
log "检测到设备/dev/$target_disk分区数为$isb个"
elif [ "$isb" = 3 -o "$isb" = 4 ] ;then
isb=3
log "检测到设备/dev/$target_disk分区数为$isb个"
else
log "检测到设备/dev/$target_disk分区数$isb个,请备份数据后删除分区重新操作!"
expquit 1
fi
log "检测到操作目标设备:/dev/$target_disk$isb!"
case "$target_disk" in case "$target_disk" in
sd*) sd*)
[ "$isB" = "/dev/${target_disk}1" -a "$target_function" = "/overlay" ] && fdiskB $target_disk 3 || fdiskB $target_disk $isb [ "$isB" = "/dev/${target_disk}1" -a "$target_function" = "/overlay" ] && fdiskB $target_disk 3 || fdiskB $target_disk $isb
@ -271,17 +339,16 @@ autopart() {
[ "$isB" = "/dev/${target_disk}p1" -a "$target_function" = "/overlay" ] && fdiskB $target_disk p3 || fdiskB $target_disk p$isb [ "$isB" = "/dev/${target_disk}p1" -a "$target_function" = "/overlay" ] && fdiskB $target_disk p3 || fdiskB $target_disk p$isb
;; ;;
*) *)
log "未能识别/dev/$target_disk目标硬盘请联系作者sirpdboy" log "目标设备/dev/$target_disk暂不支持请联系作者sirpdboy"
expquit 1 expquit 1
;; ;;
esac esac
fi fi
# rm -f $LOCK rm -f $LOCK
} }
start() { start() {
init_env
[ x$x = x1 ] && exit || autopart [ x$x = x1 ] && exit || autopart
} }
@ -292,7 +359,8 @@ x=1
expquit() { expquit() {
rm -f $LOCK rm -f $LOCK
echo $1 [ -e "/etc/config/dockerd" ] && /etc/init.d/dockerd restart >/dev/null 2> /dev/null
[ $1 == 2 ] &&reboot sleep 5
[ $1 == 2 ] && log "重启中...\n" &&reboot
exit $1 exit $1
} }

View File

@ -0,0 +1 @@
1043

View File

@ -0,0 +1 @@
1

View File

@ -1,5 +1,11 @@
#!/bin/sh #!/bin/sh
chmod +x /etc/init.d/partexp >/dev/null 2>&1 chmod +x /etc/init.d/partexp >/dev/null 2>&1
[ `uci -q get partexp.global` ] || uci set partexp.global=global
LOGD=/etc/partexp
LOG=$LOGD/partexp.log
LOGPOS=$LOGD/lucilogpos
[ -d "$LOGD" ] || mkdir -p $LOGD
[ ! -f "$LOG" ] && echo "start" > $LOG
[ ! -f "$LOGPOS" ] && echo 'start' > $LOGPOS
rm -rf /tmp/luci-modulecache /tmp/luci-indexcache* rm -rf /tmp/luci-modulecache /tmp/luci-indexcache*
exit 0 exit 0

View File

@ -1,11 +1,12 @@
# #
# provides Web UI to shut down (power off) your device. # provides Web UI to shut down (power off) your device.
# routers are listed at https://github.com/sirpdboy/luci-app-poweroffdevice # Copyright (C) 2022-2023 sirpdboy <herboy2008@gmail.com>
# This is free software, licensed under the GNU General Public License v3. # This is free software, licensed under the GNU General Public License v3.
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-poweroffdevice NAME:=poweroffdevice
PKG_NAME:=luci-app-$(NAME)
LUCI_TITLE:=LuCI support for poweroffdevice Router LUCI_TITLE:=LuCI support for poweroffdevice Router
LUCI_DESCRIPTION:=provides Web UI to shut down (power off) your device. LUCI_DESCRIPTION:=provides Web UI to shut down (power off) your device.

View File

@ -3,7 +3,9 @@ module("luci.controller.poweroffdevice", package.seeall)
function index() function index()
entry({"admin","system","poweroffdevice"},template("poweroffdevice/poweroffdevice"), _("PowerOff"), 92) local e = entry({"admin","system","poweroffdevice"},template("poweroffdevice/poweroffdevice"), _("PowerOff"), 92)
e.dependent=false
e.acl_depends = { "luci-app-poweroffdevice" }
entry({"admin","system","poweroffdevice","call"},post("action_poweroff")) entry({"admin","system","poweroffdevice","call"},post("action_poweroff"))
end end

View File

@ -1 +0,0 @@
zh-cn

View File

@ -0,0 +1,31 @@
#
# provides Web UI to shut down (power off) your device.
# routers are listed at https://github.com/sirpdboy/luci-app-poweroffdevice
# This is free software, licensed under the GNU General Public License v3.
msgid "PowerOff"
msgstr "关机"
msgid "Power Off Device"
msgstr "设备关机"
msgid "Perform Power Off"
msgstr "执行关机"
msgid "Turn off the power to the device you are using"
msgstr "关闭您正在使用的设备的电源"
msgid "WARNING: Power off might result in a reboot on a device which not support power off."
msgstr "警告:对于不支持关机的设备,关机可能会导致重新启动."
msgid "Device unreachable"
msgstr "操作设备无效"
msgid "Shutting Down..."
msgstr "正在关机..."
msgid "Device shutdown complete!"
msgstr "设备关机完毕!"

View File

@ -0,0 +1,11 @@
{
"luci-app-poweroffdevice": {
"description": "Grant UCI access for luci-app-poweroffdevice",
"read": {
"uci": [ "poweroffdevice" ]
},
"write": {
"uci": [ "poweroffdevice" ]
}
}
}

View File

@ -6,13 +6,13 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=smartdns PKG_NAME:=smartdns
PKG_VERSION:=1.2023.42 PKG_VERSION:=1.2024.45
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://www.github.com/pymumu/smartdns.git PKG_SOURCE_URL:=https://www.github.com/pymumu/smartdns.git
PKG_SOURCE_VERSION:=ed102cda03c56e9c63040d33d4a391b56491493e PKG_SOURCE_VERSION:=9ee27e7ba2d9789b7e007410e76c06a957f85e98
PKG_MIRROR_HASH:=366e98b92c3d22844ff5fc52c35f65c3b01e1b92fc9dc14c474823f0cc3ed11a PKG_MIRROR_HASH:=f32a27081f11020dc76d07099dbe184bd875589a90ccfe88124a7ce094300d76
PKG_MAINTAINER:=Nick Peng <pymumu@gmail.com> PKG_MAINTAINER:=Nick Peng <pymumu@gmail.com>
PKG_LICENSE:=GPL-3.0-or-later PKG_LICENSE:=GPL-3.0-or-later
@ -51,11 +51,14 @@ endef
define Package/smartdns/install define Package/smartdns/install
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/smartdns $(1)/etc/smartdns/domain-set $(1)/etc/smartdns/conf.d/ $(INSTALL_DIR) $(1)/etc/smartdns $(1)/etc/smartdns/domain-set $(1)/etc/smartdns/conf.d/
$(INSTALL_DIR) $(1)/etc/smartdns/ip-set $(1)/etc/smartdns/download
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/smartdns $(1)/usr/sbin/smartdns $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/smartdns $(1)/usr/sbin/smartdns
$(INSTALL_BIN) $(PKG_BUILD_DIR)/package/openwrt/files/etc/init.d/smartdns $(1)/etc/init.d/smartdns $(INSTALL_BIN) $(PKG_BUILD_DIR)/package/openwrt/files/etc/init.d/smartdns $(1)/etc/init.d/smartdns
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/address.conf $(1)/etc/smartdns/address.conf $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/address.conf $(1)/etc/smartdns/address.conf
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/blacklist-ip.conf $(1)/etc/smartdns/blacklist-ip.conf $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/blacklist-ip.conf $(1)/etc/smartdns/blacklist-ip.conf
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/custom.conf $(1)/etc/smartdns/custom.conf $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/custom.conf $(1)/etc/smartdns/custom.conf
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/domain-block.list $(1)/etc/smartdns/domain-block.list
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/domain-forwarding.list $(1)/etc/smartdns/domain-forwarding.list
$(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/files/etc/config/smartdns $(1)/etc/config/smartdns $(INSTALL_CONF) $(PKG_BUILD_DIR)/package/openwrt/files/etc/config/smartdns $(1)/etc/config/smartdns
endef endef