diff --git a/MerlinAU.sh b/MerlinAU.sh index 422b0425..531b3793 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,7 +4,7 @@ # # Project Created: 2023-Oct-01 by @ExtremeFiretop # Official Co-Author: @Martinski W. since 2023-Nov-01 -# Last Modified: 2026-Aug-27 +# Last Modified: 2026-Sep-03 # # MerlinAUā„¢ / MerlinAutoUpdateā„¢ # Official project: https://github.com/ExtremeFiretop/MerlinAutoUpdate-Router @@ -20,7 +20,7 @@ set -u ## Set version for each Production Release ## readonly SCRIPT_VERSION=1.6.7 -readonly SCRIPT_VERSTAG="26082409" +readonly SCRIPT_VERSTAG="26090309" readonly SCRIPT_NAME="MerlinAU" ## Set to "master" for Production Releases ## SCRIPT_BRANCH="dev" @@ -37,7 +37,7 @@ readonly FW_SFURL_BASE="https://sourceforge.net/projects/asuswrt-merlin/files" readonly FW_SFURL_RELEASE_SUFFIX="Release" readonly FW_GITURL_RELEASE="https://api.github.com/repos/gnuton/asuswrt-merlin.ng/releases/latest" readonly FW_SHA256_URL="https://www.asuswrt-merlin.net/download" -# The scheduled checksum mirror is maintained on the repository's default branch. # +# The scheduled checksum mirror is maintained on the repository's default branch # readonly FW_SHA256_MIRROR_URL="${SCRIPT_URL_BASE}/main/merlin-sha256.txt" ##----------------------------------------## @@ -103,6 +103,7 @@ readonly versionDev_TAG="${SCRIPT_VERSION}_${SCRIPT_VERSTAG}" ##----------------------------------------## ## Modified by Martinski W. [2025-Jan-15] ## ##----------------------------------------## +readonly TEMP_DIR="/tmp/var/tmp" readonly ADDONS_PATH="/jffs/addons" readonly SCRIPTS_PATH="/jffs/scripts" readonly SETTINGS_DIR="${ADDONS_PATH}/$ScriptDirNameD" @@ -124,6 +125,9 @@ readonly TEMPFILE="/tmp/MerlinAU_settings_$$.txt" readonly webPageFileRegExp="user([1-9]|[1-2][0-9])[.]asp" readonly webPageLineTabExp="\{url: \"$webPageFileRegExp\", tabName: " readonly webPageLineRegExp="${webPageLineTabExp}\"$SCRIPT_NAME\"\}," +readonly curlHTTPstatusStr="HTTP/S_Status_Code" +readonly curlTmpLogFile="${TEMP_DIR}/tmpCurl_${ScriptFNameTag}_$$.TMP.LOG" +readonly curlErrLogFile="${TEMP_DIR}/tmpCurl_${ScriptFNameTag}_$$.ERR.LOG" # Give FIRST priority to built-in binaries over any other # export PATH="/bin:/usr/bin:/sbin:/usr/sbin:$PATH" @@ -169,9 +173,9 @@ readonly FW_UpdateEMailNotificationDefault=DISABLED readonly amtmMailDirPath="/jffs/addons/amtm/mail" readonly amtmMailConfFile="${amtmMailDirPath}/email.conf" readonly amtmMailPswdFile="${amtmMailDirPath}/emailpw.enc" -readonly tempEMailContent="/tmp/var/tmp/tempEMailContent.$$.TXT" -readonly tempNodeEMailList="/tmp/var/tmp/tempNodeEMailList.$$.TXT" -readonly tempEMailBodyMsg="/tmp/var/tmp/tempEMailBodyMsg.$$.TXT" +readonly tempEMailContent="${TEMP_DIR}/tempEMailContent.$$.TXT" +readonly tempEMailBodyMsg="${TEMP_DIR}/tempEMailBodyMsg.$$.TXT" +readonly tempNodeEMailList="${TEMP_DIR}/tempNodeEMailList.$$.TXT" readonly saveEMailInfoMsg="${SETTINGS_DIR}/savedEMailInfoMsg.SAVE.TXT" readonly theEMailDateTimeFormat="%Y-%b-%d %a %I:%M:%S %p %Z" @@ -356,7 +360,7 @@ _UserLogMsg_() DoPrintf() { if "$isInteractive" && "$isVerbose" - then printf "$@" + then printf "$1" fi } @@ -593,9 +597,9 @@ _ReleaseMutexFLock_() [ "$fwupMutexFLock_OK" != "true" ] then return 0 fi - printf '' > "$fwupMutexFLock_FN" flock -u "$fwupMutexFLock_FD" 2>/dev/null + eval exec "${fwupMutexFLock_FD}>&-" fwupMutexFLock_OK=false } @@ -631,9 +635,7 @@ _AcquireMutexFLock_() fi fi - [ ! -s "$fwupMutexFLock_FN" ] && \ eval exec "$fwupMutexFLock_FD>$fwupMutexFLock_FN" - if flock -x -n "$fwupMutexFLock_FD" 2>/dev/null then printf "$(basename "$0")|$$\n" > "$fwupMutexFLock_FN" @@ -2917,18 +2919,26 @@ _CurlFileDownload_() if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ] then return 1 fi - local retCode=1 local tempFilePathDL="${2}.DL.$$.TMP" - local srceFilePathDL="${SCRIPT_URL_REPO}/$1" + local srceFilePathURL="${SCRIPT_URL_REPO}/$1" + local curlRetCode returnCODE statusSTRx httpStatusSTR - curl -LSs --retry 4 --retry-delay 5 --retry-connrefused \ - "$srceFilePathDL" -o "$tempFilePathDL" - if [ $? -ne 0 ] || [ ! -s "$tempFilePathDL" ] || \ - grep -iq "^404: Not Found" "$tempFilePathDL" + rm -f "$tempFilePathDL" + printf '' > "$curlErrLogFile" ; printf '' > "$curlTmpLogFile" + + curl -LSs --retry 3 --retry-delay 5 --retry-connrefused \ + --connect-timeout 30 --max-time 60 \ + -w "${curlHTTPstatusStr}: %{http_code}\n" --stderr "$curlErrLogFile" \ + "$srceFilePathURL" --output "$tempFilePathDL" >> "$curlTmpLogFile" + curlRetCode="$?" + + returnCODE="$curlRetCode" + statusSTRx="Curl Status Code: $curlRetCode" + httpStatusSTR="$(grep -oE "${curlHTTPstatusStr}: [4-5][0-9]{2,}" "$curlTmpLogFile")" + + if [ "$curlRetCode" -eq 0 ] && \ + [ -z "$httpStatusSTR" ] && [ -s "$tempFilePathDL" ] then - rm -f "$tempFilePathDL" - retCode=1 - else if [ "$1" = "$SCRIPT_WEB_ASP_FILE" ] && \ [ -f "$2" ] && [ -f "$TEMP_MENU_TREE" ] && \ ! diff -q "$tempFilePathDL" "$2" >/dev/null 2>&1 @@ -2937,13 +2947,24 @@ _CurlFileDownload_() fi if ! mv -f "$tempFilePathDL" "$2" then + returnCODE=111 rm -f "$tempFilePathDL" - return 1 fi - retCode=0 + else + if [ "$curlRetCode" -eq 0 ] && [ -n "$httpStatusSTR" ] + then + returnCODE="$(echo "$httpStatusSTR" | awk -F' ' '{print $2}')" + statusSTRx="HTTP/S Status Code: $returnCODE" + fi + if [ -s "$curlErrLogFile" ] && "$isInteractive" + then echo ; cat "$curlErrLogFile" + fi + Say "${REDct}**ERROR**${NOct}: Unable to download the file [$2] [${MGNTct}${statusSTRx}${NOct}]" + rm -f "$tempFilePathDL" fi - return "$retCode" + rm -f "$curlErrLogFile" "$curlTmpLogFile" + return "$returnCODE" } ##----------------------------------------## @@ -2966,9 +2987,12 @@ _DownloadScriptFiles_() retCode=1 Say "${REDct}**ERROR**${NOct}: Unable to download latest version file for $SCRIPT_NAME." fi + if "$mountWebGUI_OK" && \ _CurlFileDownload_ "$SCRIPT_WEB_ASP_FILE" "$SCRIPT_WEB_ASP_PATH" then + retCode=0 + dos2unix "$SCRIPT_WEB_ASP_PATH" chmod 664 "$SCRIPT_WEB_ASP_PATH" if "$updatedWebUIPage" then @@ -2981,15 +3005,17 @@ _DownloadScriptFiles_() fi "$isUpdateAction" && _Mount_WebUI_ fi - retCode=0 elif "$mountWebGUI_OK" then retCode=1 Say "${REDct}**ERROR**${NOct}: Unable to download latest WebUI ASP file for $SCRIPT_NAME." fi + if _CurlFileDownload_ "${SCRIPT_NAME}.sh" "$ScriptFilePath" then - retCode=0 ; chmod 755 "$ScriptFilePath" + retCode=0 + dos2unix "$ScriptFilePath" + chmod 755 "$ScriptFilePath" else retCode=1 Say "${REDct}**ERROR**${NOct}: Unable to download latest script file for $SCRIPT_NAME." @@ -3098,7 +3124,7 @@ _SCRIPT_UPDATE_() if ! _CheckNewScriptMinFWBeforeUpdate_ then _WriteVarDefToHelperJSFile_ "minimumScriptFWRequired" "$NewMinSupportedFirmwareVers" - printf "\n${CRITct}*WARNING*:${NOct} MerlinAU v${DLRepoVersion} " + printf "\n${CRITct}*WARNING*${NOct}: MerlinAU v${DLRepoVersion} " printf "requires a newer router firmware version.\n" printf "\nCurrent F/W version found: ${REDct}%s${NOct}" "$current_version" printf "\nMinimum version supported: ${GRNct}%s${NOct}\n" "$NewMinSupportedFirmwareVers" @@ -3172,7 +3198,7 @@ _SCRIPT_UPDATE_() if ! _CheckNewScriptMinFWBeforeUpdate_ then _WriteVarDefToHelperJSFile_ "minimumScriptFWRequired" "$NewMinSupportedFirmwareVers" - printf "\n${CRITct}*WARNING*:${NOct} MerlinAU v${DLRepoVersion} " + printf "\n${CRITct}*WARNING*${NOct}: MerlinAU v${DLRepoVersion} " printf "requires a newer router firmware version.\n" printf "\nCurrent F/W version found: ${REDct}%s${NOct}" "$current_version" printf "\nMinimum version supported: ${GRNct}%s${NOct}\n" "$NewMinSupportedFirmwareVers" @@ -3271,7 +3297,7 @@ ScriptUpdateFromAMTM() ##----------------------------------------## _CheckForNewScriptUpdates_() { - local verStr DLScriptVerPath="${SCRIPT_VERPATH}.DL.tmp" + local verStr DLScriptVerPath="${SCRIPT_VERPATH}.DL.TMP" echo DLRepoVersion="$SCRIPT_VERSION" if [ -s "$SCRIPT_VERPATH" ] @@ -4909,7 +4935,7 @@ _GetPasswordInput_() local newPSWDtmpStr PSWDprompt showPSWD local retCode charNum newPSWDlength # For more responsive TAB keypress debounce # - local tabKeyDebounceSem="/tmp/var/tmp/${ScriptFNameTag}_TabKeySEM.txt" + local tabKeyDebounceSem="${TEMP_DIR}/${ScriptFNameTag}_TabKeySEM.txt" if [ $# -eq 0 ] || [ -z "$1" ] then @@ -5858,7 +5884,6 @@ _DownloadForMerlin_() wget --tries=5 --waitretry=5 --retry-connrefused \ -O "$FW_ZIP_FPATH" "$release_link" - # Check if the file was downloaded successfully # if [ ! -s "$FW_ZIP_FPATH" ] then return 1 else return 0 @@ -5957,7 +5982,7 @@ _CopyGnutonFiles_() if "$copy_attempted" && "$copy_success" then #---------------------------------------------------------------# - # Check if Gntuon file was downloaded to a USB-attached drive. + # Check if Gnuton file was downloaded to a USB-attached drive. # Take into account special case for Entware "/opt/" paths. #---------------------------------------------------------------# if ! echo "$FW_DL_FPATH" | grep -qE "^(/tmp/mnt/|/tmp/opt/|/opt/)" @@ -5984,9 +6009,6 @@ _CopyGnutonFiles_() return 0 } -##------------------------------------------## -## Modified by ExtremeFiretop [2026-Aug-24] ## -##------------------------------------------## ##------------------------------------------## ## Modified by ExtremeFiretop [2026-Aug-24] ## ##------------------------------------------## @@ -5995,9 +6017,11 @@ _GetFirmwareSHA256FromList_() local checksumList="$1" local firmwareName="$2" - # Return a checksum only when there is exactly one exact filename match - # and its digest is a syntactically valid SHA256 value. Using awk avoids - # treating firmware filenames as regular expressions. + #-------------------------------------------------------------------# + # Return a checksum ONLY when there is exactly one filename match + # and its digest is a valid SHA256 value. Using awk avoids + # treating the firmware image filenames as regular expressions. + #-------------------------------------------------------------------# printf '%s\n' "$checksumList" | awk -v firmwareName="$firmwareName" ' $2 == firmwareName && length($1) == 64 && $1 !~ /[^0-9A-Fa-f]/ { matchCount++ @@ -6009,13 +6033,61 @@ _GetFirmwareSHA256FromList_() }' } +##-------------------------------------## +## Added by Martinski W. [2026-Sep-03] ## +##-------------------------------------## +_GetChecksumsFromRMerlinWebsite_() +{ + local curlRetCode returnCODE statusSTRx httpStatusSTR + local outTempFPathDL="${TEMP_DIR}/SHA256_SIGS_DL_$$.TMP" + + theChecksums="" + rm -f "$outTempFPathDL" + printf '' > "$curlErrLogFile" ; printf '' > "$curlTmpLogFile" + + curl -LSs --retry 3 --retry-delay 5 --retry-connrefused \ + --connect-timeout 30 --max-time 60 \ + -w "${curlHTTPstatusStr}: %{http_code}\n" --stderr "$curlErrLogFile" \ + "$FW_SHA256_URL" --output "$outTempFPathDL" >> "$curlTmpLogFile" + curlRetCode="$?" + + returnCODE="$curlRetCode" + statusSTRx="Curl Status Code: $curlRetCode" + httpStatusSTR="$(grep -oE "${curlHTTPstatusStr}: [4-5][0-9]{2,}" "$curlTmpLogFile")" + + if [ "$curlRetCode" -eq 0 ] && \ + [ -z "$httpStatusSTR" ] && [ -s "$outTempFPathDL" ] + then + theChecksums="$(cat "$outTempFPathDL" | \ + sed -n '/<.*>SHA256 signatures:<\/.*>/,/<\/pre>/p' | \ + sed -n '/]*>/,/<\/pre>/p' | \ + sed -e 's/^.*]*>// ; s/<[^>]*>//g' | \ + sed -e 's/^[[:space:]]*//g' | \ + sed -e 's/[[:space:]]*$//g' | \ + sed -e '/^[[:space:]]*$/d' | tr -d '\r')" + else + if [ "$curlRetCode" -eq 0 ] && [ -n "$httpStatusSTR" ] + then + returnCODE="$(echo "$httpStatusSTR" | awk -F' ' '{print $2}')" + statusSTRx="HTTP/S Status Code: $returnCODE" + fi + if [ -s "$curlErrLogFile" ] && "$isInteractive" + then echo ; cat "$curlErrLogFile" + fi + Say "${MGNTct}*WARNING*${NOct}: Unable to download the SHA256 checksum signature list from the ASUSWRT-Merlin website [${MGNTct}${statusSTRx}${NOct}]" + fi + + rm -f "$curlErrLogFile" "$curlTmpLogFile" "$outTempFPathDL" + return "$returnCODE" +} + +##----------------------------------------## +## Modified by Martinski W. [2026-Sep-03] ## +##----------------------------------------## _CheckOnlineFirmwareSHA256_() { - local checksums="" - local dl_sig="" - local fw_name="" - local fw_sig="" - local checksumSource="" + local fw_name fw_sig dl_sig="" + local theChecksums="" checksumSource="" if [ ! -f "$firmware_file" ] then @@ -6027,59 +6099,65 @@ _CheckOnlineFirmwareSHA256_() fw_name="$(basename "$firmware_file")" fw_sig="$(openssl sha256 "$firmware_file" | awk -F ' ' '{print tolower($2)}')" - # PRIMARY: Fetch the checksum directly from the ASUSWRT-Merlin website. - checksums="$(curl -Lfs --retry 4 --retry-delay 5 --retry-connrefused \ - "$FW_SHA256_URL" 2>/dev/null | - sed -n '/<.*>SHA256 signatures:<\/.*>/,/<\/pre>/p' | - sed -n '/]*>/,/<\/pre>/p' | - sed -e 's/<[^>]*>//g; s/^[[:space:]]*//; s/[[:space:]]*$//')" + #-----------------------------------------------------------------------# + # PRIMARY SOURCE: Fetch directly from ASUSWRT-Merlin official website. + # RMerlin's website host has a tendency to ban whole countries from + # accessing the server so we'll do more error checking & reporting + # to show when that happens so users become aware of the situation. + #-----------------------------------------------------------------------# + _GetChecksumsFromRMerlinWebsite_ - if [ -n "$checksums" ] + if [ -n "$theChecksums" ] then - dl_sig="$(_GetFirmwareSHA256FromList_ "$checksums" "$fw_name")" + dl_sig="$(_GetFirmwareSHA256FromList_ "$theChecksums" "$fw_name")" fi if [ -n "$dl_sig" ] then checksumSource="ASUSWRT-Merlin website" else - Say "${YLWct}**WARNING**${NOct}: Independently published checksum could not be retrieved from the ASUSWRT-Merlin website." - - # SECONDARY: Use the repository mirror only when the official source - # did not yield a usable checksum. Never use the checksum bundled in - # the firmware archive for an online update. - checksums="$(curl -Lfs --retry 4 --retry-delay 5 --retry-connrefused \ + Say "${MGNTct}*WARNING*${NOct}: Independently published checksum signature could NOT be retrieved from the ASUSWRT-Merlin website." + + #-----------------------------------------------------------------------# + # SECONDARY SOURCE: Use the repository mirror ONLY when the official + # source did NOT yield a usable checksum. Never use a checksum bundled + # with the firmware image in the ZIP archive for an online F/W update. + #-----------------------------------------------------------------------# + theChecksums="$(curl -Lfs --retry 3 --retry-delay 5 --retry-connrefused \ + --connect-timeout 30 --max-time 60 \ "$FW_SHA256_MIRROR_URL" 2>/dev/null)" - if [ -n "$checksums" ] + if [ -n "$theChecksums" ] then - dl_sig="$(_GetFirmwareSHA256FromList_ "$checksums" "$fw_name")" + dl_sig="$(_GetFirmwareSHA256FromList_ "$theChecksums" "$fw_name")" fi if [ -z "$dl_sig" ] then - Say "${REDct}**ERROR**${NOct}: No unique valid SHA256 signature for ${fw_name} was available from either independent online source." - Say "Online firmware update was aborted; bundled archive checksum fallback is intentionally disabled." + Say "${REDct}**ERROR**${NOct}: No unique and valid SHA256 checksum signature for ${fw_name} was available from either independent online source." + Say "Online firmware update was aborted. Bundled archive checksum fallback is intentionally disabled." _DoCleanUp_ 1 _SendEMailNotification_ FAILED_FW_CHECKSUM_STATUS return 1 fi - checksumSource="MerlinAU GitHub checksum mirror" - Say "${YLWct}**WARNING**${NOct}: Using the MerlinAU GitHub checksum mirror for verification. (15 MINUTE DELAY!)" + checksumSource="MerlinAU GitHub repository mirror" + Say "${MGNTct}*WARNING*${NOct}: Using the MerlinAU GitHub checksum mirror for verification (15-MINUTE Update Intervals!)" fi - # If the primary source supplied a checksum but it mismatches, this fails - # immediately. The mirror is never used to bypass a checksum mismatch. + #--------------------------------------------------------------------------# + # If the PRIMARY source supplied a checksum but it's a mismatch, it fails + # immediately. The mirror must NOT be used to bypass a checksum mismatch. + #--------------------------------------------------------------------------# if [ "$fw_sig" != "$dl_sig" ] then - Say "${REDct}**ERROR**${NOct}: SHA256 signature from extracted firmware file does not match the SHA256 signature from the ${checksumSource}." + Say "${REDct}**ERROR**${NOct}: SHA256 signature from extracted firmware file does NOT match the SHA256 signature from the ${checksumSource}." _DoCleanUp_ 1 _SendEMailNotification_ FAILED_FW_CHECKSUM_STATUS return 1 fi - Say "SHA256 signature check for firmware image file passed successfully using the ${checksumSource}." + Say "SHA256 signature check for firmware image file passed successfully [source: ${checksumSource}]" return 0 } @@ -6414,7 +6492,7 @@ _Approve_FW_Update_() if [ "$currentSetting" = "BLOCKED" ] then - printf "${REDct}*WARNING*:${NOct} Found high-risk phrases in the changelog file.\n" + printf "${REDct}*WARNING*${NOct}: Found high-risk phrases in the changelog file.\n" printf "The advice is to approve if you've read the firmware changelog and you want to proceed with the update.\n" if _WaitForYESorNO_ "Do you want to ${GRNct}APPROVE${NOct} the latest firmware update?" @@ -6426,7 +6504,7 @@ _Approve_FW_Update_() printf "The latest firmware update remain ${REDct}BLOCKED.${NOct}\n" fi else - printf "${REDct}*WARNING*:${NOct} Found high-risk phrases in the changelog file.\n" + printf "${REDct}*WARNING*${NOct}: Found high-risk phrases in the changelog file.\n" if _WaitForYESorNO_ "Do you want to ${REDct}BLOCK${NOct} the latest firmware update?" then Update_Custom_Settings "FW_New_Update_Changelog_Approval" "BLOCKED" @@ -9149,7 +9227,7 @@ _GetOfflineFirmwareVersion_() then fwVersionFormat="${BLUEct}BASE${WHITEct}.${CYANct}MAJOR${WHITEct}.${MGNTct}MINOR${WHITEct}.${YLWct}PATCH${NOct}" # Prompt user for the firmware version if extraction fails # - printf "\n${REDct}**WARNING**${NOct}\n" + printf "\n${REDct}*WARNING*${NOct}\n" if "$isGNUtonFW" then printf "\nFailed to identify firmware version from the update file name." @@ -9172,7 +9250,7 @@ _GetOfflineFirmwareVersion_() then return 1 fi - printf "\n${REDct}**WARNING**${NOct} Invalid format detected!\n" + printf "\n${REDct}*WARNING*${NOct}: Invalid format detected!\n" printf "\nPlease enter the firmware version number in the format ${fwVersionFormat}\n" if "$isGNUtonFW" then @@ -9694,7 +9772,7 @@ _RunFirmwareUpdateNow_() # it has the minimum firmware version supported. if "$routerModelCheckFailed" then - Say "${REDct}*WARNING*:${NOct} The current router model is not supported by this script." + Say "${REDct}*WARNING*${NOct}: The current router model is not supported by this script." if "$inMenuMode" then printf "\nWould you like to uninstall the script now?" @@ -9714,7 +9792,7 @@ _RunFirmwareUpdateNow_() fi if "$MinFirmwareVerCheckFailed" && ! "$offlineUpdateTrigger" then - Say "${REDct}*WARNING*:${NOct} The current firmware version is below the minimum supported. + Say "${REDct}*WARNING*${NOct}: The current firmware version is below the minimum supported. Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or higher to use this script.\n" "$inMenuMode" && _WaitForEnterKey_ "$theMenuReturnPromptMsg" return 1 @@ -9818,16 +9896,16 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or # Use set to read the output of the function into variables # if "$isGNUtonFW" then - Say "Using release information for Gnuton Firmware." - _GnutonBuildSelection_ - md5_url="$(GetLatestFirmwareMD5URL "$FW_GITURL_RELEASE" "$firmware_choice")" - GnutonChangeLogURL="$(GetLatestChangelogURL "$FW_GITURL_RELEASE")" - set -- $(_GetLatestFWUpdateVersionFromGitHub_ "$FW_GITURL_RELEASE" "$firmware_choice") - retCode="$?" + Say "Using release information for Gnuton Firmware." + _GnutonBuildSelection_ + md5_url="$(GetLatestFirmwareMD5URL "$FW_GITURL_RELEASE" "$firmware_choice")" + GnutonChangeLogURL="$(GetLatestChangelogURL "$FW_GITURL_RELEASE")" + set -- $(_GetLatestFWUpdateVersionFromGitHub_ "$FW_GITURL_RELEASE" "$firmware_choice") + retCode="$?" else - Say "Using release information for Merlin Firmware." - set -- $(_GetLatestFWUpdateVersionFromWebsite_ "$FW_SFURL_RELEASE") - retCode="$?" + Say "Using release information for Merlin Firmware." + set -- $(_GetLatestFWUpdateVersionFromWebsite_ "$FW_SFURL_RELEASE") + retCode="$?" fi if [ "$retCode" -eq 0 ] && [ $# -eq 2 ] && \ [ "$1" != "**ERROR**" ] && [ "$2" != "**NO_URL**" ] @@ -9852,7 +9930,7 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or NewUpdate_VersionVerify="$(_GetLatestFWUpdateVersionFromRouter_ 1)" if [ "$NewUpdate_VersionVerify" != "$release_version" ] then - Say "WARNING: The release version found by MerlinAU [$release_version] does not match the F/W update version from the router [$NewUpdate_VersionVerify]." + Say "*WARNING*: The release version found by MerlinAU [$release_version] does NOT match the F/W update version from the router [$NewUpdate_VersionVerify]." "$inMenuMode" && _WaitForEnterKey_ "$mainMenuReturnPromptStr" return 1 fi @@ -10246,8 +10324,8 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or #----------------------------------------------------------------------------------# # **IMPORTANT NOTE**: - # Due to the nature of 'nohup' and the specific behavior of this 'curl' request, - # the following 'curl' command MUST always be the last step in this block. + # Due to the nature of 'nohup' and the specific behavior of this 'Curl' request, + # the following 'Curl' command MUST always be the last step in this block. # Do NOT insert any commands after it! (unless you understand the implications). #----------------------------------------------------------------------------------# nohup curl -k "${routerURL}/upgrade.cgi" \ @@ -10268,9 +10346,9 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or #----------------------------------------------------------# # In the rare case that the F/W Update gets "stuck" for - # some reason & the "curl" cmd never returns, we create + # some reason & the "Curl" cmd never returns, we create # a background child process that sleeps for 3 minutes - # and then kills the "curl" process if it still exists. + # and then kills the "Curl" process if it still exists. # Otherwise, this child process does nothing & returns. # NORMALLY the "Curl" command returns almost instantly # once the upload is complete. @@ -10536,25 +10614,25 @@ _CheckForMinimumRequirements_() if [ "$(uname -o)" != "ASUSWRT-Merlin" ] then requirementsCheckOK=false - Say "\n${CRITct}*WARNING*:${NOct} The current firmware installed is NOT ASUSWRT-Merlin.\n" + Say "\n${CRITct}*WARNING*${NOct}: The current firmware installed is NOT ASUSWRT-Merlin.\n" fi if ! nvram get rc_support | grep -qwoF "am_addons" then requirementsCheckOK=false - Say "\n${CRITct}*WARNING*:${NOct} The current firmware installed does NOT support add-ons.\n" + Say "\n${CRITct}*WARNING*${NOct}: The current firmware installed does NOT support add-ons.\n" fi if ! _CheckForMinimumModelSupport_ then requirementsCheckOK=false - Say "\n${CRITct}*WARNING*:${NOct} The current router model ${REDct}${FW_RouterModelID}${NOct} is NOT supported by this script.\n" + Say "\n${CRITct}*WARNING*${NOct}: The current router model ${REDct}${FW_RouterModelID}${NOct} is NOT supported by this script.\n" fi if ! _CheckForMinimumVersionSupport_ then requirementsCheckOK=false - Say "\n${CRITct}*WARNING*:${NOct} The current firmware version is below the minimum supported by this script." + Say "\n${CRITct}*WARNING*${NOct}: The current firmware version is below the minimum supported by this script." printf "\nCurrent F/W version found: ${REDct}${FW_InstalledVersion}${NOct}" printf "\nMinimum version supported: ${GRNct}${MinSupportedFirmwareVers}${NOct}\n" fi @@ -11542,20 +11620,20 @@ _ShowMainMenuOptions_() # Unsupported Model Check # if "$routerModelCheckFailed" then - Say "${REDct}*WARNING*:${NOct} The current router model is not supported by this script. + Say "${REDct}*WARNING*${NOct}: The current router model is not supported by this script. Please uninstall." echo fi if "$MinFirmwareVerCheckFailed" then - Say "${REDct}*WARNING*:${NOct} The current firmware version is below the minimum supported. + Say "${REDct}*WARNING*${NOct}: The current firmware version is below the minimum supported. Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or higher to use this script." echo fi if ! _HasRouterMoreThan256MBtotalRAM_ && ! _ValidateUSBMountPoint_ "$FW_ZIP_BASE_DIR" then - Say "${REDct}*WARNING*:${NOct} Limited RAM detected (256MB). + Say "${REDct}*WARNING*${NOct}: Limited RAM detected (256MB). A USB drive is required for F/W updates." echo fi @@ -12289,7 +12367,7 @@ _RunLockedInitializationChecks_() if ! _CleanUpOldLogFiles_ then - Say "${YLWct}WARNING:${NOct} Unable to clean up old firmware-update log files." + Say "${YLWct}*WARNING*${NOct}: Unable to clean up old firmware-update log files." retCode=1 fi @@ -12297,7 +12375,7 @@ _RunLockedInitializationChecks_() checkWebsUpdateScriptForGnuton="$isGNUtonFW" if ! _Gnuton_Check_Webs_Update_Script_ then - Say "${YLWct}WARNING:${NOct} Unable to check or install the GNUton \"${FW_WebsUpdateFile}\" patch." + Say "${YLWct}*WARNING*${NOct}: Unable to check or install the GNUton \"${FW_WebsUpdateFile}\" patch." retCode=1 fi diff --git a/README.md b/README.md index ad9411a4..1492a294 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # MerlinAU - AsusWRT-Merlin Firmware Auto Updater -## v1.6.6 -## 2026-Aug-16 +## v1.6.7 +## 2026-Sep-03 ## WebUI: image