mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-10 18:34:18 +08:00
🏅 Sync 2026-08-07 03:28:35
This commit is contained in:
+2
-2
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=7z
|
||||
PKG_VERSION:=26.01
|
||||
PKG_RELEASE:=2
|
||||
PKG_VERSION:=26.02
|
||||
PKG_RELEASE:=3
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)$(subst .,,$(PKG_VERSION))-src.tar.xz
|
||||
PKG_SOURCE_URL:=https://7-zip.org/a/
|
||||
|
||||
+2
-2
@@ -10,8 +10,8 @@ include $(TOPDIR)/rules.mk
|
||||
PKG_ARCH_BAIDUDRIVE:=$(ARCH)
|
||||
|
||||
PKG_NAME:=baidudrive
|
||||
PKG_VERSION:=linkease-runtime-v1.7.5
|
||||
PKG_RELEASE:=6
|
||||
PKG_VERSION:=linkeasefull-runtime-v3.0.5
|
||||
PKG_RELEASE:=7
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/istoreos/istoreos-app-hub/releases/download/baidudrive-runtime-v$(PKG_VERSION)/
|
||||
PKG_HASH:=skip
|
||||
|
||||
+2
-2
@@ -2,9 +2,9 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gecoosac
|
||||
PKG_VERSION:=2.2.20251015
|
||||
PKG_RELEASE:=14
|
||||
PKG_RELEASE:=15
|
||||
|
||||
PKG_MAINTAINER:=lwb1978 <lwb1978@gmail.com>
|
||||
PKG_MAINTAINER:=Roc Lai <laipeng668@qq.com>
|
||||
PKG_LICENSE:=AGPL-3.0-only
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
config gecoosac 'config'
|
||||
option config_compat '2'
|
||||
option enabled '0'
|
||||
option port '60650'
|
||||
option isonlyoneprot '1'
|
||||
|
||||
@@ -101,6 +101,49 @@ is_path_in_dir() {
|
||||
[ "${path#"$root"/}" != "$path" ]
|
||||
}
|
||||
|
||||
is_secure_dir() {
|
||||
local allow_sticky="$2" owner permissions metadata
|
||||
|
||||
[ -d "$1" ] && [ ! -L "$1" ] || return 1
|
||||
metadata="$(ls -ldn "$1" 2>/dev/null)" || return 1
|
||||
set -- $metadata
|
||||
permissions="$1"
|
||||
owner="$3"
|
||||
[ "$owner" = "0" ] || return 1
|
||||
case "$permissions" in
|
||||
d?????????) ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
|
||||
if [ "$(printf '%s' "$permissions" | cut -c6)" = "w" ] || \
|
||||
[ "$(printf '%s' "$permissions" | cut -c9)" = "w" ]; then
|
||||
[ "$allow_sticky" = "1" ] && [ "$(printf '%s' "$permissions" | cut -c10)" = "t" ] || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_secure_upload_dir() {
|
||||
local path current part rest
|
||||
|
||||
path="$(normalize_path "$1")" || return 1
|
||||
[ -d "$path" ] && [ ! -L "$path" ] || return 1
|
||||
current="/"
|
||||
rest="${path#/}"
|
||||
|
||||
while [ -n "$rest" ]; do
|
||||
part="${rest%%/*}"
|
||||
if [ "$part" = "$rest" ]; then
|
||||
rest=""
|
||||
else
|
||||
rest="${rest#*/}"
|
||||
fi
|
||||
current="${current%/}/$part"
|
||||
case "$current" in
|
||||
/tmp) is_secure_dir "$current" 1 || return 1 ;;
|
||||
*) is_secure_dir "$current" || return 1 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
is_safe_db_dir() {
|
||||
local path upload_root
|
||||
|
||||
@@ -154,7 +197,6 @@ run_with_timeout() {
|
||||
kill "$pid" >/dev/null 2>&1
|
||||
sleep 1
|
||||
kill -9 "$pid" >/dev/null 2>&1
|
||||
wait "$pid" 2>/dev/null
|
||||
return 1
|
||||
fi
|
||||
sleep 1
|
||||
@@ -164,6 +206,42 @@ run_with_timeout() {
|
||||
wait "$pid"
|
||||
}
|
||||
|
||||
run_with_timeout_output() {
|
||||
local timeout output pid i
|
||||
|
||||
timeout="$1"
|
||||
output="$2"
|
||||
shift 2
|
||||
|
||||
"$@" >"$output" 2>/dev/null &
|
||||
pid="$!"
|
||||
i=0
|
||||
|
||||
while kill -0 "$pid" >/dev/null 2>&1; do
|
||||
if [ "$i" -ge "$timeout" ]; then
|
||||
kill "$pid" >/dev/null 2>&1
|
||||
kill -9 "$pid" >/dev/null 2>&1
|
||||
return 1
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
wait "$pid"
|
||||
}
|
||||
|
||||
is_readable_regular_file() {
|
||||
local path="$1" tmp_dir status
|
||||
|
||||
tmp_dir="$(mktemp -d /tmp/gecoosac-file.XXXXXX)" || return 1
|
||||
run_with_timeout_output "$CERT_TIMEOUT" "$tmp_dir/check" \
|
||||
/bin/sh -c '[ -f "$1" ] && [ -r "$1" ] && [ -s "$1" ]' \
|
||||
gecoosac-file-check "$path" </dev/null
|
||||
status="$?"
|
||||
rm -rf "$tmp_dir"
|
||||
return "$status"
|
||||
}
|
||||
|
||||
is_ipv4() {
|
||||
local value="$1"
|
||||
local part count
|
||||
@@ -194,13 +272,19 @@ san_has_entry() {
|
||||
}
|
||||
|
||||
cert_matches_san() {
|
||||
local cert_file="$1"
|
||||
local cert_host="$2"
|
||||
local cert_ip="$3"
|
||||
local san
|
||||
local cert_file="$1" cert_host="$2" cert_ip="$3"
|
||||
local san tmp_dir
|
||||
|
||||
[ -s "$cert_file" ] || return 1
|
||||
san="$(openssl x509 -in "$cert_file" -noout -ext subjectAltName 2>/dev/null)" || return 1
|
||||
is_readable_regular_file "$cert_file" || return 1
|
||||
tmp_dir="$(mktemp -d /tmp/gecoosac-cert.XXXXXX)" || return 1
|
||||
if ! run_with_timeout_output "$CERT_TIMEOUT" "$tmp_dir/san" \
|
||||
openssl x509 -in "$cert_file" -noout -ext subjectAltName </dev/null; then
|
||||
rm -rf "$tmp_dir"
|
||||
return 1
|
||||
fi
|
||||
san="$(cat "$tmp_dir/san" 2>/dev/null)"
|
||||
rm -rf "$tmp_dir"
|
||||
[ -n "$san" ] || return 1
|
||||
san_has_entry "$san" "DNS:${cert_host}" || return 1
|
||||
[ -z "$cert_ip" ] || san_has_entry "$san" "IP Address:${cert_ip}" || return 1
|
||||
|
||||
@@ -208,13 +292,22 @@ cert_matches_san() {
|
||||
}
|
||||
|
||||
cert_matches_key() {
|
||||
local cert_file="$1"
|
||||
local key_file="$2"
|
||||
local cert_pub key_pub
|
||||
local cert_file="$1" key_file="$2"
|
||||
local cert_pub key_pub tmp_dir
|
||||
|
||||
[ -s "$cert_file" ] && [ -s "$key_file" ] || return 1
|
||||
cert_pub="$(openssl x509 -in "$cert_file" -noout -pubkey 2>/dev/null)" || return 1
|
||||
key_pub="$(openssl pkey -in "$key_file" -pubout 2>/dev/null)" || return 1
|
||||
is_readable_regular_file "$cert_file" || return 1
|
||||
is_readable_regular_file "$key_file" || return 1
|
||||
tmp_dir="$(mktemp -d /tmp/gecoosac-cert.XXXXXX)" || return 1
|
||||
if ! run_with_timeout_output "$CERT_TIMEOUT" "$tmp_dir/cert.pub" \
|
||||
openssl x509 -in "$cert_file" -noout -pubkey </dev/null || \
|
||||
! run_with_timeout_output "$CERT_TIMEOUT" "$tmp_dir/key.pub" \
|
||||
openssl pkey -in "$key_file" -pubout </dev/null; then
|
||||
rm -rf "$tmp_dir"
|
||||
return 1
|
||||
fi
|
||||
cert_pub="$(cat "$tmp_dir/cert.pub" 2>/dev/null)"
|
||||
key_pub="$(cat "$tmp_dir/key.pub" 2>/dev/null)"
|
||||
rm -rf "$tmp_dir"
|
||||
|
||||
[ -n "$cert_pub" ] && [ "$cert_pub" = "$key_pub" ]
|
||||
}
|
||||
@@ -235,7 +328,7 @@ generate_default_cert() {
|
||||
cert_ip="$(uci -q get network.lan.ipaddr)"
|
||||
is_ipv4 "$cert_ip" || cert_ip=""
|
||||
|
||||
if [ -s "$DEFAULT_KEY_FILE" ] && cert_matches_san "$DEFAULT_CRT_FILE" "$cert_host" "$cert_ip" && cert_matches_key "$DEFAULT_CRT_FILE" "$DEFAULT_KEY_FILE"; then
|
||||
if is_readable_regular_file "$DEFAULT_KEY_FILE" && cert_matches_san "$DEFAULT_CRT_FILE" "$cert_host" "$cert_ip" && cert_matches_key "$DEFAULT_CRT_FILE" "$DEFAULT_KEY_FILE"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -262,7 +355,7 @@ generate_default_cert() {
|
||||
-addext "basicConstraints=critical,CA:FALSE" \
|
||||
-addext "keyUsage=digitalSignature" \
|
||||
-addext "extendedKeyUsage=serverAuth" \
|
||||
-addext "subjectAltName=$cert_san"
|
||||
-addext "subjectAltName=$cert_san" </dev/null
|
||||
|
||||
if [ -s "$tmp_crt" ] && [ -s "$tmp_key" ] && cert_matches_san "$tmp_crt" "$cert_host" "$cert_ip" && cert_matches_key "$tmp_crt" "$tmp_key"; then
|
||||
mv "$tmp_key" "$DEFAULT_KEY_FILE"
|
||||
@@ -281,22 +374,37 @@ normalize_conf() {
|
||||
if is_safe_upload_dir "$upload_dir"; then
|
||||
upload_dir="$(normalize_path "$upload_dir")"
|
||||
else
|
||||
upload_dir="$DEFAULT_UPLOAD_DIR"
|
||||
logger -t gecoosac "refusing unsupported upload directory: $upload_dir"
|
||||
return 1
|
||||
fi
|
||||
if is_safe_db_dir "$db_dir" "$upload_dir"; then
|
||||
db_dir="$(normalize_path "$db_dir")"
|
||||
else
|
||||
db_dir="$DEFAULT_DB_DIR"
|
||||
logger -t gecoosac "refusing unsupported database directory: $db_dir"
|
||||
return 1
|
||||
fi
|
||||
is_abs_path "$crt_file" || crt_file="$DEFAULT_CRT_FILE"
|
||||
is_abs_path "$key_file" || key_file="$DEFAULT_KEY_FILE"
|
||||
is_abs_path "$crt_file" || {
|
||||
logger -t gecoosac "refusing non-absolute certificate path: $crt_file"
|
||||
return 1
|
||||
}
|
||||
is_abs_path "$key_file" || {
|
||||
logger -t gecoosac "refusing non-absolute key path: $key_file"
|
||||
return 1
|
||||
}
|
||||
if is_safe_pid_dir "$piddir" "$upload_dir"; then
|
||||
piddir="$(normalize_path "$piddir")"
|
||||
else
|
||||
piddir="$DEFAULT_PID_DIR"
|
||||
logger -t gecoosac "refusing unsupported PID directory: $piddir"
|
||||
return 1
|
||||
fi
|
||||
is_port "$port" || port="60650"
|
||||
is_port "$m_port" || m_port="8080"
|
||||
is_port "$port" || {
|
||||
logger -t gecoosac "refusing invalid interface port: $port"
|
||||
return 1
|
||||
}
|
||||
is_port "$m_port" || {
|
||||
logger -t gecoosac "refusing invalid management port: $m_port"
|
||||
return 1
|
||||
}
|
||||
|
||||
[ "$enabled" = "1" ] || enabled="0"
|
||||
[ "$isonlyoneprot" = "0" ] || isonlyoneprot="1"
|
||||
@@ -311,50 +419,79 @@ normalize_conf() {
|
||||
}
|
||||
|
||||
ensure_dirs() {
|
||||
if ! mkdir -p "$upload_dir" "$db_dir" "$piddir" /etc/gecoosac/tls; then
|
||||
local path
|
||||
|
||||
path="$(normalize_path "$upload_dir")" || return 1
|
||||
if ! ensure_dir_tree "$path" || ! mkdir -p "$db_dir" "$piddir" /etc/gecoosac/tls; then
|
||||
logger -t gecoosac "failed to create runtime directories"
|
||||
return 1
|
||||
fi
|
||||
chmod go-w "$path" || return 1
|
||||
is_secure_upload_dir "$path" || {
|
||||
logger -t gecoosac "upload directory or its parent is not root-owned and private: $path"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
ensure_dir_tree() {
|
||||
local path current part rest
|
||||
|
||||
path="$(normalize_path "$1")" || return 1
|
||||
current="/"
|
||||
rest="${path#/}"
|
||||
while [ -n "$rest" ]; do
|
||||
part="${rest%%/*}"
|
||||
if [ "$part" = "$rest" ]; then
|
||||
rest=""
|
||||
else
|
||||
rest="${rest#*/}"
|
||||
fi
|
||||
current="${current%/}/$part"
|
||||
[ ! -L "$current" ] || return 1
|
||||
if [ -e "$current" ]; then
|
||||
[ -d "$current" ] || return 1
|
||||
else
|
||||
mkdir "$current" || return 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
prepare_service() {
|
||||
init_conf
|
||||
[ "$enabled" = "1" ] || return 0
|
||||
normalize_conf || return 1
|
||||
if [ ! -x "$PROG" ]; then
|
||||
logger -t gecoosac "program not found: $PROG"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$isonlyoneprot" = "0" ] && [ "$port" -eq "$m_port" ] 2>/dev/null; then
|
||||
logger -t gecoosac "interface port and management port must be different"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ensure_dirs || return 1
|
||||
if [ "$isonlyoneprot" = "0" ] && [ "$https" = "1" ]; then
|
||||
if [ "$crt_file" = "$DEFAULT_CRT_FILE" ] && [ "$key_file" = "$DEFAULT_KEY_FILE" ]; then
|
||||
generate_default_cert || return 1
|
||||
fi
|
||||
|
||||
if ! cert_matches_key "$crt_file" "$key_file"; then
|
||||
logger -t gecoosac "HTTPS certificate and key do not match or cannot be read"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local runtime_upload_dir runtime_db_dir runtime_piddir
|
||||
|
||||
init_conf
|
||||
normalize_conf
|
||||
|
||||
prepare_service || return 1
|
||||
[ "$enabled" = "1" ] || return 0
|
||||
if [ ! -x "$PROG" ]; then
|
||||
logger -t gecoosac "program not found: $PROG"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$isonlyoneprot" = "0" ] && [ "$port" = "$m_port" ]; then
|
||||
logger -t gecoosac "interface port and management port must be different"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ensure_dirs || return 1
|
||||
runtime_upload_dir="${upload_dir%/}/"
|
||||
runtime_db_dir="${db_dir%/}/"
|
||||
runtime_piddir="${piddir%/}/"
|
||||
|
||||
if [ "$isonlyoneprot" = "0" ] && [ "$https" = "1" ]; then
|
||||
if [ "$crt_file" = "$DEFAULT_CRT_FILE" ] && [ "$key_file" = "$DEFAULT_KEY_FILE" ]; then
|
||||
generate_default_cert || return 1
|
||||
fi
|
||||
|
||||
if [ ! -r "$crt_file" ] || [ ! -r "$key_file" ]; then
|
||||
logger -t gecoosac "HTTPS is enabled but certificate or key file is missing"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! cert_matches_key "$crt_file" "$key_file"; then
|
||||
logger -t gecoosac "HTTPS certificate and key do not match"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
procd_open_instance gecoosac
|
||||
procd_set_param command "$PROG"
|
||||
procd_append_param command -f "$runtime_upload_dir"
|
||||
@@ -387,8 +524,28 @@ start_service() {
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
wait_service_stopped() {
|
||||
local i
|
||||
|
||||
if ! type service_running >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
i=0
|
||||
while [ "$i" -lt 5 ]; do
|
||||
service_running gecoosac || return 0
|
||||
sleep 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
prepare_service || return 1
|
||||
if ! stop || ! wait_service_stopped; then
|
||||
logger -t gecoosac "unable to stop the existing service for reload"
|
||||
return 1
|
||||
fi
|
||||
start
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ DEFAULT_KEY_FILE=/etc/gecoosac/tls/gecoosac.key
|
||||
DEFAULT_PID_DIR=/var/run
|
||||
OLD_CRT_FILE=/etc/gecoosac/tls/1.crt
|
||||
OLD_KEY_FILE=/etc/gecoosac/tls/1.key
|
||||
CONFIG_COMPAT=2
|
||||
|
||||
ensure_section() {
|
||||
uci -q get gecoosac.config >/dev/null && return 0
|
||||
@@ -128,7 +129,7 @@ normalize_upload_dir() {
|
||||
if is_safe_upload_dir "$upload_dir"; then
|
||||
normalized="$(normalize_path "$upload_dir")"
|
||||
else
|
||||
normalized="$DEFAULT_UPLOAD_DIR"
|
||||
return 0
|
||||
fi
|
||||
|
||||
[ "$upload_dir" = "$normalized" ] && return 0
|
||||
@@ -138,7 +139,6 @@ normalize_upload_dir() {
|
||||
|
||||
normalize_dir_option() {
|
||||
local option="$1"
|
||||
local default="$2"
|
||||
local validator="$3"
|
||||
local value normalized upload_dir
|
||||
|
||||
@@ -150,7 +150,7 @@ normalize_dir_option() {
|
||||
if "$validator" "$value" "$upload_dir"; then
|
||||
normalized="$(normalize_path "$value")"
|
||||
else
|
||||
normalized="$default"
|
||||
return 0
|
||||
fi
|
||||
|
||||
[ "$value" = "$normalized" ] && return 0
|
||||
@@ -159,30 +159,71 @@ normalize_dir_option() {
|
||||
}
|
||||
|
||||
migrate_legacy_cert_paths() {
|
||||
local crt_file key_file
|
||||
local migrate
|
||||
local crt_file key_file migrate
|
||||
|
||||
crt_file="$(uci -q get gecoosac.config.crt_file)"
|
||||
key_file="$(uci -q get gecoosac.config.key_file)"
|
||||
migrate=0
|
||||
|
||||
if [ "$crt_file" = "$OLD_CRT_FILE" ]; then
|
||||
if [ -z "$key_file" ] || [ "$key_file" = "$OLD_KEY_FILE" ]; then
|
||||
migrate=1
|
||||
fi
|
||||
if [ "$crt_file" = "$OLD_CRT_FILE" ] && [ -z "$key_file" ]; then
|
||||
uci -q set "gecoosac.config.key_file=${OLD_KEY_FILE}" || return 1
|
||||
key_file="$OLD_KEY_FILE"
|
||||
changed=1
|
||||
elif [ -z "$crt_file" ] && [ "$key_file" = "$OLD_KEY_FILE" ]; then
|
||||
uci -q set "gecoosac.config.crt_file=${OLD_CRT_FILE}" || return 1
|
||||
crt_file="$OLD_CRT_FILE"
|
||||
changed=1
|
||||
fi
|
||||
|
||||
if [ "$crt_file" = "$OLD_CRT_FILE" ] && [ "$key_file" = "$OLD_KEY_FILE" ]; then
|
||||
migrate=1
|
||||
elif [ -z "$crt_file" ] && [ -z "$key_file" ]; then
|
||||
[ -f "$OLD_CRT_FILE" ] && [ -f "$OLD_KEY_FILE" ] || return 0
|
||||
migrate=1
|
||||
fi
|
||||
|
||||
if [ "$migrate" = "1" ]; then
|
||||
uci -q set "gecoosac.config.crt_file=${DEFAULT_CRT_FILE}"
|
||||
uci -q set "gecoosac.config.key_file=${DEFAULT_KEY_FILE}"
|
||||
changed=1
|
||||
[ "$migrate" = "1" ] || return 0
|
||||
[ -f "$OLD_CRT_FILE" ] && [ ! -L "$OLD_CRT_FILE" ] || return 0
|
||||
[ -f "$OLD_KEY_FILE" ] && [ ! -L "$OLD_KEY_FILE" ] || return 0
|
||||
[ ! -e "$DEFAULT_CRT_FILE" ] && [ ! -L "$DEFAULT_CRT_FILE" ] || return 0
|
||||
[ ! -e "$DEFAULT_KEY_FILE" ] && [ ! -L "$DEFAULT_KEY_FILE" ] || return 0
|
||||
|
||||
mkdir -p /etc/gecoosac/tls || {
|
||||
logger -t gecoosac "unable to prepare TLS directory for legacy certificate migration"
|
||||
return 1
|
||||
}
|
||||
if ! mv "$OLD_CRT_FILE" "$DEFAULT_CRT_FILE"; then
|
||||
logger -t gecoosac "unable to migrate legacy certificate"
|
||||
return 1
|
||||
fi
|
||||
if ! mv "$OLD_KEY_FILE" "$DEFAULT_KEY_FILE"; then
|
||||
mv "$DEFAULT_CRT_FILE" "$OLD_CRT_FILE" 2>/dev/null
|
||||
logger -t gecoosac "unable to migrate legacy private key"
|
||||
return 1
|
||||
fi
|
||||
if ! chmod 644 "$DEFAULT_CRT_FILE" || ! chmod 600 "$DEFAULT_KEY_FILE" || \
|
||||
! uci -q set "gecoosac.config.crt_file=${DEFAULT_CRT_FILE}" || \
|
||||
! uci -q set "gecoosac.config.key_file=${DEFAULT_KEY_FILE}"; then
|
||||
mv "$DEFAULT_KEY_FILE" "$OLD_KEY_FILE" 2>/dev/null
|
||||
mv "$DEFAULT_CRT_FILE" "$OLD_CRT_FILE" 2>/dev/null
|
||||
logger -t gecoosac "unable to complete legacy certificate migration"
|
||||
return 1
|
||||
fi
|
||||
changed=1
|
||||
}
|
||||
|
||||
migrate_config() {
|
||||
local compat
|
||||
|
||||
compat="$(uci -q get gecoosac.config.config_compat)"
|
||||
[ "$compat" = "$CONFIG_COMPAT" ] && return 0
|
||||
migrate_legacy_cert_paths || return 1
|
||||
uci -q set "gecoosac.config.config_compat=${CONFIG_COMPAT}" || return 1
|
||||
changed=1
|
||||
}
|
||||
|
||||
ensure_section
|
||||
migrate_legacy_cert_paths
|
||||
migrate_config || exit 1
|
||||
normalize_upload_dir
|
||||
normalize_dir_option db_dir "$DEFAULT_DB_DIR" is_safe_db_dir
|
||||
normalize_dir_option piddir "$DEFAULT_PID_DIR" is_safe_pid_dir
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=hysteria
|
||||
PKG_VERSION:=2.11.0
|
||||
PKG_RELEASE:=13
|
||||
PKG_VERSION:=2.12.0
|
||||
PKG_RELEASE:=14
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/apernet/hysteria/tar.gz/app/v$(PKG_VERSION)?
|
||||
|
||||
@@ -10,9 +10,9 @@ include $(TOPDIR)/rules.mk
|
||||
PKG_ARCH_LINKEASE:=$(ARCH)
|
||||
|
||||
PKG_NAME:=linkease-common-bin
|
||||
PKG_VERSION:=linkease-runtime-v1.7.5
|
||||
PKG_SOURCE_DATE:=$(PKG_VERSION)
|
||||
PKG_RELEASE:=2
|
||||
# use PKG_SOURCE_DATE instead of PKG_VERSION for compitable
|
||||
PKG_SOURCE_DATE:=1.7.5
|
||||
PKG_RELEASE:=3
|
||||
|
||||
ARCH_HEXCODE:=
|
||||
ifeq ($(ARCH),x86_64)
|
||||
@@ -28,7 +28,7 @@ else ifeq ($(ARCH),mipsel)
|
||||
ARCH_HEXCODE=1b0c
|
||||
endif
|
||||
|
||||
PKG_SOURCE_VERSION:=f6d705f77dade7d57c1bb24334da4028279689b9
|
||||
PKG_SOURCE_VERSION:=8895348606dc6cab9b25a75576e5142f553dfa82
|
||||
PKG_SOURCE:=linkease-common-bin-$(PKG_SOURCE_DATE)-linux-$(PKG_ARCH_LINKEASE).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/istoreos/istoreos-app-hub/releases/download/linkease-runtime-v$(PKG_SOURCE_DATE)/
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/linkease-common-bin-$(PKG_SOURCE_DATE)-linux-$(PKG_ARCH_LINKEASE)
|
||||
|
||||
+4
-4
@@ -10,9 +10,9 @@ include $(TOPDIR)/rules.mk
|
||||
PKG_ARCH_LINKEASE:=$(ARCH)
|
||||
|
||||
PKG_NAME:=linkease
|
||||
PKG_VERSION:=linkease-runtime-v1.7.5
|
||||
PKG_SOURCE_DATE:=$(PKG_VERSION)
|
||||
PKG_RELEASE:=5
|
||||
# use PKG_SOURCE_DATE instead of PKG_VERSION for compitable
|
||||
PKG_SOURCE_DATE:=1.7.5
|
||||
PKG_RELEASE:=6
|
||||
|
||||
ARCH_HEXCODE:=
|
||||
ifeq ($(ARCH),x86_64)
|
||||
@@ -28,7 +28,7 @@ else ifeq ($(ARCH),mipsel)
|
||||
ARCH_HEXCODE=1b0c
|
||||
endif
|
||||
|
||||
PKG_SOURCE_VERSION:=f6d705f77dade7d57c1bb24334da4028279689b9
|
||||
PKG_SOURCE_VERSION:=8895348606dc6cab9b25a75576e5142f553dfa82
|
||||
PKG_SOURCE:=linkease-bin-$(PKG_SOURCE_DATE)-linux-$(PKG_ARCH_LINKEASE).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/istoreos/istoreos-app-hub/releases/download/linkease-runtime-v$(PKG_SOURCE_DATE)/
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/linkease-bin-$(PKG_SOURCE_DATE)-linux-$(PKG_ARCH_LINKEASE)
|
||||
|
||||
+11
-4
@@ -6,19 +6,25 @@
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=linkeasefull
|
||||
PKG_VERSION:=linkease-runtime-v1.7.5
|
||||
PKG_SOURCE_DATE:=$(PKG_VERSION)
|
||||
PKG_RELEASE:=4
|
||||
PKG_ARCH_LINKEASE:=$(ARCH)
|
||||
|
||||
PKG_NAME:=linkeasefull
|
||||
# use PKG_SOURCE_DATE instead of PKG_VERSION for compitable
|
||||
PKG_SOURCE_DATE:=3.0.5
|
||||
PKG_RELEASE:=5
|
||||
|
||||
ARCH_HEXCODE:=
|
||||
ifeq ($(ARCH),x86_64)
|
||||
ARCH_HEXCODE=8664
|
||||
LINKEASE_RUNTIME_ARCH:=amd64
|
||||
PKG_HASH:=skip
|
||||
else ifeq ($(ARCH),aarch64)
|
||||
ARCH_HEXCODE=aa64
|
||||
LINKEASE_RUNTIME_ARCH:=arm64
|
||||
PKG_HASH:=skip
|
||||
endif
|
||||
|
||||
PKG_SOURCE_VERSION:=8895348606dc6cab9b25a75576e5142f553dfa82
|
||||
PKG_SOURCE:=linkease-runtime-$(PKG_SOURCE_DATE)-linux-$(LINKEASE_RUNTIME_ARCH).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/istoreos/istoreos-app-hub/releases/download/linkeasefull-runtime-v$(PKG_SOURCE_DATE)/
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/linkease-runtime-$(PKG_SOURCE_DATE)-linux-$(LINKEASE_RUNTIME_ARCH)
|
||||
@@ -34,6 +40,7 @@ define Package/$(PKG_NAME)
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
TITLE:=LinkEase Full - the local web desktop
|
||||
DEPENDS:=@(x86_64||aarch64) +linkease-common-bin +ca-bundle
|
||||
PKGARCH:=all
|
||||
URL:=https://www.linkease.com/
|
||||
endef
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-gecoosac
|
||||
PKG_VERSION:=2.2
|
||||
PKG_RELEASE:=14
|
||||
PKG_RELEASE:=15
|
||||
|
||||
LUCI_TITLE:=LuCI Support for gecoosac
|
||||
LUCI_DEPENDS:=+luci-base +gecoosac
|
||||
|
||||
@@ -20,7 +20,8 @@ let statusPollRegistered = false;
|
||||
const callServiceStatus = rpc.declare({
|
||||
object: 'luci.gecoosac',
|
||||
method: 'status',
|
||||
expect: { '': {} }
|
||||
expect: { '': {} },
|
||||
reject: true
|
||||
});
|
||||
|
||||
const callClearUpload = rpc.declare({
|
||||
@@ -34,6 +35,26 @@ function validPort(value, defaultValue) {
|
||||
return Number.isInteger(port) && port >= 1 && port <= 65535 ? String(port) : defaultValue;
|
||||
}
|
||||
|
||||
function validPortValue(value) {
|
||||
const text = String(value || '');
|
||||
const port = Number(text);
|
||||
|
||||
return /^[0-9]+$/.test(text) && Number.isSafeInteger(port) && port >= 1 && port <= 65535;
|
||||
}
|
||||
|
||||
function validatePortValue(section_id, value, otherOption, singlePortOption) {
|
||||
if (!validPortValue(value))
|
||||
return _('Port must be an integer between 1 and 65535.');
|
||||
|
||||
const singlePort = singlePortOption.formvalue(section_id);
|
||||
const otherValue = otherOption.formvalue(section_id);
|
||||
|
||||
if (singlePort === '0' && validPortValue(otherValue) && Number(value) === Number(otherValue))
|
||||
return _('Interface port and management port must be different.');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function normalizePath(value) {
|
||||
const path = String(value || '');
|
||||
|
||||
@@ -99,6 +120,9 @@ function serviceRunning(status) {
|
||||
const service = status && status.gecoosac;
|
||||
const instances = service && service.instances;
|
||||
|
||||
if (status && status.ok === false)
|
||||
return false;
|
||||
|
||||
if (status && status.running === true)
|
||||
return true;
|
||||
|
||||
@@ -112,6 +136,13 @@ function serviceRunning(status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function statusFailure() {
|
||||
return {
|
||||
ok: false,
|
||||
error: _('Unable to query service status')
|
||||
};
|
||||
}
|
||||
|
||||
function clientHost() {
|
||||
let host = window.location.hostname;
|
||||
|
||||
@@ -132,6 +163,9 @@ function clientUrl() {
|
||||
}
|
||||
|
||||
function renderStatusContent(status) {
|
||||
if (status && status.error)
|
||||
return E('p', { 'class': 'gecoosac-stopped' }, _('Service status unavailable') + ': ' + _(status.error));
|
||||
|
||||
const running = serviceRunning(status);
|
||||
const text = running
|
||||
? _('The GecoosAC service is running.')
|
||||
@@ -174,12 +208,15 @@ return view.extend({
|
||||
load() {
|
||||
return Promise.all([
|
||||
uci.load('gecoosac'),
|
||||
L.resolveDefault(callServiceStatus(), {})
|
||||
callServiceStatus().catch(function() {
|
||||
return statusFailure();
|
||||
})
|
||||
]);
|
||||
},
|
||||
|
||||
render(data) {
|
||||
let m, s, o, uploadDirOption;
|
||||
let portOption, managementPortOption, singlePortOption;
|
||||
|
||||
m = new form.Map('gecoosac', _('Gecoos AC'),
|
||||
_('Only supports Gecoos AP firmware 7.6 and above.') + '<br />' +
|
||||
@@ -190,7 +227,9 @@ return view.extend({
|
||||
s.render = function() {
|
||||
if (!statusPollRegistered) {
|
||||
poll.add(function() {
|
||||
return L.resolveDefault(callServiceStatus(), {}).then(updateStatus);
|
||||
return callServiceStatus().then(updateStatus).catch(function() {
|
||||
updateStatus(statusFailure());
|
||||
});
|
||||
}, 3);
|
||||
statusPollRegistered = true;
|
||||
}
|
||||
@@ -212,23 +251,55 @@ return view.extend({
|
||||
o = s.option(form.Flag, 'enabled', _('Enabled AC'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'port', _('Set interface port'));
|
||||
portOption = s.option(form.Value, 'port', _('Set interface port'));
|
||||
o = portOption;
|
||||
o.placeholder = '60650';
|
||||
o.default = '60650';
|
||||
o.datatype = 'port';
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Flag, 'isonlyoneprot', _('Single Port Mode'),
|
||||
singlePortOption = s.option(form.Flag, 'isonlyoneprot', _('Single Port Mode'),
|
||||
_('Do not enable the independent management port, only use one port for management.'));
|
||||
o = singlePortOption;
|
||||
o.default = '1';
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'm_port', _('Set management port'));
|
||||
managementPortOption = s.option(form.Value, 'm_port', _('Set management port'));
|
||||
o = managementPortOption;
|
||||
o.placeholder = '8080';
|
||||
o.default = '8080';
|
||||
o.datatype = 'port';
|
||||
o.depends('isonlyoneprot', '0');
|
||||
|
||||
portOption.validate = function(section_id, value) {
|
||||
return validatePortValue(section_id, value, managementPortOption, singlePortOption);
|
||||
};
|
||||
managementPortOption.validate = function(section_id, value) {
|
||||
return validatePortValue(section_id, value, portOption, singlePortOption);
|
||||
};
|
||||
singlePortOption.validate = function(section_id, value) {
|
||||
if (value === '0') {
|
||||
const port = portOption.formvalue(section_id);
|
||||
const managementPort = managementPortOption.formvalue(section_id);
|
||||
|
||||
if (validPortValue(port) && validPortValue(managementPort) && Number(port) === Number(managementPort))
|
||||
return _('Interface port and management port must be different.');
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
const revalidatePorts = function(_event, section_id) {
|
||||
for (const option of [ portOption, managementPortOption, singlePortOption ]) {
|
||||
const element = option.getUIElement(section_id);
|
||||
|
||||
if (element)
|
||||
element.triggerValidation();
|
||||
}
|
||||
};
|
||||
portOption.onchange = revalidatePorts;
|
||||
managementPortOption.onchange = revalidatePorts;
|
||||
singlePortOption.onchange = revalidatePorts;
|
||||
|
||||
o = s.option(form.Flag, 'https', _('Enable HTTPS service'),
|
||||
_('Default certificate files are generated when HTTPS starts; custom paths must point to a readable certificate and matching key.'));
|
||||
o.default = '0';
|
||||
@@ -320,11 +391,11 @@ return view.extend({
|
||||
if (!confirm(_('Really clear the saved upload directory?')))
|
||||
return Promise.resolve();
|
||||
|
||||
return callClearUpload().then(function(res) {
|
||||
if (res && res.result === true)
|
||||
return callClearUpload().then(function() {
|
||||
if (arguments[0] && arguments[0].result === true)
|
||||
ui.addNotification(null, E('p', {}, _('Saved upload directory cleared')));
|
||||
else
|
||||
ui.addNotification(null, E('p', {}, clearUploadError(res)), 'danger');
|
||||
ui.addNotification(null, E('p', {}, clearUploadError(arguments[0])), 'danger');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -147,3 +147,36 @@ msgstr "无法删除上传目录内容"
|
||||
|
||||
msgid "Upload directory contains configured runtime paths"
|
||||
msgstr "上传目录包含已配置的运行目录"
|
||||
|
||||
msgid "Port must be an integer between 1 and 65535."
|
||||
msgstr "端口必须是 1 到 65535 之间的整数。"
|
||||
|
||||
msgid "Interface port and management port must be different."
|
||||
msgstr "接口端口和管理端口必须不同。"
|
||||
|
||||
msgid "Unable to query service status"
|
||||
msgstr "无法查询服务状态"
|
||||
|
||||
msgid "Service status unavailable"
|
||||
msgstr "服务状态不可用"
|
||||
|
||||
msgid "Invalid service status response"
|
||||
msgstr "服务状态响应无效"
|
||||
|
||||
msgid "Unable to resolve upload directory"
|
||||
msgstr "无法解析上传目录"
|
||||
|
||||
msgid "Upload directory contains a configured protected path"
|
||||
msgstr "上传目录包含已配置的受保护路径"
|
||||
|
||||
msgid "Unable to validate configured paths"
|
||||
msgstr "无法验证已配置的路径"
|
||||
|
||||
msgid "Upload directory or its parent is not root-owned and private"
|
||||
msgstr "上传目录或其父目录不是 root 所有且为私有目录"
|
||||
|
||||
msgid "Unable to prepare upload directory cleanup"
|
||||
msgstr "无法准备上传目录清理"
|
||||
|
||||
msgid "Unable to recreate upload directory"
|
||||
msgstr "无法重新创建上传目录"
|
||||
|
||||
@@ -147,3 +147,36 @@ msgstr "無法移除上傳目錄內容"
|
||||
|
||||
msgid "Upload directory contains configured runtime paths"
|
||||
msgstr "上傳目錄包含已設定的執行時路徑"
|
||||
|
||||
msgid "Port must be an integer between 1 and 65535."
|
||||
msgstr "連接埠必須是 1 到 65535 之間的整數。"
|
||||
|
||||
msgid "Interface port and management port must be different."
|
||||
msgstr "介面連接埠和管理連接埠必須不同。"
|
||||
|
||||
msgid "Unable to query service status"
|
||||
msgstr "無法查詢服務狀態"
|
||||
|
||||
msgid "Service status unavailable"
|
||||
msgstr "服務狀態無法使用"
|
||||
|
||||
msgid "Invalid service status response"
|
||||
msgstr "服務狀態回應無效"
|
||||
|
||||
msgid "Unable to resolve upload directory"
|
||||
msgstr "無法解析上傳目錄"
|
||||
|
||||
msgid "Upload directory contains a configured protected path"
|
||||
msgstr "上傳目錄包含已設定的受保護路徑"
|
||||
|
||||
msgid "Unable to validate configured paths"
|
||||
msgstr "無法驗證已設定的路徑"
|
||||
|
||||
msgid "Upload directory or its parent is not root-owned and private"
|
||||
msgstr "上傳目錄或其父目錄不是 root 所有且為私有目錄"
|
||||
|
||||
msgid "Unable to prepare upload directory cleanup"
|
||||
msgstr "無法準備上傳目錄清理"
|
||||
|
||||
msgid "Unable to recreate upload directory"
|
||||
msgstr "無法重新建立上傳目錄"
|
||||
|
||||
@@ -80,31 +80,96 @@ path_in_dir() {
|
||||
[ "${path#"$root"/}" != "$path" ]
|
||||
}
|
||||
|
||||
is_secure_dir() {
|
||||
local allow_sticky="$2" owner permissions metadata
|
||||
|
||||
[ -d "$1" ] && [ ! -L "$1" ] || return 1
|
||||
metadata="$(ls -ldn "$1" 2>/dev/null)" || return 1
|
||||
set -- $metadata
|
||||
permissions="$1"
|
||||
owner="$3"
|
||||
[ "$owner" = "0" ] || return 1
|
||||
case "$permissions" in
|
||||
d?????????) ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
|
||||
if [ "$(printf '%s' "$permissions" | cut -c6)" = "w" ] || \
|
||||
[ "$(printf '%s' "$permissions" | cut -c9)" = "w" ]; then
|
||||
[ "$allow_sticky" = "1" ] && [ "$(printf '%s' "$permissions" | cut -c10)" = "t" ] || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_secure_upload_dir() {
|
||||
local path current part rest
|
||||
|
||||
path="$(normalize_path "$1")" || return 1
|
||||
[ -d "$path" ] && [ ! -L "$path" ] || return 1
|
||||
current="/"
|
||||
rest="${path#/}"
|
||||
|
||||
while [ -n "$rest" ]; do
|
||||
part="${rest%%/*}"
|
||||
if [ "$part" = "$rest" ]; then
|
||||
rest=""
|
||||
else
|
||||
rest="${rest#*/}"
|
||||
fi
|
||||
current="${current%/}/$part"
|
||||
case "$current" in
|
||||
/tmp) is_secure_dir "$current" 1 || return 1 ;;
|
||||
*) is_secure_dir "$current" || return 1 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
configured_path_in_upload() {
|
||||
local option="$1"
|
||||
local upload_path="$2"
|
||||
local path real_path
|
||||
local upload_path="$2" path real_path
|
||||
|
||||
path="$(uci -q get "gecoosac.config.${option}")"
|
||||
[ -n "$path" ] || return 1
|
||||
|
||||
case "$path" in
|
||||
/*) ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
path="$(normalize_path "$path")" || return 2
|
||||
path_in_dir "$path" "$upload_path" && return 0
|
||||
|
||||
real_path="$(readlink -f "$path" 2>/dev/null)"
|
||||
[ -n "$real_path" ] || real_path="$(normalize_path "$path")" || return 1
|
||||
real_path="$(readlink -f "$path" 2>/dev/null)" || return 2
|
||||
[ -n "$real_path" ] || return 2
|
||||
real_path="$(normalize_path "$real_path")" || return 2
|
||||
|
||||
path_in_dir "$real_path" "$upload_path"
|
||||
}
|
||||
|
||||
status_result() {
|
||||
local ok="$1" running="$2" message="$3"
|
||||
|
||||
json_init
|
||||
json_add_boolean ok "$ok"
|
||||
json_add_boolean running "$running"
|
||||
[ -n "$message" ] && json_add_string error "$message"
|
||||
json_dump
|
||||
json_cleanup
|
||||
}
|
||||
|
||||
service_status() {
|
||||
local data instances instance running state
|
||||
|
||||
running=0
|
||||
data="$(ubus call service list '{"name":"gecoosac"}' 2>/dev/null)"
|
||||
if json_load "$data" 2>/dev/null && json_select gecoosac 2>/dev/null && json_select instances 2>/dev/null; then
|
||||
data="$(ubus call service list '{"name":"gecoosac"}' 2>/dev/null)" || {
|
||||
status_result 0 0 "Unable to query service status"
|
||||
return
|
||||
}
|
||||
json_load "$data" 2>/dev/null || {
|
||||
status_result 0 0 "Invalid service status response"
|
||||
return
|
||||
}
|
||||
|
||||
if json_select gecoosac 2>/dev/null; then
|
||||
if ! json_select instances 2>/dev/null; then
|
||||
json_cleanup
|
||||
status_result 0 0 "Invalid service status response"
|
||||
return
|
||||
fi
|
||||
json_get_keys instances
|
||||
for instance in $instances; do
|
||||
json_select "$instance" 2>/dev/null || continue
|
||||
@@ -117,14 +182,12 @@ service_status() {
|
||||
done
|
||||
fi
|
||||
|
||||
json_init
|
||||
json_add_boolean running "$running"
|
||||
json_dump
|
||||
json_cleanup
|
||||
status_result 1 "$running"
|
||||
}
|
||||
|
||||
clear_upload() {
|
||||
local path real entry
|
||||
local path real parent stage option
|
||||
|
||||
path="$(uci -q get gecoosac.config.upload_dir)"
|
||||
[ -n "$path" ] || path="$DEFAULT_UPLOAD_DIR"
|
||||
@@ -134,31 +197,69 @@ clear_upload() {
|
||||
*) json_result 0 "Expecting an absolute path"; return ;;
|
||||
esac
|
||||
|
||||
path="$(normalize_path "$path")"
|
||||
path="$(normalize_path "$path")" || { json_result 0 "Expecting an absolute path"; return; }
|
||||
real="$(readlink -f "$path" 2>/dev/null)"
|
||||
[ -n "$real" ] || real="$path"
|
||||
[ -n "$real" ] || { json_result 0 "Unable to resolve upload directory" "$path"; return; }
|
||||
real="$(normalize_path "$real")" || { json_result 0 "Expecting an absolute path"; return; }
|
||||
|
||||
if ! safe_upload_path "$real"; then
|
||||
if [ "$real" != "$path" ] || ! safe_upload_path "$real"; then
|
||||
json_result 0 "Only Gecoos upload directories can be cleared" "$real"
|
||||
return
|
||||
fi
|
||||
|
||||
if configured_path_in_upload db_dir "$real" || configured_path_in_upload piddir "$real"; then
|
||||
json_result 0 "Upload directory contains configured runtime paths" "$real"
|
||||
if [ ! -e "$real" ] && [ ! -L "$real" ]; then
|
||||
json_result 1 "" "$real"
|
||||
return
|
||||
fi
|
||||
if ! is_secure_upload_dir "$real"; then
|
||||
json_result 0 "Upload directory or its parent is not root-owned and private" "$real"
|
||||
return
|
||||
fi
|
||||
|
||||
[ -d "$real" ] || { json_result 1 "" "$real"; return; }
|
||||
for option in db_dir piddir crt_file key_file; do
|
||||
configured_path_in_upload "$option" "$real"
|
||||
case "$?" in
|
||||
0) json_result 0 "Upload directory contains a configured protected path" "$real"; return ;;
|
||||
1) ;;
|
||||
*) json_result 0 "Unable to validate configured paths" "$real"; return ;;
|
||||
esac
|
||||
done
|
||||
|
||||
for entry in "$real"/* "$real"/.[!.]* "$real"/..?*; do
|
||||
[ -e "$entry" ] || [ -L "$entry" ] || continue
|
||||
parent="${real%/*}"
|
||||
stage="$(mktemp -d "$parent/.gecoosac-clear.XXXXXX" 2>/dev/null)" || {
|
||||
json_result 0 "Unable to prepare upload directory cleanup" "$real"
|
||||
return
|
||||
}
|
||||
if ! chmod 0700 "$stage"; then
|
||||
rm -rf "$stage"
|
||||
json_result 0 "Unable to prepare upload directory cleanup" "$real"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! rm -rf "$entry"; then
|
||||
json_result 0 "Unable to remove upload directory contents" "$real"
|
||||
if ! mv "$real" "$stage/upload"; then
|
||||
rm -rf "$stage"
|
||||
json_result 0 "Unable to prepare upload directory cleanup" "$real"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! rm -rf "$stage/upload"; then
|
||||
if [ ! -e "$real" ] && [ ! -L "$real" ]; then
|
||||
mkdir "$real" 2>/dev/null && chmod 0750 "$real" 2>/dev/null
|
||||
fi
|
||||
logger -t gecoosac "upload cleanup retained staged data at $stage"
|
||||
json_result 0 "Unable to remove upload directory contents" "$real"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ ! -d "$real" ]; then
|
||||
if ! mkdir "$real" && { [ ! -d "$real" ] || [ -L "$real" ]; }; then
|
||||
json_result 0 "Unable to recreate upload directory" "$real"
|
||||
return
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ -L "$real" ] || ! chmod 0750 "$real" || ! is_secure_upload_dir "$real" || ! rmdir "$stage"; then
|
||||
json_result 0 "Unable to recreate upload directory" "$real"
|
||||
return
|
||||
fi
|
||||
|
||||
json_result 1 "" "$real"
|
||||
}
|
||||
|
||||
@@ -1,15 +1,46 @@
|
||||
# Copyright (C) 2018-2022 Lienol <lawlienol@gmail.com>
|
||||
# Copyright (C) 2018-2026 Lienol <lawlienol@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for KodExplorer
|
||||
LUCI_DEPENDS:=+nginx-ssl +unzip +zoneinfo-asia +php8 +php8-fastcgi +php8-fpm +php8-mod-curl +php8-mod-dom +php8-mod-gd +php8-mod-iconv +php8-mod-mbstring +php8-mod-opcache +php8-mod-session +php8-mod-zip +php8-mod-sqlite3 +php8-mod-pdo +php8-mod-pdo-sqlite +php8-mod-pdo-mysql +php8-mod-xml +php8-mod-xmlreader +php8-mod-xmlwriter
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_NAME:=luci-app-kodexplorer
|
||||
PKG_VERSION:=20220109
|
||||
PKG_RELEASE:=3
|
||||
PKG_RELEASE:=4
|
||||
|
||||
LUCI_TITLE:=LuCI support for KodExplorer
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_depends
|
||||
depends on PACKAGE_$(PKG_NAME)
|
||||
bool
|
||||
default y
|
||||
select PACKAGE_nginx-ssl
|
||||
select PACKAGE_unzip
|
||||
select PACKAGE_zoneinfo-asia
|
||||
select PACKAGE_php8
|
||||
select PACKAGE_php8-fastcgi
|
||||
select PACKAGE_php8-fpm
|
||||
select PACKAGE_php8-mod-curl
|
||||
select PACKAGE_php8-mod-dom
|
||||
select PACKAGE_php8-mod-gd
|
||||
select PACKAGE_php8-mod-iconv
|
||||
select PACKAGE_php8-mod-mbstring
|
||||
select PACKAGE_php8-mod-opcache
|
||||
select PACKAGE_php8-mod-pdo
|
||||
select PACKAGE_php8-mod-pdo-mysql
|
||||
select PACKAGE_php8-mod-pdo-sqlite
|
||||
select PACKAGE_php8-mod-session
|
||||
select PACKAGE_php8-mod-sqlite3
|
||||
select PACKAGE_php8-mod-xml
|
||||
select PACKAGE_php8-mod-xmlreader
|
||||
select PACKAGE_php8-mod-xmlwriter
|
||||
select PACKAGE_php8-mod-zip
|
||||
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for linkeaselite
|
||||
LUCI_DEPENDS:=+linkeaselite
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=3
|
||||
LUCI_MINIFY_CSS:=0
|
||||
LUCI_MINIFY_JS:=0
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -1,31 +0,0 @@
|
||||
module("luci.controller.linkeaselite", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/linkeaselite") then
|
||||
return
|
||||
end
|
||||
|
||||
local page = entry({"admin", "services", "linkeaselite"}, firstchild(), _("LinkEaseLite"), 20)
|
||||
page.dependent = true
|
||||
entry({"admin", "services", "linkeaselite", "config"}, cbi("linkeaselite"), _("Settings"), 10).leaf = true
|
||||
entry({"admin", "services", "linkeaselite_status"}, call("linkeaselite_status"))
|
||||
entry({"admin", "services", "linkeaselite", "file"}, call("linkeaselite_file_removed")).leaf = true
|
||||
end
|
||||
|
||||
function linkeaselite_status()
|
||||
local sys = require "luci.sys"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local port = tonumber(uci:get_first("linkeaselite", "linkeaselite", "port"))
|
||||
|
||||
local status = {
|
||||
running = (sys.call("pidof linkease-lite >/dev/null") == 0),
|
||||
port = (port or 8897)
|
||||
}
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(status)
|
||||
end
|
||||
|
||||
function linkeaselite_file_removed()
|
||||
luci.http.status(404, "Not Found")
|
||||
end
|
||||
@@ -1,24 +0,0 @@
|
||||
local m, s
|
||||
local sys = require "luci.sys"
|
||||
|
||||
m = Map("linkeaselite", translate("LinkEaseLite"), translate("LinkEaseLite is an efficient data transfer tool for small-memory devices."))
|
||||
m:section(SimpleSection).template = "linkeaselite_status"
|
||||
|
||||
m.on_after_commit = function(self)
|
||||
sys.call("/etc/init.d/linkeaselite restart >/dev/null 2>&1")
|
||||
end
|
||||
|
||||
s = m:section(TypedSection, "linkeaselite", translate("Global settings"))
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
s:option(Flag, "enabled", translate("Enable")).rmempty = false
|
||||
|
||||
local port = s:option(Value, "port", translate("Port"))
|
||||
port.rmempty = false
|
||||
port.datatype = "port"
|
||||
port.default = "8897"
|
||||
|
||||
s:option(Flag, "allowPublic", translate("AllowPublic"), translate("Allowing access via public IP addresses can lead to insufficient security.")).rmempty = false
|
||||
|
||||
return m
|
||||
@@ -1,42 +0,0 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(5, '<%=url("admin/services/linkeaselite_status")%>', null,
|
||||
function(x, st)
|
||||
{
|
||||
var tb = document.getElementById('linkeaselite_status');
|
||||
if (st && tb)
|
||||
{
|
||||
var legacyUrl = "http://" + window.location.hostname + ":" + (st.port || 8897) + "/";
|
||||
var overallStatus = st.running
|
||||
? '<br/><em style=\"color:green\"><%:The LinkEaseLite service is running.%></em>'
|
||||
: '<br/><em style=\"color:red\"><%:The LinkEaseLite service is not running.%></em>';
|
||||
tb.innerHTML = overallStatus;
|
||||
|
||||
function appendBreak()
|
||||
{
|
||||
tb.appendChild(document.createElement("br"));
|
||||
}
|
||||
|
||||
function appendButton(value, action)
|
||||
{
|
||||
var button = document.createElement("input");
|
||||
button.className = "btn cbi-button cbi-button-apply";
|
||||
button.type = "button";
|
||||
button.value = value;
|
||||
button.onclick = action;
|
||||
tb.appendChild(button);
|
||||
}
|
||||
|
||||
appendBreak();
|
||||
appendBreak();
|
||||
appendButton(" <%:Click to open LinkEaseLite%> ", function() { window.open(legacyUrl); });
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]></script>
|
||||
|
||||
<fieldset class="cbi-section">
|
||||
<legend><%:LinkEaseLite Status%></legend>
|
||||
<p id="linkeaselite_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
||||
@@ -1,35 +0,0 @@
|
||||
msgid "LinkEaseLite"
|
||||
msgstr "易有云Lite"
|
||||
|
||||
msgid "LinkEaseLite is an efficient data transfer tool for small-memory devices."
|
||||
msgstr "易有云Lite是面向小内存设备的轻量数据传输工具。"
|
||||
|
||||
msgid "Global settings"
|
||||
msgstr "全局设置"
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "AllowPublic"
|
||||
msgstr "公网访问"
|
||||
|
||||
msgid "Allowing access via public IP addresses can lead to insufficient security."
|
||||
msgstr "允许公网IP访问,会导致不够安全。"
|
||||
|
||||
msgid "Click to open LinkEaseLite"
|
||||
msgstr "点击打开易有云Lite"
|
||||
|
||||
msgid "The LinkEaseLite service is running."
|
||||
msgstr "易有云Lite服务已启动"
|
||||
|
||||
msgid "The LinkEaseLite service is not running."
|
||||
msgstr "易有云Lite服务未启动"
|
||||
|
||||
msgid "LinkEaseLite Status"
|
||||
msgstr "易有云Lite服务状态"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "收集数据..."
|
||||
@@ -1 +0,0 @@
|
||||
zh-cn
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f /tmp/luci-indexcache /tmp/luci-indexcache.*
|
||||
exit 0
|
||||
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=26.8.1
|
||||
PKG_RELEASE:=202
|
||||
PKG_RELEASE:=203
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -1105,6 +1105,9 @@ function gen_config(var)
|
||||
local dns_socks_address = var["dns_socks_address"]
|
||||
local dns_socks_port = var["dns_socks_port"]
|
||||
local no_run = var["no_run"]
|
||||
local use_proxy_list = var["use_proxy_list"]
|
||||
local use_gfw_list = var["use_gfw_list"]
|
||||
local chn_list = var["chn_list"]
|
||||
|
||||
local dns_domain_rules = {}
|
||||
local dns = nil
|
||||
@@ -1552,7 +1555,50 @@ function gen_config(var)
|
||||
end
|
||||
|
||||
--shunt rule
|
||||
uci:foreach(appname, "shunt_rules", function(e)
|
||||
local function foreach_shunt_rule(callback)
|
||||
uci:foreach(appname, "shunt_rules", callback)
|
||||
|
||||
if use_gfw_list ~= "1" or chn_list ~= "0" then return end
|
||||
|
||||
-- GFW 模式下使用分流节点时添加特定规则
|
||||
local function read_proxy_list(path)
|
||||
if use_proxy_list ~= "1" then return "" end
|
||||
local map, list = {}, {}
|
||||
local f = io.open(path)
|
||||
if f then
|
||||
for line in f:lines() do
|
||||
if line ~= "" and not line:find("#", 1, true) and not map[line] then
|
||||
map[line] = 1
|
||||
list[#list + 1] = line
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
return table.concat(list, "\n")
|
||||
end
|
||||
|
||||
local domain_list = read_proxy_list("/usr/share/passwall/rules/proxy_host")
|
||||
local ip_list = read_proxy_list("/usr/share/passwall/rules/proxy_ip")
|
||||
|
||||
local bin = api.finded_com("geoview")
|
||||
if bin then
|
||||
local geo_file = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") .. "/geosite.dat"
|
||||
if luci.sys.call('"' .. bin .. '" -type geosite -input "' .. geo_file .. '" | grep -q "^GFW$"') == 0 then
|
||||
domain_list = (domain_list == "") and "geosite:gfw" or domain_list .. "\ngeosite:gfw"
|
||||
end
|
||||
end
|
||||
|
||||
if domain_list ~= "" or ip_list ~= "" then
|
||||
node["GFW_Mode_List"] = "_default"
|
||||
callback({
|
||||
[".name"] = "GFW_Mode_List",
|
||||
remarks = "GFW_Mode_List",
|
||||
domain_list = (domain_list ~= "") and domain_list or nil,
|
||||
ip_list = (ip_list ~= "") and ip_list or nil
|
||||
})
|
||||
end
|
||||
end
|
||||
foreach_shunt_rule(function(e)
|
||||
local outboundTag = gen_shunt_node(e[".name"])
|
||||
if outboundTag and e.remarks then
|
||||
if outboundTag == "default" then
|
||||
@@ -1755,6 +1801,14 @@ function gen_config(var)
|
||||
table.insert(rules, rule)
|
||||
end
|
||||
end)
|
||||
|
||||
if use_gfw_list == "1" and chn_list == "0" then -- GFW 模式下使用分流节点时添加兜底规则
|
||||
table.insert(rules, {
|
||||
action = "route",
|
||||
port_range = { "0:65535" },
|
||||
outbound = "direct"
|
||||
})
|
||||
end
|
||||
else
|
||||
COMMON.default_outbound_tag = gen_outbound_get_tag(flag, node or node_id, nil, {
|
||||
fragment = singbox_settings.fragment == "1" or nil,
|
||||
|
||||
@@ -868,6 +868,9 @@ function gen_config(var)
|
||||
local dns_socks_port = var["dns_socks_port"]
|
||||
local loglevel = var["loglevel"] or "warning"
|
||||
local no_run = var["no_run"]
|
||||
local use_proxy_list = var["use_proxy_list"]
|
||||
local use_gfw_list = var["use_gfw_list"]
|
||||
local chn_list = var["chn_list"]
|
||||
|
||||
local dns_domain_rules = {}
|
||||
local dns = nil
|
||||
@@ -1363,7 +1366,50 @@ function gen_config(var)
|
||||
end
|
||||
|
||||
--shunt rule
|
||||
uci:foreach(appname, "shunt_rules", function(e)
|
||||
local function foreach_shunt_rule(callback)
|
||||
uci:foreach(appname, "shunt_rules", callback)
|
||||
|
||||
if use_gfw_list ~= "1" or chn_list ~= "0" then return end
|
||||
|
||||
-- GFW 模式下使用分流节点时添加特定规则
|
||||
local function read_proxy_list(path)
|
||||
if use_proxy_list ~= "1" then return "" end
|
||||
local map, list = {}, {}
|
||||
local f = io.open(path)
|
||||
if f then
|
||||
for line in f:lines() do
|
||||
if line ~= "" and not line:find("#", 1, true) and not map[line] then
|
||||
map[line] = 1
|
||||
list[#list + 1] = line
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
return table.concat(list, "\n")
|
||||
end
|
||||
|
||||
local domain_list = read_proxy_list("/usr/share/passwall/rules/proxy_host")
|
||||
local ip_list = read_proxy_list("/usr/share/passwall/rules/proxy_ip")
|
||||
|
||||
local bin = api.finded_com("geoview")
|
||||
if bin then
|
||||
local geo_file = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/") .. "/geosite.dat"
|
||||
if luci.sys.call('"' .. bin .. '" -type geosite -input "' .. geo_file .. '" | grep -q "^GFW$"') == 0 then
|
||||
domain_list = (domain_list == "") and "geosite:gfw" or domain_list .. "\ngeosite:gfw"
|
||||
end
|
||||
end
|
||||
|
||||
if domain_list ~= "" or ip_list ~= "" then
|
||||
node["GFW_Mode_List"] = "_default"
|
||||
callback({
|
||||
[".name"] = "GFW_Mode_List",
|
||||
remarks = "GFW_Mode_List",
|
||||
domain_list = (domain_list ~= "") and domain_list or nil,
|
||||
ip_list = (ip_list ~= "") and ip_list or nil
|
||||
})
|
||||
end
|
||||
end
|
||||
foreach_shunt_rule(function(e)
|
||||
local outbound_tag = gen_shunt_node(e[".name"])
|
||||
if outbound_tag and e.remarks then
|
||||
if outbound_tag == "default" then
|
||||
@@ -1463,6 +1509,15 @@ function gen_config(var)
|
||||
end
|
||||
end)
|
||||
|
||||
if use_gfw_list == "1" and chn_list == "0" then -- GFW 模式下使用分流节点时添加兜底规则
|
||||
table.insert(rules, {
|
||||
ruleTag = "GFW_Mode_Default",
|
||||
outboundTag = "direct",
|
||||
port = (node.domainStrategy == "IPIfNonMatch") and "1-65535" or nil,
|
||||
network = (node.domainStrategy ~= "IPIfNonMatch") and "tcp,udp" or nil
|
||||
})
|
||||
end
|
||||
|
||||
table.insert(rules, {
|
||||
outboundTag = "direct",
|
||||
ip = { "geoip:private" }
|
||||
|
||||
@@ -99,7 +99,7 @@ run_ipt2socks() {
|
||||
run_singbox() {
|
||||
local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||
local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
|
||||
local loglevel log_file config_file server_host server_port no_run
|
||||
local loglevel log_file config_file server_host server_port no_run use_proxy_list use_gfw_list chn_list
|
||||
eval_set_val "$@"
|
||||
[ -z "$type" ] && {
|
||||
type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
@@ -120,6 +120,9 @@ run_singbox() {
|
||||
|
||||
[ -n "$flag" ] && json_add_string "flag" "$flag"
|
||||
[ -n "$node" ] && json_add_string "node" "$node"
|
||||
[ -n "$use_proxy_list" ] && json_add_string "use_proxy_list" "$use_proxy_list"
|
||||
[ -n "$use_gfw_list" ] && json_add_string "use_gfw_list" "$use_gfw_list"
|
||||
[ -n "$chn_list" ] && json_add_string "chn_list" "$chn_list"
|
||||
[ -n "$server_host" ] && json_add_string "server_host" "$server_host"
|
||||
[ -n "$server_port" ] && json_add_string "server_port" "$server_port"
|
||||
[ -n "$tcp_redir_port" ] && json_add_string "tcp_redir_port" "$tcp_redir_port"
|
||||
@@ -197,7 +200,7 @@ run_singbox() {
|
||||
run_xray() {
|
||||
local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||
local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
|
||||
local loglevel log_file config_file server_host server_port no_run
|
||||
local loglevel log_file config_file server_host server_port no_run use_proxy_list use_gfw_list chn_list
|
||||
eval_set_val "$@"
|
||||
[ -z "$type" ] && {
|
||||
type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
@@ -209,6 +212,9 @@ run_xray() {
|
||||
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warning")
|
||||
[ -n "$flag" ] && json_add_string "flag" "$flag"
|
||||
[ -n "$node" ] && json_add_string "node" "$node"
|
||||
[ -n "$use_proxy_list" ] && json_add_string "use_proxy_list" "$use_proxy_list"
|
||||
[ -n "$use_gfw_list" ] && json_add_string "use_gfw_list" "$use_gfw_list"
|
||||
[ -n "$chn_list" ] && json_add_string "chn_list" "$chn_list"
|
||||
[ -n "$server_host" ] && json_add_string "server_host" "$server_host"
|
||||
[ -n "$server_port" ] && json_add_string "server_port" "$server_port"
|
||||
[ -n "$tcp_redir_port" ] && json_add_string "tcp_redir_port" "$tcp_redir_port"
|
||||
@@ -760,6 +766,7 @@ run_redir() {
|
||||
}
|
||||
NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1)
|
||||
}
|
||||
_args="${_args} use_proxy_list=$USE_PROXY_LIST use_gfw_list=$USE_GFW_LIST chn_list=$CHN_LIST"
|
||||
run_singbox flag=$_flag node=$node tcp_redir_port=$local_port tcp_proxy_way=$TCP_PROXY_WAY config_file=$config_file log_file=$log_file ${_args}
|
||||
;;
|
||||
xray)
|
||||
@@ -846,6 +853,7 @@ run_redir() {
|
||||
}
|
||||
NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1)
|
||||
}
|
||||
_args="${_args} use_proxy_list=$USE_PROXY_LIST use_gfw_list=$USE_GFW_LIST chn_list=$CHN_LIST"
|
||||
run_xray flag=$_flag node=$node tcp_redir_port=$local_port tcp_proxy_way=$TCP_PROXY_WAY config_file=$config_file log_file=$log_file ${_args}
|
||||
;;
|
||||
naiveproxy)
|
||||
@@ -1751,6 +1759,7 @@ acl_app() {
|
||||
}
|
||||
config_file="$TMP_PATH/$config_file"
|
||||
[ "${type}" = "sing-box" ] && type="singbox"
|
||||
_extra_param="${_extra_param} use_proxy_list=$use_proxy_list use_gfw_list=$use_gfw_list chn_list=$chn_list"
|
||||
run_${type} flag=$tcp_node node=$tcp_node tcp_redir_port=$redir_port ${_extra_param} config_file=$config_file log_file=$log_file loglevel=$loglevel
|
||||
else
|
||||
config_file="acl/${tcp_node}_SOCKS_${socks_port}.json"
|
||||
|
||||
@@ -1398,8 +1398,8 @@ del_firewall_rule() {
|
||||
done
|
||||
for ipt in "$ipt_f" "$ip6t_f"; do
|
||||
for chain in "FORWARD" "INPUT" "OUTPUT"; do
|
||||
for i in $(seq 1 $($ipt -nL $chain | grep -c PSW)); do
|
||||
local index=$($ipt --line-number -nL $chain | grep PSW | head -1 | awk '{print $1}')
|
||||
for i in $(seq 1 $($ipt -nL $chain | grep -c PSW_REJECT)); do
|
||||
local index=$($ipt --line-number -nL $chain | grep PSW_REJECT | head -1 | awk '{print $1}')
|
||||
$ipt -D $chain $index 2>/dev/null
|
||||
done
|
||||
done
|
||||
|
||||
@@ -8,7 +8,6 @@ include $(TOPDIR)/rules.mk
|
||||
LUCI_TITLE:=LuCI based ipk/apk store
|
||||
LUCI_DESCRIPTION:=luci-app-store is a ipk/apk store developed by LinkEase team
|
||||
LUCI_DEPENDS:=@(x86_64||aarch64) +curl +tar +libuci-lua +mount-utils +luci-lib-taskd
|
||||
LUCI_DEPENDS+=$(if $(CONFIG_USE_APK),+apk +luci-compat,+opkg)
|
||||
|
||||
LUCI_EXTRA_DEPENDS:=luci-lib-taskd (>=1.0.19)
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
+2
-2
@@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=natflow
|
||||
PKG_VERSION:=20260531
|
||||
PKG_RELEASE:=60
|
||||
PKG_RELEASE:=61
|
||||
|
||||
PKG_SOURCE:=$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://github.com/ptpt52/natflow.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=c4c0370953045bac23728fbeff456fc584cd9c80
|
||||
PKG_SOURCE_VERSION:=4e62e176dee1ee5d2bea09c40f5d515d6b8a3655
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=fastfetch
|
||||
PKG_VERSION:=2.66.0
|
||||
PKG_RELEASE:=12
|
||||
PKG_VERSION:=2.67.0
|
||||
PKG_RELEASE:=13
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/fastfetch-cli/fastfetch/tar.gz/$(PKG_VERSION)?
|
||||
|
||||
Reference in New Issue
Block a user