Skip to content

Commit 2e2ec1d

Browse files
Merge pull request #579 from ExtremeFiretop/dev
Dev 1.6.4 as Next Stable Release
2 parents 681fafc + 7191a70 commit 2e2ec1d

4 files changed

Lines changed: 167 additions & 40 deletions

File tree

‎.github/workflows/Create-NewReleases.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- name: Checkout source code
18-
uses: actions/checkout@v6.0.2
18+
uses: actions/checkout@v6.0.3
1919
with:
2020
fetch-depth: 0
2121
ref: 'main' # Ensure we're tagging the main branch after the merge

‎MerlinAU.sh‎

Lines changed: 163 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
#
55
# Original Creation Date: 2023-Oct-01 by @ExtremeFiretop.
66
# Official Co-Author: @Martinski W. - Date: 2023-Nov-01
7-
# Last Modified: 2026-May-21
7+
# Last Modified: 2026-Jun-11
88
###################################################################
99
set -u
1010

1111
## Set version for each Production Release ##
12-
readonly SCRIPT_VERSION=1.6.3
13-
readonly SCRIPT_VERSTAG="26052123"
12+
readonly SCRIPT_VERSION=1.6.4
13+
readonly SCRIPT_VERSTAG="26061118"
1414
readonly SCRIPT_NAME="MerlinAU"
1515
## Set to "master" for Production Releases ##
16-
SCRIPT_BRANCH="master"
16+
SCRIPT_BRANCH="dev"
1717

1818
##----------------------------------------##
1919
## Modified by Martinski W. [2024-Jul-03] ##
@@ -434,7 +434,7 @@ _ReleaseLock_()
434434
fi
435435
[ -s "$LockFilePath" ] && return 0
436436
fi
437-
rm -f "$LockFilePath"
437+
printf '' > "$LockFilePath"
438438
}
439439

440440
## Defaults ##
@@ -445,7 +445,7 @@ LockFileMaxAgeSecs=600 #10-minutes#
445445
if [ $# -eq 0 ] || [ -z "$1" ]
446446
then
447447
#Interactive Mode#
448-
LockMaxTimeoutSecs=3
448+
LockMaxTimeoutSecs=5
449449
LockFileMaxAgeSecs=1200
450450
else
451451
case "$1" in
@@ -478,7 +478,7 @@ _AcquireLock_()
478478
_CreateLockFile_()
479479
{ echo "$$|$lockTypeReq" > "$LockFilePath" ; }
480480

481-
if [ ! -f "$LockFilePath" ]
481+
if [ ! -s "$LockFilePath" ]
482482
then _CreateLockFile_ ; return 0
483483
fi
484484

@@ -539,6 +539,33 @@ _AcquireLock_()
539539
return "$retCode"
540540
}
541541

542+
##-------------------------------------##
543+
## Added for initialization operations ##
544+
##-------------------------------------##
545+
initMutexFLock_FD=577
546+
initMutexFLock_FN="/tmp/var/${ScriptFNameTag}_Initialization.FLock"
547+
548+
#--------------------------------------------------------------#
549+
# This is a mutually exclusive, blocking FLOCK mechanism used
550+
# to protect initialization routines when concurrent MerlinAU
551+
# executions are running (e.g. called from services-start).
552+
#--------------------------------------------------------------#
553+
_AcquireInitMutexFLock_()
554+
{
555+
eval exec "${initMutexFLock_FD}>$initMutexFLock_FN"
556+
if flock -x "$initMutexFLock_FD" 2>/dev/null
557+
then return 0
558+
fi
559+
eval exec "${initMutexFLock_FD}>&-"
560+
return 1
561+
}
562+
563+
_ReleaseInitMutexFLock_()
564+
{
565+
flock -u "$initMutexFLock_FD" 2>/dev/null
566+
eval exec "${initMutexFLock_FD}>&-"
567+
}
568+
542569
##-------------------------------------##
543570
## Added by Martinski W. [2026-Mar-18] ##
544571
##-------------------------------------##
@@ -773,7 +800,8 @@ Toggle_LEDs_PID=""
773800

774801
# To enable/disable the built-in "F/W Update Check" #
775802
FW_UpdateCheckState="$(nvram get firmware_check_enable)"
776-
FW_UpdateCheckScript="/usr/sbin/webs_update.sh"
803+
readonly FW_WebsUpdateFile="webs_update.sh"
804+
readonly FW_UpdateCheckScript="/usr/sbin/$FW_WebsUpdateFile"
777805

778806
##-------------------------------------##
779807
## Added by Martinski W. [2023-Nov-24] ##
@@ -2217,31 +2245,46 @@ readonly POST_REBOOT_SCRIPT_HOOK="[ -x $ScriptFilePath ] && $POST_REBOOT_SCRIPT_
22172245
readonly POST_UPDATE_EMAIL_SCRIPT_JOB="$ScriptFilePath postUpdateEmail &"
22182246
readonly POST_UPDATE_EMAIL_SCRIPT_HOOK="[ -x $ScriptFilePath ] && $POST_UPDATE_EMAIL_SCRIPT_JOB $hookScriptTagStr"
22192247

2220-
##-------------------------------------##
2221-
## Added by Martinski W. [2026-Feb-07] ##
2222-
##-------------------------------------##
2248+
##------------------------------------------##
2249+
## Modified by ExtremeFiretop [2026-Jun-10] ##
2250+
##------------------------------------------##
22232251
_CleanUpOldLogFiles_()
22242252
{
22252253
[ ! -d "$FW_LOG_DIR" ] && return 1
2226-
local numLogFiles topLogFile
2254+
local numLogFiles topLogFile savedTopLogFile=""
22272255

22282256
numLogFiles="$(ls -1lt "$FW_LOG_DIR"/*.log 2>/dev/null | wc -l)"
22292257
# Leave one log file (if any available) #
22302258
[ "$numLogFiles" -lt 2 ] && return 0
22312259

22322260
# Save the most recent log file #
2233-
topFile="$(ls -1t "$FW_LOG_DIR"/*.log 2>/dev/null | head -n1)"
2234-
[ -n "$topFile" ] && mv -f "$topFile" "${topFile}.SAVED.TEMP.LOG"
2261+
topLogFile="$(ls -1t "$FW_LOG_DIR"/*.log 2>/dev/null | head -n1)"
2262+
2263+
if [ -n "$topLogFile" ] && [ -s "$topLogFile" ]
2264+
then
2265+
savedTopLogFile="${topLogFile}.SAVED.$$.TEMP.LOG"
2266+
if ! mv -f "$topLogFile" "$savedTopLogFile" 2>/dev/null
2267+
then
2268+
return 1
2269+
fi
2270+
fi
22352271

22362272
# Delete logs older than 30 days #
22372273
/usr/bin/find -L "$FW_LOG_DIR" -name '*.log' -mtime +30 -exec rm {} \;
22382274

22392275
# Restore the most recent log file #
2240-
[ -n "$topFile" ] && mv -f "${topFile}.SAVED.TEMP.LOG" "$topFile"
2276+
if [ -n "$topLogFile" ] && \
2277+
[ -n "$savedTopLogFile" ] && \
2278+
[ -s "$savedTopLogFile" ]
2279+
then
2280+
if ! mv -f "$savedTopLogFile" "$topLogFile" 2>/dev/null
2281+
then
2282+
return 1
2283+
fi
2284+
fi
2285+
return 0
22412286
}
22422287

2243-
_CleanUpOldLogFiles_
2244-
22452288
##----------------------------------------##
22462289
## Modified by Martinski W. [2024-Jan-27] ##
22472290
##----------------------------------------##
@@ -2860,7 +2903,7 @@ _CurlFileDownload_()
28602903
then return 1
28612904
fi
28622905
local retCode=1
2863-
local tempFilePathDL="${2}.DL.TMP"
2906+
local tempFilePathDL="${2}.DL.$$.TMP"
28642907
local srceFilePathDL="${SCRIPT_URL_REPO}/$1"
28652908

28662909
curl -LSs --retry 4 --retry-delay 5 --retry-connrefused \
@@ -2877,7 +2920,11 @@ _CurlFileDownload_()
28772920
then updatedWebUIPage=true
28782921
else updatedWebUIPage=false
28792922
fi
2880-
mv -f "$tempFilePathDL" "$2"
2923+
if ! mv -f "$tempFilePathDL" "$2"
2924+
then
2925+
rm -f "$tempFilePathDL"
2926+
return 1
2927+
fi
28812928
retCode=0
28822929
fi
28832930

@@ -12033,7 +12080,7 @@ _DoInitializationStartup_()
1203312080
}
1203412081

1203512082
##----------------------------------------##
12036-
## Modified by Martinski W. [2025-Jul-29] ##
12083+
## Modified by Martinski W. [2026-Jun-11] ##
1203712084
##----------------------------------------##
1203812085
#######################################################################
1203912086
# TEMPORARY hack to check if the Gnuton F/W built-in 'webs_update.sh'
@@ -12052,10 +12099,9 @@ _Gnuton_Check_Webs_Update_Script_()
1205212099
return 0
1205312100
fi
1205412101

12055-
local theWebsUpdateFile="webs_update.sh"
12056-
local fixedGnutonWebsUpdateFilePath="${SETTINGS_DIR}/$theWebsUpdateFile"
12057-
local dwnldGnutonWebsUpdateFilePath="${SETTINGS_DIR}/${theWebsUpdateFile}.GNUTON"
12058-
local localVersTag remoteVersTag
12102+
local fixedGnutonWebsUpdateFilePath="${SETTINGS_DIR}/$FW_WebsUpdateFile"
12103+
local dwnldGnutonWebsUpdateFilePath="${SETTINGS_DIR}/${FW_WebsUpdateFile}.GNUTON.$$"
12104+
local localVersTag remoteVersTag diffRC mountPoint
1205912105

1206012106
# Get local VERSTAG (if any) #
1206112107
localVersTag="$(_Get_GnutonWebUpdate_ScriptVersTag_ "$FW_UpdateCheckScript")"
@@ -12064,39 +12110,119 @@ _Gnuton_Check_Webs_Update_Script_()
1206412110
# Get the fixed version of the script targeted for Gnuton F/W #
1206512111
if _CurlFileDownload_ "gnuton_webs_update.sh" "$dwnldGnutonWebsUpdateFilePath"
1206612112
then
12067-
chmod 755 "$dwnldGnutonWebsUpdateFilePath"
12113+
if ! chmod 755 "$dwnldGnutonWebsUpdateFilePath" 2>/dev/null
12114+
then
12115+
Say "${REDct}**ERROR**${NOct}: Unable to set permissions on the downloaded GNUton \"${FW_WebsUpdateFile}\" file."
12116+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12117+
return 1
12118+
fi
1206812119
remoteVersTag="$(_Get_GnutonWebUpdate_ScriptVersTag_ "$dwnldGnutonWebsUpdateFilePath")"
1206912120
[ -z "$remoteVersTag" ] && remoteVersTag=0
1207012121
else
12071-
return 1 #NOT available so do nothing#
12122+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12123+
return 1
12124+
fi
12125+
12126+
# Distinguish files that differ from an actual comparison error #
12127+
diff -q "$FW_UpdateCheckScript" "$dwnldGnutonWebsUpdateFilePath" >/dev/null 2>&1
12128+
diffRC="$?"
12129+
12130+
if [ "$diffRC" -gt 1 ]
12131+
then
12132+
Say "${REDct}**ERROR**${NOct}: Unable to compare the GNUton \"${FW_WebsUpdateFile}\" files."
12133+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12134+
return 1
1207212135
fi
1207312136

1207412137
# (Re)bind/mount only if remote is newer version OR files differ #
1207512138
if [ "$remoteVersTag" -gt "$localVersTag" ] || \
12076-
! diff -q "$FW_UpdateCheckScript" "$dwnldGnutonWebsUpdateFilePath" >/dev/null 2>&1
12139+
{ [ "$remoteVersTag" -eq "$localVersTag" ] && [ "$diffRC" -ne 0 ] ; }
1207712140
then
12078-
umount "$FW_UpdateCheckScript" 2>/dev/null
12079-
mv -f "$dwnldGnutonWebsUpdateFilePath" "$fixedGnutonWebsUpdateFilePath"
12080-
mount -o bind "$fixedGnutonWebsUpdateFilePath" "$FW_UpdateCheckScript"
12081-
Say "${YLWct}Set up a fixed version of the \"${theWebsUpdateFile}\" script file.${NOct}"
12141+
for mountPoint in $(grep "$FW_UpdateCheckScript" /proc/mounts | awk -F' ' '{print $2}')
12142+
do umount "$FW_UpdateCheckScript" 2>/dev/null
12143+
done
12144+
12145+
if grep -q "$FW_UpdateCheckScript" /proc/mounts
12146+
then
12147+
Say "${REDct}**ERROR**${NOct}: Unable to unmount \"$FW_UpdateCheckScript\"."
12148+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12149+
return 1
12150+
fi
12151+
12152+
if ! mv -f "$dwnldGnutonWebsUpdateFilePath" "$fixedGnutonWebsUpdateFilePath" 2>/dev/null
12153+
then
12154+
Say "${REDct}**ERROR**${NOct}: Unable to install the fixed GNUton \"${FW_WebsUpdateFile}\" file."
12155+
rm -f "$dwnldGnutonWebsUpdateFilePath"
12156+
return 1
12157+
fi
12158+
12159+
if [ ! -s "$fixedGnutonWebsUpdateFilePath" ]
12160+
then
12161+
Say "${REDct}**ERROR**${NOct}: GNUton \"${FW_WebsUpdateFile}\" source file is missing before bind mount."
12162+
return 1
12163+
fi
12164+
12165+
if [ ! -s "$FW_UpdateCheckScript" ]
12166+
then
12167+
Say "${REDct}**ERROR**${NOct}: Bind-mount target \"$FW_UpdateCheckScript\" does not exist."
12168+
return 1
12169+
fi
12170+
12171+
if ! mount -o bind "$fixedGnutonWebsUpdateFilePath" "$FW_UpdateCheckScript"
12172+
then
12173+
Say "${REDct}**ERROR**${NOct}: Unable to bind-mount the fixed GNUton \"${FW_WebsUpdateFile}\" file."
12174+
return 1
12175+
fi
12176+
Say "${YLWct}Set up a fixed version of the \"${FW_WebsUpdateFile}\" script file.${NOct}"
1208212177
else
1208312178
rm -f "$dwnldGnutonWebsUpdateFilePath"
1208412179
fi
12180+
return 0
12181+
}
12182+
12183+
##----------------------------------------##
12184+
## Modified by Martinski W. [2026-Jun-11] ##
12185+
##----------------------------------------##
12186+
# Startup/Initialization operations done by possible concurrent processes #
12187+
_RunLockedInitializationChecks_()
12188+
{
12189+
local retCode=0
12190+
12191+
if ! _CleanUpOldLogFiles_
12192+
then
12193+
Say "${YLWct}WARNING:${NOct} Unable to clean up old firmware-update log files."
12194+
retCode=1
12195+
fi
12196+
12197+
# Set variable to 'false' to stop the check #
12198+
checkWebsUpdateScriptForGnuton="$isGNUtonFW"
12199+
if ! _Gnuton_Check_Webs_Update_Script_
12200+
then
12201+
Say "${YLWct}WARNING:${NOct} Unable to check or install the GNUton \"${FW_WebsUpdateFile}\" patch."
12202+
retCode=1
12203+
fi
12204+
12205+
return "$retCode"
1208512206
}
1208612207

1208712208
if [ "$SCRIPT_BRANCH" = "master" ]
1208812209
then SCRIPT_VERS_INFO=""
1208912210
else SCRIPT_VERS_INFO="[$versionDev_TAG]"
1209012211
fi
1209112212

12092-
## Set variable to 'false' to stop the check ##
12093-
checkWebsUpdateScriptForGnuton="$isGNUtonFW"
12094-
_Gnuton_Check_Webs_Update_Script_
12095-
1209612213
FW_InstalledVersion="$(_GetCurrentFWInstalledLongVersion_)"
1209712214
FW_InstalledVerStr="${GRNct}${FW_InstalledVersion}${NOct}"
1209812215
FW_NewUpdateVerInit=TBD
1209912216

12217+
if _AcquireInitMutexFLock_
12218+
then
12219+
_RunLockedInitializationChecks_
12220+
_ReleaseInitMutexFLock_
12221+
else
12222+
Say "${REDct}**ERROR**${NOct}: Unable to acquire the initialization lock. Exiting..."
12223+
exit 1
12224+
fi
12225+
1210012226
##----------------------------------------##
1210112227
## Modified by Martinski W. [2025-Apr-07] ##
1210212228
##----------------------------------------##
@@ -12132,7 +12258,8 @@ fi
1213212258
if [ $# -gt 0 ]
1213312259
then
1213412260
if ! _AcquireLock_ cliOptsLock
12135-
then Say "Exiting..." ; exit 1 ; fi
12261+
then Say "Exiting..." ; exit 1
12262+
fi
1213612263

1213712264
[ "$1" = "amtmupdate" ] && isVerbose=false
1213812265

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# MerlinAU - AsusWRT-Merlin Firmware Auto Updater
22

3-
## v1.6.3
4-
## 2026-May-22
3+
## v1.6.4
4+
## 2026-June-21
55

66
## WebUI:
77
<img width="775" height="1640" alt="image" src="https://github.com/user-attachments/assets/846f889b-b39f-4ffe-a37a-8892ad9b2f7f" />

‎version.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.6.3
1+
1.6.4

0 commit comments

Comments
 (0)