99set -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=" 26061019 "
1414readonly SCRIPT_NAME=" MerlinAU"
1515# # Set to "master" for Production Releases ##
1616SCRIPT_BRANCH=" master"
@@ -546,6 +546,12 @@ fwupMutexFLock_FD=576
546546fwupMutexFLock_FN=" /tmp/var/${ScriptFNameTag} _FW_Update.FLock"
547547fwupMutexFLock_OK=false # DO NOT have FLock#
548548
549+ # #-------------------------------------##
550+ # # Added for initialization operations ##
551+ # #-------------------------------------##
552+ initMutexFLock_FD=577
553+ initMutexFLock_FN=" /tmp/var/${ScriptFNameTag} _Initialization.FLock"
554+
549555_ReleaseMutexFLock_ ()
550556{
551557 if [ $# -gt 0 ] && \
@@ -2217,30 +2223,45 @@ readonly POST_REBOOT_SCRIPT_HOOK="[ -x $ScriptFilePath ] && $POST_REBOOT_SCRIPT_
22172223readonly POST_UPDATE_EMAIL_SCRIPT_JOB=" $ScriptFilePath postUpdateEmail &"
22182224readonly POST_UPDATE_EMAIL_SCRIPT_HOOK=" [ -x $ScriptFilePath ] && $POST_UPDATE_EMAIL_SCRIPT_JOB $hookScriptTagStr "
22192225
2220- # #-------------------------------------##
2221- # # Added by Martinski W. [2026-Feb-07 ] ##
2222- # #-------------------------------------##
2226+ # #------------------------------------------ ##
2227+ # # Modified by ExtremeFiretop [2026-Jun-10 ] ##
2228+ # #------------------------------------------ ##
22232229_CleanUpOldLogFiles_ ()
22242230{
22252231 [ ! -d " $FW_LOG_DIR " ] && return 1
2226- local numLogFiles topLogFile
2232+ local numLogFiles topFile savedTopFile
22272233
22282234 numLogFiles=" $( ls -1lt " $FW_LOG_DIR " /* .log 2> /dev/null | wc -l) "
22292235 # Leave one log file (if any available) #
22302236 [ " $numLogFiles " -lt 2 ] && return 0
22312237
22322238 # Save the most recent log file #
22332239 topFile=" $( ls -1t " $FW_LOG_DIR " /* .log 2> /dev/null | head -n1) "
2234- [ -n " $topFile " ] && mv -f " $topFile " " ${topFile} .SAVED.TEMP.LOG"
2240+
2241+ if [ -n " $topFile " ]
2242+ then
2243+ savedTopFile=" ${topFile} .SAVED.$$ .TEMP.LOG"
2244+
2245+ if ! mv -f " $topFile " " $savedTopFile "
2246+ then
2247+ return 1
2248+ fi
2249+ fi
22352250
22362251 # Delete logs older than 30 days #
22372252 /usr/bin/find -L " $FW_LOG_DIR " -name ' *.log' -mtime +30 -exec rm {} \;
22382253
22392254 # Restore the most recent log file #
2240- [ -n " $topFile " ] && mv -f " ${topFile} .SAVED.TEMP.LOG" " $topFile "
2241- }
2255+ if [ -n " $topFile " ] && [ -f " $savedTopFile " ]
2256+ then
2257+ if ! mv -f " $savedTopFile " " $topFile "
2258+ then
2259+ return 1
2260+ fi
2261+ fi
22422262
2243- _CleanUpOldLogFiles_
2263+ return 0
2264+ }
22442265
22452266# #----------------------------------------##
22462267# # Modified by Martinski W. [2024-Jan-27] ##
@@ -2860,7 +2881,7 @@ _CurlFileDownload_()
28602881 then return 1
28612882 fi
28622883 local retCode=1
2863- local tempFilePathDL=" ${2} .DL.TMP"
2884+ local tempFilePathDL=" ${2} .DL.$$ . TMP"
28642885 local srceFilePathDL=" ${SCRIPT_URL_REPO} /$1 "
28652886
28662887 curl -LSs --retry 4 --retry-delay 5 --retry-connrefused \
@@ -2877,7 +2898,11 @@ _CurlFileDownload_()
28772898 then updatedWebUIPage=true
28782899 else updatedWebUIPage=false
28792900 fi
2880- mv -f " $tempFilePathDL " " $2 "
2901+ if ! mv -f " $tempFilePathDL " " $2 "
2902+ then
2903+ rm -f " $tempFilePathDL "
2904+ return 1
2905+ fi
28812906 retCode=0
28822907 fi
28832908
@@ -12032,9 +12057,9 @@ _DoInitializationStartup_()
1203212057 _SetDefaultBuildType_
1203312058}
1203412059
12035- # #----------------------------------------##
12036- # # Modified by Martinski W. [2025-Jul-29 ] ##
12037- # #----------------------------------------##
12060+ # #------------------------------------------ ##
12061+ # # Modified by ExtremeFiretop [2026-Jun-10 ] ##
12062+ # #------------------------------------------ ##
1203812063# ######################################################################
1203912064# TEMPORARY hack to check if the Gnuton F/W built-in 'webs_update.sh'
1204012065# script is the most recent version that includes required fixes.
@@ -12054,8 +12079,8 @@ _Gnuton_Check_Webs_Update_Script_()
1205412079
1205512080 local theWebsUpdateFile=" webs_update.sh"
1205612081 local fixedGnutonWebsUpdateFilePath=" ${SETTINGS_DIR} /$theWebsUpdateFile "
12057- local dwnldGnutonWebsUpdateFilePath=" ${SETTINGS_DIR} /${theWebsUpdateFile} .GNUTON"
12058- local localVersTag remoteVersTag
12082+ local dwnldGnutonWebsUpdateFilePath=" ${SETTINGS_DIR} /${theWebsUpdateFile} .GNUTON. $$ "
12083+ local localVersTag remoteVersTag diffRC
1205912084
1206012085 # Get local VERSTAG (if any) #
1206112086 localVersTag=" $( _Get_GnutonWebUpdate_ScriptVersTag_ " $FW_UpdateCheckScript " ) "
@@ -12064,35 +12089,137 @@ _Gnuton_Check_Webs_Update_Script_()
1206412089 # Get the fixed version of the script targeted for Gnuton F/W #
1206512090 if _CurlFileDownload_ " gnuton_webs_update.sh" " $dwnldGnutonWebsUpdateFilePath "
1206612091 then
12067- chmod 755 " $dwnldGnutonWebsUpdateFilePath "
12092+ if ! chmod 755 " $dwnldGnutonWebsUpdateFilePath "
12093+ then
12094+ Say " ${REDct} **ERROR**${NOct} : Unable to set permissions on the downloaded GNUton webs_update.sh file."
12095+ rm -f " $dwnldGnutonWebsUpdateFilePath "
12096+ return 1
12097+ fi
12098+
1206812099 remoteVersTag=" $( _Get_GnutonWebUpdate_ScriptVersTag_ " $dwnldGnutonWebsUpdateFilePath " ) "
1206912100 [ -z " $remoteVersTag " ] && remoteVersTag=0
1207012101 else
12071- return 1 # NOT available so do nothing#
12102+ rm -f " $dwnldGnutonWebsUpdateFilePath "
12103+ return 1
12104+ fi
12105+
12106+ # Distinguish files that differ from an actual comparison error.
12107+ diff -q " $FW_UpdateCheckScript " " $dwnldGnutonWebsUpdateFilePath " > /dev/null 2>&1
12108+
12109+ diffRC=$?
12110+
12111+ if [ " $diffRC " -gt 1 ]
12112+ then
12113+ Say " ${REDct} **ERROR**${NOct} : Unable to compare the GNUton webs_update.sh files."
12114+ rm -f " $dwnldGnutonWebsUpdateFilePath "
12115+ return 1
1207212116 fi
1207312117
1207412118 # (Re)bind/mount only if remote is newer version OR files differ #
1207512119 if [ " $remoteVersTag " -gt " $localVersTag " ] || \
12076- ! diff -q " $FW_UpdateCheckScript " " $dwnldGnutonWebsUpdateFilePath " > /dev/null 2>&1
12120+ [ " $diffRC " -eq 1 ]
1207712121 then
12078- umount " $FW_UpdateCheckScript " 2> /dev/null
12079- mv -f " $dwnldGnutonWebsUpdateFilePath " " $fixedGnutonWebsUpdateFilePath "
12080- mount -o bind " $fixedGnutonWebsUpdateFilePath " " $FW_UpdateCheckScript "
12122+ # Remove all existing bind-mount layers, including duplicates.
12123+ while awk -v target=" $FW_UpdateCheckScript " '
12124+ $2 == target { found=1 }
12125+ END { exit !found }
12126+ ' /proc/mounts
12127+ do
12128+ if ! umount " $FW_UpdateCheckScript "
12129+ then
12130+ Say " ${REDct} **ERROR**${NOct} : Unable to unmount \" $FW_UpdateCheckScript \" ."
12131+ rm -f " $dwnldGnutonWebsUpdateFilePath "
12132+ return 1
12133+ fi
12134+ done
12135+
12136+ if ! mv -f " $dwnldGnutonWebsUpdateFilePath " " $fixedGnutonWebsUpdateFilePath "
12137+ then
12138+ Say " ${REDct} **ERROR**${NOct} : Unable to install the fixed GNUton webs_update.sh file."
12139+ rm -f " $dwnldGnutonWebsUpdateFilePath "
12140+ return 1
12141+ fi
12142+
12143+ if [ ! -f " $fixedGnutonWebsUpdateFilePath " ]
12144+ then
12145+ Say " ${REDct} **ERROR**${NOct} : GNUton webs_update.sh source file is missing before bind mount."
12146+ return 1
12147+ fi
12148+
12149+ if [ ! -e " $FW_UpdateCheckScript " ]
12150+ then
12151+ Say " ${REDct} **ERROR**${NOct} : Bind-mount target \" $FW_UpdateCheckScript \" does not exist."
12152+ return 1
12153+ fi
12154+
12155+ if ! mount -o bind \
12156+ " $fixedGnutonWebsUpdateFilePath " \
12157+ " $FW_UpdateCheckScript "
12158+ then
12159+ Say " ${REDct} **ERROR**${NOct} : Unable to bind-mount the fixed GNUton webs_update.sh file."
12160+ return 1
12161+ fi
12162+
1208112163 Say " ${YLWct} Set up a fixed version of the \" ${theWebsUpdateFile} \" script file.${NOct} "
1208212164 else
1208312165 rm -f " $dwnldGnutonWebsUpdateFilePath "
1208412166 fi
12167+
12168+ return 0
1208512169}
1208612170
12171+ # #---------------------------------------##
12172+ # # Added by ExtremeFiretop [2026-Jun-10] ##
12173+ # #---------------------------------------##
12174+ # Serialize startup-time operations that use shared log and GNUton files.
12175+ _RunLockedInitializationChecks_ ()
12176+ {
12177+ local retCode=0
12178+
12179+ [ ! -d /tmp/var ] && mkdir -p /tmp/var
12180+
12181+ # Open the dedicated lock file on its own file descriptor.
12182+ if ! eval " exec ${initMutexFLock_FD} >\" ${initMutexFLock_FN} \" "
12183+ then
12184+ Say " ${REDct} **ERROR**${NOct} : Unable to open the initialization lock file."
12185+ return 1
12186+ fi
12187+
12188+ # Use a blocking exclusive lock so concurrent MerlinAU processes wait.
12189+ if ! flock -x " $initMutexFLock_FD " 2> /dev/null
12190+ then
12191+ Say " ${REDct} **ERROR**${NOct} : Unable to acquire the initialization lock."
12192+ eval " exec ${initMutexFLock_FD} >&-"
12193+ return 1
12194+ fi
12195+
12196+ # These operations access shared paths and must not overlap.
12197+ if [ -d " $FW_LOG_DIR " ] && \
12198+ ! _CleanUpOldLogFiles_
12199+ then
12200+ Say " ${YLWct} WARNING:${NOct} Unable to clean up old firmware-update log files."
12201+ retCode=1
12202+ fi
12203+
12204+ checkWebsUpdateScriptForGnuton=" $isGNUtonFW "
12205+ if ! _Gnuton_Check_Webs_Update_Script_
12206+ then
12207+ Say " ${YLWct} WARNING:${NOct} Unable to check or install the GNUton webs_update.sh patch."
12208+ retCode=1
12209+ fi
12210+
12211+ flock -u " $initMutexFLock_FD " 2> /dev/null
12212+ eval " exec ${initMutexFLock_FD} >&-"
12213+
12214+ return " $retCode "
12215+ }
12216+
12217+
1208712218if [ " $SCRIPT_BRANCH " = " master" ]
1208812219then SCRIPT_VERS_INFO=" "
1208912220else SCRIPT_VERS_INFO=" [$versionDev_TAG ]"
1209012221fi
1209112222
12092- # # Set variable to 'false' to stop the check ##
12093- checkWebsUpdateScriptForGnuton=" $isGNUtonFW "
12094- _Gnuton_Check_Webs_Update_Script_
12095-
1209612223FW_InstalledVersion=" $( _GetCurrentFWInstalledLongVersion_) "
1209712224FW_InstalledVerStr=" ${GRNct}${FW_InstalledVersion}${NOct} "
1209812225FW_NewUpdateVerInit=TBD
@@ -12107,6 +12234,8 @@ then
1210712234 then Say " Exiting..." ; exit 1
1210812235 fi
1210912236
12237+ _RunLockedInitializationChecks_
12238+
1211012239 inMenuMode=true
1211112240 _DoInitializationStartup_
1211212241 _CheckFor_VersionFile_
@@ -12134,6 +12263,8 @@ then
1213412263 if ! _AcquireLock_ cliOptsLock
1213512264 then Say " Exiting..." ; exit 1 ; fi
1213612265
12266+ _RunLockedInitializationChecks_
12267+
1213712268 [ " $1 " = " amtmupdate" ] && isVerbose=false
1213812269
1213912270 inMenuMode=false
0 commit comments