diff --git a/filebrowser-q/Makefile b/filebrowser-q/Makefile index ecdb4b8d2..90d8e2cb3 100644 --- a/filebrowser-q/Makefile +++ b/filebrowser-q/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=filebrowser-q PKG_VERSION:=2.1.5-beta -PKG_RELEASE:=18 +PKG_RELEASE:=19 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/gtsteffaniak/filebrowser/tar.gz/v$(PKG_VERSION)? diff --git a/filebrowser-q/files/filebrowser.config b/filebrowser-q/files/filebrowser.config index d42f3440d..d8d51b57b 100644 --- a/filebrowser-q/files/filebrowser.config +++ b/filebrowser-q/files/filebrowser.config @@ -2,4 +2,5 @@ config filebrowser 'config' option enabled '0' option listen_port '8787' option root_path '/' - + option cacheDir '/tmp' + option cacheDirMaxSizeMB '500' diff --git a/filebrowser-q/files/filebrowser.init b/filebrowser-q/files/filebrowser.init index 46a7e6f5e..e85993bdb 100644 --- a/filebrowser-q/files/filebrowser.init +++ b/filebrowser-q/files/filebrowser.init @@ -6,7 +6,7 @@ START=99 CONF="filebrowser-q" PROG="/usr/bin/filebrowser-q" CONF_PATH="/etc/filebrowser-q/config.yaml" -DB_PATH="/etc/filebrowser-q/database.db" +DB_PATH="/etc/filebrowser-q/filebrowser.sqlite" start_service() { config_load "$CONF" @@ -15,16 +15,22 @@ start_service() { config_get_bool enabled "config" "enabled" "0" [ "$enabled" -eq "1" ] || return 1 - local listen_port root_path root_name - config_get listen_port "config" "listen_port" "8787" - config_get root_path "config" "root_path" "/" + local listen_port root_path root_name adminUsername adminPassword cacheDir cacheDirMaxSizeMB + config_get listen_port "config" "listen_port" "8787" + config_get root_path "config" "root_path" "/" + config_get cacheDir "config" "cacheDir" "/tmp" + config_get cacheDirMaxSizeMB "config" "cacheDirMaxSizeMB" "500" - root_name="" - [ "$root_path" = "/" ] && root_name="root" + root_name="" + [ "$root_path" = "/" ] && root_name="root" - if [ ! -f "$CONF_PATH" ]; then - mkdir -p "$(dirname "$CONF_PATH")" - cat < "$CONF_PATH" + # Migrate config files generated by older package versions. + if grep -q 'database.db' "$CONF_PATH"; then + mv -f "$CONF_PATH" "$CONF_PATH".old + fi + if [ ! -f "$CONF_PATH" ]; then + mkdir -p "$(dirname "$CONF_PATH")" + cat < "$CONF_PATH" http: port: $listen_port server: @@ -35,38 +41,28 @@ server: name: "$root_name" config: defaultEnabled: true + cacheDir: "$cacheDir" + cacheDirCleanup: true + cacheDirMaxSizeMB: $cacheDirMaxSizeMB auth: methods: password: enabled: true adminUsername: "admin" - adminPassword: "admin" + adminPassword: "admin123" userDefaults: ui: locale: "zhCN" EOF - else - # Migrate config files generated by older package versions. - if grep -q '^ database: "' "$CONF_PATH"; then - sed -i \ - -e "s/^server:$/http:\\n port: $listen_port\\nserver:/" \ - -e "/^ port:/d" \ - -e 's,^ database: "\(.*\)", database:\n path: "\1",' \ - -e '/^auth:$/a\ - methods:\ - password:\ - enabled: true' \ - -e 's/^ adminUsername:/ adminUsername:/' \ - -e 's/^ adminPassword:/ adminPassword:/' \ - "$CONF_PATH" - fi - - grep -q " name:" "$CONF_PATH" || sed -i "s,.*- path:.*,&\n name: \"\"," "$CONF_PATH" - sed -e "s/^ port:.*/ port: $listen_port/" \ - -e "s, - path:.*, - path: \"$root_path\"," \ - -e "s/ name: \".*\"/ name: \"$root_name\"/" \ - -i "$CONF_PATH" - fi + else + grep -q " name:" "$CONF_PATH" || sed -i "s,.*- path:.*,&\n name: \"\"," "$CONF_PATH" + sed -e "s/^ port:.*/ port: $listen_port/" \ + -e "s, - path:.*, - path: \"$root_path\"," \ + -e "s/ name: \".*\"/ name: \"$root_name\"/" \ + -e "s,^ cacheDir:.*, cacheDir: \"$cacheDir\"," \ + -e "s/^ cacheDirMaxSizeMB:.*/ cacheDirMaxSizeMB: $cacheDirMaxSizeMB/" \ + -i "$CONF_PATH" + fi procd_open_instance procd_set_param command "$PROG" @@ -79,7 +75,6 @@ EOF procd_set_param respawn procd_close_instance - } service_triggers() { diff --git a/luci-app-adguardhome/patches/08_control.patch b/luci-app-adguardhome/patches/08_control.patch index 61aa9b009..53a0de330 100644 --- a/luci-app-adguardhome/patches/08_control.patch +++ b/luci-app-adguardhome/patches/08_control.patch @@ -4,17 +4,19 @@ Date: Sun, 25 Oct 2026 15:11:25 +0800 Subject: [PATCH] Add control script for AdGuardHome management This script manages the AdGuardHome service, including input validation, port management, and redirect handling. + +In exchange mode the saved old_port is recorded in the same sense it is compared later (the port dnsmasq holds once the swap is in place), so repeated runs no longer tear the swap down and rebuild it. --- - root/usr/share/AdGuardHome/control.sh | 273 ++++++++++++++++++++++++++ - 1 file changed, 273 insertions(+) + root/usr/share/AdGuardHome/control.sh | 284 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 284 insertions(+) create mode 100644 root/usr/share/AdGuardHome/control.sh diff --git a/root/usr/share/AdGuardHome/control.sh b/root/usr/share/AdGuardHome/control.sh new file mode 100644 -index 0000000..eabfcf3 +index 0000000..5917abb --- /dev/null +++ b/root/usr/share/AdGuardHome/control.sh -@@ -0,0 +1,273 @@ +@@ -0,0 +1,284 @@ +#!/bin/sh +# /usr/share/AdGuardHome/control.sh +. /usr/share/AdGuardHome/helper.sh @@ -267,9 +269,20 @@ index 0000000..eabfcf3 + fi + fi + ++ # In exchange mode old_port is compared later against the port dnsmasq ++ # holds (the AdGuardHome port before the swap). If the swap is already in ++ # place (yaml 53, dnsmasq elsewhere), record dnsmasq's port, otherwise the ++ # next run sees a bogus change and tears the swap down and rebuilds it. ++ local state_port="$adguardhome_PORT" ++ if [ "$redirect" = "exchange" ] && [ "$enabled" = "1" ] && [ "$adguardhome_PORT" = "53" ]; then ++ local dp ++ dp="$(uci -q get dhcp.@dnsmasq[0].port)" ++ is_port "$dp" && [ "$dp" != "53" ] && state_port="$dp" ++ fi ++ + # All three values are validated above, so this is plain data. + printf 'old_redirect="%s"\nold_port="%s"\nold_enabled="%s"\n' \ -+ "$redirect" "$adguardhome_PORT" "$enabled" > "$STATE_FILE" ++ "$redirect" "$state_port" "$enabled" > "$STATE_FILE" + + if [ "$enabled" = "0" ] || [ "$adguardhome_PORT" = "0" ]; then + printf '%s' "0" > /var/run/AdGredir diff --git a/luci-app-adguardhome/patches/10_yaml_helper.patch b/luci-app-adguardhome/patches/10_yaml_helper.patch index 750841c6a..f3640f135 100644 --- a/luci-app-adguardhome/patches/10_yaml_helper.patch +++ b/luci-app-adguardhome/patches/10_yaml_helper.patch @@ -4,17 +4,19 @@ Date: Sun, 25 Oct 2026 15:13:27 +0800 Subject: [PATCH] Add helper script for YAML configuration management This script provides auxiliary functions for reading and writing YAML configuration files, including a secure method for editing keys and values. + +config_editor replaces the file atomically (mktemp in the same directory, owner and mode kept, then rename) so AdGuard Home can never read a truncated file while it is being edited. --- - root/usr/share/AdGuardHome/helper.sh | 65 ++++++++++++++++++++++++++++ - 1 file changed, 65 insertions(+) + root/usr/share/AdGuardHome/helper.sh | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 76 insertions(+) create mode 100644 root/usr/share/AdGuardHome/helper.sh diff --git a/root/usr/share/AdGuardHome/helper.sh b/root/usr/share/AdGuardHome/helper.sh new file mode 100644 -index 0000000..ddc401f +index 0000000..fdff92b --- /dev/null +++ b/root/usr/share/AdGuardHome/helper.sh -@@ -0,0 +1,65 @@ +@@ -0,0 +1,76 @@ +#!/bin/sh +# Auxiliary functions specially used for reading and writing YAML +# @@ -27,7 +29,7 @@ index 0000000..ddc401f +# ever handed to a shell. VALUE reaches awk through the environment (no -v escape +# processing) and the rewrite is done by awk itself, not by system("sed ..."). +config_editor() { -+ local key="$1" value="$2" file="$3" ro="$4" tmp nl ++ local key="$1" value="$2" file="$3" ro="$4" tmp new nl + nl=' +' + [ -f "$file" ] && [ ! -L "$file" ] || return 1 @@ -44,8 +46,19 @@ index 0000000..ddc401f + + tmp="$(mktemp /tmp/agh_yaml.XXXXXX)" || return 1 + if AGH_VALUE="$value" awk -v yaml="$key" -v ro="" "$AGH_YAML_AWK" "$file" > "$tmp" && [ -s "$tmp" ]; then -+ # Write through the existing file so owner and mode are preserved. -+ cat "$tmp" > "$file" ++ # Replace the file atomically: AdGuardHome may be (re)starting right now, ++ # and truncating it in place lets it read an empty file and overwrite the ++ # whole config with defaults. mktemp (O_EXCL) in the same directory gives ++ # a rename on the same filesystem and cannot be redirected by a symlink. ++ new="$(mktemp "$file.XXXXXX")" || { rm -f "$tmp"; return 1; } ++ if cat "$tmp" > "$new" \ ++ && chown "$(ls -ln "$file" | awk '{print $3":"$4}')" "$new" \ ++ && chmod "$(ls -l "$file" | awk '{m=0; s=substr($1,2,9); for(i=1;i<=9;i++) if(substr(s,i,1)!="-") m+=2^(9-i); printf "%o", m}')" "$new" \ ++ && mv -f "$new" "$file"; then ++ : ++ else ++ rm -f "$new" ++ fi + fi + rm -f "$tmp" +} diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/control.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/control.sh index eabfcf3df..5917abb3f 100755 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/control.sh +++ b/luci-app-adguardhome/root/usr/share/AdGuardHome/control.sh @@ -250,9 +250,20 @@ _do_redirect() { fi fi + # In exchange mode old_port is compared later against the port dnsmasq + # holds (the AdGuardHome port before the swap). If the swap is already in + # place (yaml 53, dnsmasq elsewhere), record dnsmasq's port, otherwise the + # next run sees a bogus change and tears the swap down and rebuilds it. + local state_port="$adguardhome_PORT" + if [ "$redirect" = "exchange" ] && [ "$enabled" = "1" ] && [ "$adguardhome_PORT" = "53" ]; then + local dp + dp="$(uci -q get dhcp.@dnsmasq[0].port)" + is_port "$dp" && [ "$dp" != "53" ] && state_port="$dp" + fi + # All three values are validated above, so this is plain data. printf 'old_redirect="%s"\nold_port="%s"\nold_enabled="%s"\n' \ - "$redirect" "$adguardhome_PORT" "$enabled" > "$STATE_FILE" + "$redirect" "$state_port" "$enabled" > "$STATE_FILE" if [ "$enabled" = "0" ] || [ "$adguardhome_PORT" = "0" ]; then printf '%s' "0" > /var/run/AdGredir diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/helper.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/helper.sh index ddc401f45..fdff92b63 100755 --- a/luci-app-adguardhome/root/usr/share/AdGuardHome/helper.sh +++ b/luci-app-adguardhome/root/usr/share/AdGuardHome/helper.sh @@ -10,7 +10,7 @@ # ever handed to a shell. VALUE reaches awk through the environment (no -v escape # processing) and the rewrite is done by awk itself, not by system("sed ..."). config_editor() { - local key="$1" value="$2" file="$3" ro="$4" tmp nl + local key="$1" value="$2" file="$3" ro="$4" tmp new nl nl=' ' [ -f "$file" ] && [ ! -L "$file" ] || return 1 @@ -27,8 +27,19 @@ config_editor() { tmp="$(mktemp /tmp/agh_yaml.XXXXXX)" || return 1 if AGH_VALUE="$value" awk -v yaml="$key" -v ro="" "$AGH_YAML_AWK" "$file" > "$tmp" && [ -s "$tmp" ]; then - # Write through the existing file so owner and mode are preserved. - cat "$tmp" > "$file" + # Replace the file atomically: AdGuardHome may be (re)starting right now, + # and truncating it in place lets it read an empty file and overwrite the + # whole config with defaults. mktemp (O_EXCL) in the same directory gives + # a rename on the same filesystem and cannot be redirected by a symlink. + new="$(mktemp "$file.XXXXXX")" || { rm -f "$tmp"; return 1; } + if cat "$tmp" > "$new" \ + && chown "$(ls -ln "$file" | awk '{print $3":"$4}')" "$new" \ + && chmod "$(ls -l "$file" | awk '{m=0; s=substr($1,2,9); for(i=1;i<=9;i++) if(substr(s,i,1)!="-") m+=2^(9-i); printf "%o", m}')" "$new" \ + && mv -f "$new" "$file"; then + : + else + rm -f "$new" + fi fi rm -f "$tmp" } diff --git a/luci-app-filebrowser-q/htdocs/luci-static/resources/view/filebrowser-q.js b/luci-app-filebrowser-q/htdocs/luci-static/resources/view/filebrowser-q.js index 5fb856a4c..cd38b85ca 100644 --- a/luci-app-filebrowser-q/htdocs/luci-static/resources/view/filebrowser-q.js +++ b/luci-app-filebrowser-q/htdocs/luci-static/resources/view/filebrowser-q.js @@ -47,8 +47,8 @@ return view.extend({ let webport = (uci.get(data, 'config', 'listen_port') || '8787'); m = new form.Map('filebrowser-q', _('FileBrowser Quantum'), - _('The best free self-hosted web-based file manager.') + '
'+ - _('Default login username is %s and password is %s.').format('admin', 'admin')); + _('The best free self-hosted web-based file manager.') + '
' + + _('Default login username is %s and password is %s.').format('admin', 'admin123')); s = m.section(form.TypedSection); s.anonymous = true; @@ -63,7 +63,7 @@ return view.extend({ return E('div', { class: 'cbi-section', id: 'status_bar' }, [ E('p', { id: 'service_status' }, _('Collecting data...')) ]); - } + }; s = m.section(form.NamedSection, 'config', 'filebrowser'); @@ -80,6 +80,15 @@ return view.extend({ o.default = '/'; o.rmempty = false; + o = s.option(form.Value, 'cacheDir', _('Cache directory')); + o.default = '/tmp'; + o.rmempty = false; + + o = s.option(form.Value, 'cacheDirMaxSizeMB', _('Cache max size (MB)')); + o.datatype = 'uinteger'; + o.default = '500'; + o.rmempty = false; + return m.render(); } }); diff --git a/luci-app-filebrowser-q/po/zh_Hans/filebrowser-q.po b/luci-app-filebrowser-q/po/zh_Hans/filebrowser-q.po index 0edd024ee..497313a23 100644 --- a/luci-app-filebrowser-q/po/zh_Hans/filebrowser-q.po +++ b/luci-app-filebrowser-q/po/zh_Hans/filebrowser-q.po @@ -8,6 +8,12 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Transfer-Encoding: 8bit\n" +msgid "Cache directory" +msgstr "缓存目录" + +msgid "Cache max size (MB)" +msgstr "最大缓存大小 (MB)" + msgid "Collecting data..." msgstr "正在收集数据中..." @@ -31,3 +37,6 @@ msgstr "运行中" msgid "Root directory" msgstr "根目录" + +msgid "The best free self-hosted web-based file manager." +msgstr "好用的免费自托管 Web 文件管理器。"