diff --git a/MerlinAU.sh b/MerlinAU.sh index 29a91f8f..68c67fa9 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,15 +4,15 @@ # # Original Creation Date: 2023-Oct-01 by @ExtremeFiretop. # Official Co-Author: @Martinski W. - Date: 2023-Nov-01 -# Last Modified: 2024-Aug-07 +# Last Modified: 2024-Aug-05 ################################################################### set -u ## Set version for each Production Release ## -readonly SCRIPT_VERSION=1.2.7 +readonly SCRIPT_VERSION=1.3.0 readonly SCRIPT_NAME="MerlinAU" ## Set to "master" for Production Releases ## -SCRIPT_BRANCH="master" +SCRIPT_BRANCH="dev" ##----------------------------------------## ## Modified by Martinski W. [2024-Jul-03] ## @@ -22,16 +22,17 @@ readonly SCRIPT_URL_BASE="https://raw.githubusercontent.com/ExtremeFiretop/Merli SCRIPT_URL_REPO="${SCRIPT_URL_BASE}/$SCRIPT_BRANCH" # Firmware URL Info # -readonly FW_URL_BASE="https://sourceforge.net/projects/asuswrt-merlin/files" -readonly FW_URL_RELEASE_SUFFIX="Release" +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" ##----------------------------------------## ## Modified by Martinski W. [2024-May-31] ## ##----------------------------------------## # Changelog Info # -readonly CL_URL_NG="${FW_URL_BASE}/Documentation/Changelog-NG.txt/download" -readonly CL_URL_386="${FW_URL_BASE}/Documentation/Changelog-386.txt/download" -readonly CL_URL_3006="${FW_URL_BASE}/Documentation/Changelog-3006.txt/download" +readonly CL_URL_NG="${FW_SFURL_BASE}/Documentation/Changelog-NG.txt/download" +readonly CL_URL_386="${FW_SFURL_BASE}/Documentation/Changelog-386.txt/download" +readonly CL_URL_3006="${FW_SFURL_BASE}/Documentation/Changelog-3006.txt/download" readonly high_risk_terms="factory default reset|features are disabled|break backward compatibility|must be manually|strongly recommended" @@ -498,6 +499,39 @@ _ScriptVersionStrToNum_() echo "$verNum" ; return 0 } +##---------------------------------------## +## Added by ExtremeFiretop [2024-Jun-19] ## +##---------------------------------------## +_GetFirmwareVariantFromRouter_() +{ + ##DEFAULTS TO MERLIN## + local retCode=0 newVersionStr + + buildInfoStr="$(nvram get buildinfo)" + innerverStr="$(nvram get innerver)" + + ##FOR TESTING/DEBUG ONLY## + if false # Change to true for forcing GNUton flag + then + isGNUtonFW=true + else + # Check if innerver and fwInstalledExtendNum contains "gnuton" + if echo "$innerverStr" | grep -iq "gnuton" || \ + echo "$fwInstalledExtendNum" | grep -iq "gnuton" + then + isGNUtonFW=true + # if the version string contain "merlin" + elif echo "$buildInfoStr" | grep -iq "merlin" + then + isGNUtonFW=false + else + isGNUtonFW=false + fi + fi + + echo "$isGNUtonFW" ; return "$retCode" +} + ##----------------------------------------## ## Modified by Martinski W. [2024-May-31] ## ##----------------------------------------## @@ -573,7 +607,6 @@ readonly CRON_MONTH_NAMES="(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)" readonly CRON_MONTH_RegEx="$CRON_MONTH_NAMES([\/,-]$CRON_MONTH_NAMES)*|([*1-9]|1[0-2])([\/,-]([1-9]|1[0-2]))*" readonly CRON_UNKNOWN_DATE="**ERROR**: UNKNOWN Date Found" - ##------------------------------------------## ## Modified by Martinski W. [2024-Aug-06] ## ##------------------------------------------## @@ -585,8 +618,12 @@ readonly FW_UpdateNotificationDateFormat="%Y-%m-%d_%H:%M:00" readonly MODEL_ID="$(_GetRouterModelID_)" readonly PRODUCT_ID="$(_GetRouterProductID_)" +##FOR TESTING/DEBUG ONLY## +#readonly PRODUCT_ID="TUF-AX3000_V2" +##FOR TESTING/DEBUG ONLY## readonly FW_FileName="${PRODUCT_ID}_firmware" -readonly FW_URL_RELEASE="${FW_URL_BASE}/${PRODUCT_ID}/${FW_URL_RELEASE_SUFFIX}/" +readonly FW_SFURL_RELEASE="${FW_SFURL_BASE}/${PRODUCT_ID}/${FW_SFURL_RELEASE_SUFFIX}/" +readonly isGNUtonFW=$(_GetFirmwareVariantFromRouter_) ##----------------------------------------## ## Modified by Martinski W. [2024-Jun-05] ## @@ -627,6 +664,7 @@ ${REDct}v${SCRIPT_VERSION}${NOct} --> ${GRNct}v${DLRepoVersion}${NOct}" fi } + ##----------------------------------------## ## Modified by Martinski W. [2024-Jul-03] ## ##----------------------------------------## @@ -934,7 +972,8 @@ Get_Custom_Setting() if [ -f "$SETTINGSFILE" ]; then case "$setting_type" in - "ROGBuild" | "credentials_base64" | "CheckChangeLog" | \ + "ROGBuild" | "TUFBuild" | "credentials_base64" | \ + "CheckChangeLog" | \ "Allow_Updates_OverVPN" | \ "FW_Allow_Beta_Production_Up" | \ "FW_Auto_Backupmon" | \ @@ -1007,7 +1046,8 @@ Update_Custom_Settings() [ ! -d "$SETTINGS_DIR" ] && mkdir -m 755 -p "$SETTINGS_DIR" case "$setting_type" in - "ROGBuild" | "credentials_base64" | "CheckChangeLog" | \ + "ROGBuild" | "TUFBuild" | "credentials_base64" | \ + "CheckChangeLog" | \ "Allow_Updates_OverVPN" | \ "FW_Allow_Beta_Production_Up" | \ "FW_Auto_Backupmon" | \ @@ -1220,7 +1260,8 @@ _Set_FW_UpdateZIP_DirectoryPath_() while true do - printf "\nEnter the directory path where the ZIP subdirectory [${GRNct}${FW_ZIP_SUBDIR}${NOct}] will be stored.\n" + if "$isGNUtonFW"; then printf "\nEnter the directory path where the update subdirectory [${GRNct}${FW_ZIP_SUBDIR}${NOct}] will be stored.\n" + else printf "\nEnter the directory path where the ZIP subdirectory [${GRNct}${FW_ZIP_SUBDIR}${NOct}] will be stored.\n"; fi if [ -n "$USBMountPoint" ] && _ValidateUSBMountPoint_ "$FW_ZIP_BASE_DIR" then printf "Default directory for USB-attached drive: [${GRNct}${FW_ZIP_BASE_DIR}${NOct}]\n" @@ -1287,10 +1328,12 @@ _Set_FW_UpdateZIP_DirectoryPath_() return 1 fi # Remove now the obsolete directory path # - rm -fr "${FW_ZIP_DIR:?}" + rm -fr "${FW_LOG_DIR:?}" rm -f "${newZIP_FileDirPath}"/*.zip "${newZIP_FileDirPath}"/*.sha256 Update_Custom_Settings FW_New_Update_ZIP_Directory_Path "$newZIP_BaseDirPath" - echo "The directory path for the F/W ZIP file was updated successfully." + if "$isGNUtonFW"; then echo "The directory path for the F/W update file was updated successfully." + else echo "The directory path for the F/W ZIP file was updated successfully."; fi + keepWfile=0 _WaitForEnterKey_ "$advnMenuReturnPromptStr" fi return 0 @@ -1305,9 +1348,12 @@ _Init_Custom_Settings_Config_ # ROG upgrades to 3006 codebase should have # the ROG option deleted. #----------------------------------------------------------- -if [ "$fwInstalledBaseVers" -ge 3006 ] && grep -q "^ROGBuild" "$SETTINGSFILE" +if ! "$isGNUtonFW" then - Delete_Custom_Settings "ROGBuild" + if [ "$fwInstalledBaseVers" -ge 3006 ] && grep -q "^ROGBuild" "$SETTINGSFILE" + then + Delete_Custom_Settings "ROGBuild" + fi fi ##------------------------------------------## @@ -1450,8 +1496,8 @@ _CreateEMailContent_() fwInstalledVersion="$(_GetCurrentFWInstalledLongVersion_)" fwNewUpdateVersion="$(_GetLatestFWUpdateVersionFromRouter_ 1)" - # Remove "_rog" suffix to avoid version comparison failures # - fwInstalledVersion="$(echo "$fwInstalledVersion" | sed 's/_rog$//')" + # Remove "_rog" or "_tuf" suffix to avoid version comparison failures + fwInstalledVersion="$(echo "$fwInstalledVersion" | sed 's/_\(rog\|tuf\)$//')" case "$1" in FW_UPDATE_TEST_EMAIL) @@ -2027,7 +2073,7 @@ _ShutDownNonCriticalServices_() ##------------------------------------------## _DoCleanUp_() { - local delBINfiles=false keepZIPfile=false moveZIPback=false + local delBINfiles=false keepZIPfile=false keepWfile=false local doTrace=false [ $# -gt 0 ] && [ "$1" -eq 0 ] && doTrace=false @@ -2039,20 +2085,35 @@ _DoCleanUp_() [ $# -gt 0 ] && [ "$1" -eq 1 ] && delBINfiles=true [ $# -gt 1 ] && [ "$2" -eq 1 ] && keepZIPfile=true + [ $# -gt 2 ] && [ "$3" -eq 1 ] && keepWfile=true # Stop the LEDs blinking # _Reset_LEDs_ 1 + # Check existence of files and preserve based on flags + local moveZIPback=false + local moveWback=false + # Move file temporarily to save it from deletion # - "$keepZIPfile" && [ -f "$FW_ZIP_FPATH" ] && \ - mv -f "$FW_ZIP_FPATH" "${FW_ZIP_BASE_DIR}/$ScriptDirNameD" && moveZIPback=true + if "$keepZIPfile" && [ -f "$FW_ZIP_FPATH" ]; then + mv -f "$FW_ZIP_FPATH" "${FW_ZIP_BASE_DIR}/$ScriptDirNameD" && moveZIPback=true + fi + + if "$keepWfile" && [ -f "$FW_DL_FPATH" ]; then + mv -f "$FW_DL_FPATH" "${FW_ZIP_BASE_DIR}/$ScriptDirNameD" && moveWback=true + fi rm -f "${FW_ZIP_DIR:?}"/* "$delBINfiles" && rm -f "${FW_BIN_DIR:?}"/* - # Move file back to original location # - "$keepZIPfile" && "$moveZIPback" && \ - mv -f "${FW_ZIP_BASE_DIR}/${ScriptDirNameD}/${FW_FileName}.zip" "$FW_ZIP_FPATH" + # Move files back to their original location if they were moved + if "$moveZIPback"; then + mv -f "${FW_ZIP_BASE_DIR}/${ScriptDirNameD}/${FW_FileName}.zip" "$FW_ZIP_FPATH" + fi + + if "$moveWback"; then + mv -f "${FW_ZIP_BASE_DIR}/${ScriptDirNameD}/${FW_FileName}.${extension}" "$FW_DL_FPATH" + fi if "$doTrace" then @@ -2156,7 +2217,7 @@ check_memory_and_prompt_reboot() # Restart Entware services # _EntwareServicesHandler_ start - _DoCleanUp_ 1 "$keepZIPfile" + _DoCleanUp_ 1 "$keepZIPfile" "$keepWfile" _DoExit_ 1 fi else @@ -2191,7 +2252,7 @@ check_version_support() check_model_support() { # List of unsupported models as a space-separated string - local unsupported_models="RT-AC87U RT-AC56U RT-AC66U RT-AC3200 RT-N66U RT-AC88U RT-AC5300 RT-AC3100 RT-AC68U RT-AC66U_B1 RT-AC1900" + local unsupported_models="RT-AC87U RT-AC56U RT-AC66U RT-AC3200 RT-N66U RT-AC88U RT-AC5300 RT-AC3100 RT-AC68U RT-AC66U_B1 RT-AC1900 DSL-AC68U" # Get the current model local current_model="$(_GetRouterProductID_)" @@ -2848,6 +2909,282 @@ _GetLatestFWUpdateVersionFromWebsite_() return 0 } +##---------------------------------------## +## Added by ExtremeFiretop [2024-Feb-23] ## +##---------------------------------------## +_GetLatestFWUpdateVersionFromGithub_() +{ + local url="$1" # GitHub API URL for the latest release + local firmware_type="$2" # Type of firmware, e.g., "tuf", "rog" or "pure" + + local search_type="$firmware_type" # Default to the input firmware_type + + # If firmware_type is "pure", set search_type to include "squashfs" as well + if [ "$firmware_type" = "pure" ]; then + search_type="pure\|squashfs\|ubi" + fi + + # Fetch the latest release data from GitHub + local release_data=$(curl -s "$url") + + # Construct the grep pattern based on search_type + local grep_pattern="\"browser_download_url\": \".*${PRODUCT_ID}.*\(${search_type}\).*\.\(w\|pkgtb\)\"" + + # Filter the JSON for the desired firmware using grep and head to fetch the URL + local download_url=$(echo "$release_data" | + grep -o "$grep_pattern" | + grep -o "https://[^ ]*\.\(w\|pkgtb\)" | + head -1) + + # Check if a URL was found + if [ -z "$download_url" ]; then + echo "**ERROR** **NO_GITHUB_URL**" + return 1 + else + # Extract the version from the download URL or release data + local version=$(echo "$download_url" | grep -oE "${PRODUCT_ID}[_-][0-9.]+[^/]*" | sed "s/${PRODUCT_ID}[_-]//;s/.w$//;s/_/./g") + echo "$version" + echo "$download_url" + return 0 + fi +} + +##---------------------------------------## +## Added by ExtremeFiretop [2024-Apr-05] ## +##---------------------------------------## +GetLatestFirmwareMD5Url() { + local url="$1" # GitHub API URL for the latest release + local firmware_type="$2" # Type of firmware, e.g., "tuf", "rog" or "pure" + + local search_type="$firmware_type" # Default to the input firmware_type + + # If firmware_type is "pure", set search_type to include "squashfs" as well + if [ "$firmware_type" = "pure" ]; then + search_type="pure\|squashfs\|ubi" + fi + + # Fetch the latest release data from GitHub + local release_data=$(curl -s "$url") + + # Construct the grep pattern based on search_type + local grep_pattern="\"browser_download_url\": \".*${PRODUCT_ID}.*\(${search_type}\).*\.md5\"" + + # Filter the JSON for the desired firmware using grep and sed + local md5_url=$(echo "$release_data" | + grep -o "$grep_pattern" | + sed -E 's/.*"browser_download_url": "([^"]+)".*/\1/' | + head -1) + + # Check if a URL was found and output result or error + if [ -z "$md5_url" ]; then + echo "**ERROR** **NO_FIRMWARE_FILE_URL_FOUND**" + return 1 + else + echo "$md5_url" + fi +} + +##---------------------------------------## +## Added by ExtremeFiretop [2024-Apr-17] ## +##---------------------------------------## +GetLatestChangelogUrl() { + local url="$1" # GitHub API URL for the latest release + + # Fetch the latest release data from GitHub + local release_data=$(curl -s "$url") + + # Parse the release data to find the download URL of the CHANGELOG file + # Directly find the URL without matching a specific model number + local changelog_url=$(echo "$release_data" | grep -o "\"browser_download_url\": \".*CHANGELOG.*\"" | grep -o "https://[^ ]*\"" | tr -d '"' | head -1) + + # Check if the URL has been found + if [ -z "$changelog_url" ]; then + echo "**ERROR** **NO_CHANGELOG_FILE_URL_FOUND**" + return 1 + else + echo "$changelog_url" + fi +} + +##---------------------------------------## +## Added by ExtremeFiretop [2024-Apr-18] ## +##---------------------------------------## +_DownloadForGnuton_() { + + # Follow redirects and capture the effective URL + local effective_url=$(curl -Ls -o /dev/null -w %{url_effective} "$release_link") + + # Use the effective URL to capture the Content-Disposition header + local original_filename=$(curl -sI "$effective_url" | grep -i content-disposition | sed -n 's/.*filename=["]*\([^";]*\).*/\1/p') + + # Sanitize filename by removing problematic characters + local sanitized_filename=$(echo "$original_filename" | sed 's/[^a-zA-Z0-9._-]//g') + + # Extract the file extension + extension="${sanitized_filename##*.}" + + # Combine path, custom file name, and extension before download + FW_DL_FPATH="${FW_ZIP_DIR}/${FW_FileName}.${extension}" + FW_MD5_GITHUB="${FW_ZIP_DIR}/${FW_FileName}.md5" + FW_Changelog_GITHUB="${FW_ZIP_DIR}/${FW_FileName}_Changelog.txt" + + # Download the firmware using the release link + wget --timeout=5 --tries=4 --waitretry=5 --retry-connrefused \ + -O "$FW_DL_FPATH" "$release_link" + if [ ! -f "$FW_DL_FPATH" ]; then + return 1 + fi + + # Download the latest MD5 checksum + Say "Downloading latest MD5 checksum ${GRNct}${md5_url}${NOct}" + wget --timeout=5 --tries=4 --waitretry=5 --retry-connrefused \ + -O "$FW_MD5_GITHUB" "$md5_url" + if [ ! -f "$FW_MD5_GITHUB" ]; then + return 1 + fi + + # Download the latest changelog + Say "Downloading latest Changelog ${GRNct}${Gnuton_changelogurl}${NOct}" + wget --timeout=5 --tries=4 --waitretry=5 --retry-connrefused \ + -O "$FW_Changelog_GITHUB" "$Gnuton_changelogurl" + if [ ! -f "$FW_Changelog_GITHUB" ]; then + return 1 + else + return 0 + fi +} + +##---------------------------------------## +## Added by ExtremeFiretop [2024-Apr-18] ## +##---------------------------------------## +_DownloadForMerlin_() { + + wget --timeout=5 --tries=4 --waitretry=5 --retry-connrefused \ + -O "$FW_ZIP_FPATH" "$release_link" + + # Check if the file was downloaded successfully + if [ ! -f "$FW_ZIP_FPATH" ]; then + return 1 + else + return 0 + fi +} + +##---------------------------------------## +## Added by ExtremeFiretop [2024-Apr-18] ## +##---------------------------------------## +_UnzipMerlin_() { + Say "-----------------------------------------------------------" + # List & log the contents of the ZIP file + unzip -l "$FW_ZIP_FPATH" 2>&1 | \ + while IFS= read -r uzLINE ; do Say "$uzLINE" ; done + Say "-----------------------------------------------------------" + + # Extracting the firmware binary image + if unzip -o "$FW_ZIP_FPATH" -d "$FW_BIN_DIR" -x README* 2>&1 | \ + while IFS= read -r line ; do Say "$line" ; done + then + Say "-----------------------------------------------------------" + #---------------------------------------------------------------# + # Check if ZIP file was downloaded to a USB-attached drive. + # Take into account special case for Entware "/opt/" paths. + #---------------------------------------------------------------# + if ! echo "$FW_ZIP_FPATH" | grep -qE "^(/tmp/mnt/|/tmp/opt/|/opt/)" + then + # It's not on a USB drive, so it's safe to delete it + rm -f "$FW_ZIP_FPATH" + elif ! _ValidateUSBMountPoint_ "$FW_ZIP_BASE_DIR" 1 + then + #-------------------------------------------------------------# + # This should not happen because we already checked for it + # at the very beginning of this function, but just in case + # it does (drive going bad suddenly?) we'll report it here. + #-------------------------------------------------------------# + Say "Expected directory path $FW_ZIP_BASE_DIR is NOT found." + Say "${REDct}**ERROR**${NOct}: Required USB storage device is not connected or not mounted correctly." + return 1 + # Consider how to handle this error. For now, we'll not delete the ZIP file. + else + keepZIPfile=1 + fi + else + #------------------------------------------------------------# + # Remove ZIP file here because it may have been corrupted. + # Better to download it again and start all over, instead + # of trying to figure out why uncompressing it failed. + #------------------------------------------------------------# + rm -f "$FW_ZIP_FPATH" + _SendEMailNotification_ FAILED_FW_UNZIP_STATUS + Say "${REDct}**ERROR**${NOct}: Unable to decompress the firmware ZIP file [$FW_ZIP_FPATH]." + _return 1 + fi + return 0 +} + +##---------------------------------------## +## Added by ExtremeFiretop [2024-Apr-18] ## +##---------------------------------------## +_CopyGnutonFiles_() { + +Say "Checking if file management is required" + +local copy_success=0 +local copy_attempted=1 + +# Check and copy the firmware file if different from destination +if [ "$FW_DL_FPATH" != "${FW_BIN_DIR}/${FW_FileName}.${extension}" ]; then + Say "File management is required" + copy_attempted=0 + cp "$FW_DL_FPATH" "$FW_BIN_DIR" && Say "Copying firmware file..." || copy_success=1 +else + Say "File management is not required" +fi + +if ! "$offlineUpdateTrigger" +then + # Check and copy the MD5 file if different from destination + if [ "$FW_MD5_GITHUB" != "${FW_BIN_DIR}/${FW_FileName}.md5" ]; then + copy_attempted=0 + mv -f "$FW_MD5_GITHUB" "$FW_BIN_DIR" && Say "Moving MD5 file..." || copy_success=1 + fi + + # Check and copy the Changelog file if different from destination + if [ "$FW_Changelog_GITHUB" != "${FW_BIN_DIR}/${FW_FileName}_Changelog.txt" ]; then + copy_attempted=0 + mv -f "$FW_Changelog_GITHUB" "$FW_BIN_DIR" && Say "Moving changelog file..." || copy_success=1 + fi +fi + +if [ $copy_attempted -eq 0 ] && [ $copy_success -eq 0 ] +then + #---------------------------------------------------------------# + # Check if Gntuon 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/)" + then + # It's not on a USB drive, so it's safe to delete it + rm -f "$FW_DL_FPATH" + rm -f "$FW_Changelog_GITHUB" + rm -f "$FW_MD5_GITHUB" + elif ! _ValidateUSBMountPoint_ "$FW_ZIP_BASE_DIR" 1 + then + #-------------------------------------------------------------# + # This should not happen because we already checked for it + # at the very beginning of this function, but just in case + # it does (drive going bad suddenly?) we'll report it here. + #-------------------------------------------------------------# + Say "Expected directory path $FW_ZIP_BASE_DIR is NOT found." + Say "${REDct}**ERROR**${NOct}: Required USB storage device is not connected or not mounted correctly." + return 1 + # Consider how to handle this error. For now, we'll not delete the firmware file. + else + keepWfile=1 + fi +fi +return 0 +} + ##------------------------------------------## ## Modified by ExtremeFiretop [2024-Jul-24] ## ##------------------------------------------## @@ -2918,6 +3255,35 @@ _CheckOfflineFirmwareSHA256_() fi } +##---------------------------------------## +## Added by ExtremeFiretop [2024-Apr-18] ## +##---------------------------------------## +_CheckFirmwareMD5_() { + # Check if both the MD5 checksum file and the firmware file exist + if [ -f "${FW_BIN_DIR}/${FW_FileName}.md5" ] && [ -f "$firmware_file" ]; then + # Extract the MD5 checksum from the downloaded .md5 file + # Assuming the .md5 file contains a single line with the checksum followed by the filename + local md5_expected=$(cut -d' ' -f1 "${FW_BIN_DIR}/${FW_FileName}.md5") + + # Calculate the MD5 checksum of the firmware file + local md5_actual=$(md5sum "$firmware_file" | cut -d' ' -f1) + + # Compare the calculated MD5 checksum with the expected MD5 checksum + if [ "$md5_actual" != "$md5_expected" ]; then + Say "${REDct}**ERROR**${NOct}: Extracted firmware does not match the MD5 checksum!" + _DoCleanUp_ 1 + _SendEMailNotification_ FAILED_FW_CHECKSUM_STATUS + return 1 + else + Say "Firmware MD5 checksum verified successfully." + fi + else + Say "${REDct}**ERROR**${NOct}: MD5 checksum file not found or firmware file is missing!" + _DoCleanUp_ 1 + return 1 + fi +} + ##----------------------------------------## ## Modified by Martinski W. [2024-May-27] ## ##----------------------------------------## @@ -2953,7 +3319,7 @@ _toggle_change_log_check_() } ##------------------------------------------## -## Modified by ExtremeFiretop [2024-Jul-23] ## +## Modified by ExtremeFiretop [2024-Jun-27] ## ##------------------------------------------## _Toggle_VPN_Access_() { @@ -3056,7 +3422,67 @@ _Toggle_Auto_Backups_() ##------------------------------------------## ## Modified by ExtremeFiretop [2024-Feb-18] ## ##------------------------------------------## -change_build_type() +_ChangeBuildType_TUF_() +{ + local doReturnToMenu buildtypechoice + printf "Changing Flash Build Type...\n" + + # Use Get_Custom_Setting to retrieve the previous choice + previous_choice="$(Get_Custom_Setting "TUFBuild")" + + # If the previous choice is not set, default to 'n' + if [ "$previous_choice" = "TBD" ]; then + previous_choice="n" + fi + + # Convert previous choice to a descriptive text + if [ "$previous_choice" = "y" ]; then + display_choice="TUF Build" + else + display_choice="Pure Build" + fi + + printf "\nCurrent Build Type: ${GRNct}$display_choice${NOct}.\n" + + doReturnToMenu=false + while true + do + printf "\n${SEPstr}" + printf "\nChoose your preferred option for the build type to flash:\n" + printf "\n ${GRNct}1${NOct}. Original ${REDct}TUF${NOct} themed user interface${NOct}\n" + printf "\n ${GRNct}2${NOct}. Pure ${GRNct}non-TUF${NOct} themed user interface ${GRNct}(Recommended)${NOct}\n" + printf "\n ${GRNct}e${NOct}. Exit to Advanced Menu\n" + printf "${SEPstr}\n" + printf "[$display_choice] Enter selection: " + read -r choice + + [ -z "$choice" ] && break + + if echo "$choice" | grep -qE "^(e|exit|Exit)$" + then doReturnToMenu=true ; break ; fi + + case $choice in + 1) buildtypechoice="y" ; break + ;; + 2) buildtypechoice="n" ; break + ;; + *) echo ; _InvalidMenuSelection_ + ;; + esac + done + + "$doReturnToMenu" && return 0 + + Update_Custom_Settings "TUFBuild" "$buildtypechoice" + printf "\nThe build type to flash was updated successfully.\n" + + _WaitForEnterKey_ "$advnMenuReturnPromptStr" +} + +##------------------------------------------## +## Modified by ExtremeFiretop [2024-Feb-18] ## +##------------------------------------------## +_ChangeBuildType_ROG_() { local doReturnToMenu buildtypechoice printf "Changing Flash Build Type...\n" @@ -3713,9 +4139,9 @@ _CheckPostponementDays_() return "$retCode" } -##----------------------------------------## -## Modified by Martinski W. [2024-Aug-06] ## -##----------------------------------------## +##------------------------------------------## +## Modified by ExtremeFiretop [2024-May-06] ## +##------------------------------------------## _Set_FW_UpdatePostponementDays_() { local validNumRegExp="([0-9]|[1-9][0-9]|1[0-9][0-9])" @@ -4004,21 +4430,31 @@ _ChangelogVerificationCheck_() current_version="$(_GetCurrentFWInstalledLongVersion_)" release_version="$(Get_Custom_Setting "FW_New_Update_Notification_Vers")" - # Get the correct Changelog filename: "Changelog-[3006|386|NG].txt" # - if echo "$release_version" | grep -qE "^3006[.]" - then - changeLogTag="3006" - elif echo "$release_version" | grep -q "386[.]" + if "$isGNUtonFW" then - changeLogTag="386" + changeLogFile="${FW_BIN_DIR}/${FW_FileName}_Changelog.txt" else - changeLogTag="NG" + # Get the correct Changelog filename: "Changelog-[3006|386|NG].txt" # + if echo "$release_version" | grep -qE "^3006[.]" + then + changeLogTag="3006" + elif echo "$release_version" | grep -q "386[.]" + then + changeLogTag="386" + else + changeLogTag="NG" + fi + changeLogFile="$(/usr/bin/find -L "${FW_BIN_DIR}" -name "Changelog-${changeLogTag}.txt" -print)" fi - changeLogFile="$(/usr/bin/find -L "${FW_BIN_DIR}" -name "Changelog-${changeLogTag}.txt" -print)" if [ ! -f "$changeLogFile" ] then - Say "Changelog file [${FW_BIN_DIR}/Changelog-${changeLogTag}.txt] does NOT exist." + if "$isGNUtonFW" + then + Say "Changelog file [${FW_BIN_DIR}/${FW_FileName}_Changelog.txt] does NOT exist." + else + Say "Changelog file [${FW_BIN_DIR}/Changelog-${changeLogTag}.txt] does NOT exist." + fi _DoCleanUp_ return 1 else @@ -4059,16 +4495,20 @@ _ChangelogVerificationCheck_() release_version_regex="$formatted_release_version \([0-9]{1,2}-[A-Za-z]{3}-[0-9]{4}\)" current_version_regex="$formatted_current_version \([0-9]{1,2}-[A-Za-z]{3}-[0-9]{4}\)" - # Check if the current version is present in the changelog - if ! grep -Eq "$current_version_regex" "$changeLogFile" + if "$isGNUtonFW" then - Say "Current version NOT found in changelog file. Bypassing changelog verification for this run." - return 0 + # For Gnuton, the whole file is relevant as it only contains the current version # + changelog_contents="$(cat "$changeLogFile")" + else + if ! grep -Eq "$current_version_regex" "$changeLogFile"; then + Say "Current version NOT found in changelog file. Bypassing changelog verification for this run." + return 0 + else + # Extract log contents between two firmware versions for non-Gnuton changelogs # + changelog_contents="$(awk "/$release_version_regex/,/$current_version_regex/" "$changeLogFile")" + fi fi - # Extract log contents between two firmware versions - changelog_contents="$(awk "/$release_version_regex/,/$current_version_regex/" "$changeLogFile")" - if [ "$mode" = "interactive" ] then if _high_risk_phrases_interactive_ "$changelog_contents" @@ -4091,7 +4531,7 @@ _ChangelogVerificationCheck_() ##----------------------------------------## ## Modified by Martinski W. [2024-May-31] ## ##----------------------------------------## -_ManageChangelog_() +_ManageChangelogMerlin_() { if [ $# -eq 0 ] || [ -z "$1" ] then echo "**ERROR** **NO_PARAMS**" ; return 1 ; fi @@ -4167,6 +4607,59 @@ _ManageChangelog_() return 0 } +_ManageChangelogGnuton_() +{ + if [ $# -eq 0 ] || [ -z "$1" ] + then echo "**ERROR** **NO_PARAMS**" ; return 1 ; fi + + local mode="$1" # Mode should be 'download' or 'view' # + local newUpdateVerStr="" + local wgetLogFile changeLogFile changeLogTag changeLogURL + + # Create directory to download changelog if missing + if ! _CreateDirectory_ "$FW_BIN_DIR" ; then return 1 ; fi + + Gnuton_changelogurl=$(GetLatestChangelogUrl "$FW_GITURL_RELEASE") + + # Follow redirects and capture the effective URL + local effective_url=$(curl -Ls -o /dev/null -w %{url_effective} "$Gnuton_changelogurl") + + # Use the effective URL to capture the Content-Disposition header + local original_filename=$(curl -sI "$effective_url" | grep -i content-disposition | sed -n 's/.*filename=["]*\([^";]*\).*/\1/p') + + # Sanitize filename by removing problematic characters + local sanitized_filename=$(echo "$original_filename" | sed 's/[^a-zA-Z0-9._-]//g') + + FW_Changelog_GITHUB="${FW_BIN_DIR}/${FW_FileName}_Changelog.txt" + + wgetLogFile="${FW_BIN_DIR}/${ScriptFNameTag}.WGET.LOG" + printf "\nRetrieving ${GRNct}${FW_Changelog_GITHUB}${NOct} ...\n" + + wget --timeout=5 --tries=4 --waitretry=5 --retry-connrefused \ + -O "$FW_Changelog_GITHUB" -o "$wgetLogFile" "${Gnuton_changelogurl}" + + if [ ! -f "$FW_Changelog_GITHUB" ] + then + Say "Changelog file [$FW_Changelog_GITHUB] does NOT exist." + echo ; [ -f "$wgetLogFile" ] && cat "$wgetLogFile" + else + if [ "$mode" = "download" ] + then + _ChangelogVerificationCheck_ "auto" + elif [ "$mode" = "view" ] + then + clear + printf "\n${GRNct}Changelog file is ready to review!${NOct}\n" + printf "\nPress '${REDct}q${NOct}' to quit when finished.\n" + dos2unix "$FW_Changelog_GITHUB" + _WaitForEnterKey_ + less "$FW_Changelog_GITHUB" + fi + fi + rm -f "$FW_Changelog_GITHUB" "$wgetLogFile" + return 1 +} + ##----------------------------------------## ## Modified by Martinski W. [2024-Aug-05] ## ##----------------------------------------## @@ -4209,7 +4702,14 @@ _CheckNewUpdateFirmwareNotification_() Update_Custom_Settings FW_New_Update_Notification_Date "$fwNewUpdateNotificationDate" "$inRouterSWmode" && sendNewUpdateStatusEmail=true if ! "$FlashStarted" - then _ManageChangelog_ "download" "$fwNewUpdateNotificationVers" ; fi + then + if "$isGNUtonFW" + then + _ManageChangelogGnuton_ "download" "$fwNewUpdateNotificationVers" + else + _ManageChangelogMerlin_ "download" "$fwNewUpdateNotificationVers" + fi + fi fi fi @@ -4220,7 +4720,14 @@ _CheckNewUpdateFirmwareNotification_() Update_Custom_Settings FW_New_Update_Notification_Date "$fwNewUpdateNotificationDate" "$inRouterSWmode" && sendNewUpdateStatusEmail=true if ! "$FlashStarted" - then _ManageChangelog_ "download" "$fwNewUpdateNotificationVers" ; fi + then + if "$isGNUtonFW" + then + _ManageChangelogGnuton_ "download" "$fwNewUpdateNotificationVers" + else + _ManageChangelogMerlin_ "download" "$fwNewUpdateNotificationVers" + fi + fi fi fwNewUpdateNotificationDate="$(Get_Custom_Setting FW_New_Update_Notification_Date)" @@ -4572,7 +5079,8 @@ _GetOfflineFirmwareVersion_() fwVersionFormat="${BLUEct}BASE${WHITEct}.${CYANct}MAJOR${WHITEct}.${MAGENTAct}MINOR${WHITEct}.${YLWct}PATCH${NOct}" # Prompt user for the firmware version if extraction fails # printf "\n${REDct}**WARNING**${NOct}\n" - printf "\nFailed to identify firmware version from the ZIP file name." + if "$isGNUtonFW"; then printf "\nFailed to identify firmware version from the update file name." + else printf "\nFailed to identify firmware version from the ZIP file name."; fi printf "\nPlease enter the firmware version number in the format ${fwVersionFormat}\n" printf "\n(Examples: 3004.388.8.0 or 3004.388.8.beta1): " read -r formatted_version @@ -4598,19 +5106,31 @@ _SelectOfflineUpdateFile_() { local selection fileList fileCount - # Check if the directory is empty or no valid files are found # - if [ -z "$(ls -A "$FW_ZIP_DIR"/*.zip 2>/dev/null)" ] + # Check if the directory is empty or no desired files are found # + if "$isGNUtonFW" then - printf "\nNo valid files found in the directory. Exiting.\n" - printf "\n---------------------------------------------------\n" - return 1 + if [ -z "$(ls -A "$FW_ZIP_DIR"/*.w "$FW_ZIP_DIR"/*.pkgtb 2>/dev/null)" ] + then + printf "\nNo valid update files found in the directory. Exiting.\n" + printf "\n---------------------------------------------------\n" + return 1 + fi + else + if [ -z "$(ls -A "$FW_ZIP_DIR"/*.zip 2>/dev/null)" ] + then + printf "\nNo valid ZIP files found in the directory. Exiting.\n" + printf "\n---------------------------------------------------\n" + return 1 + fi fi while true do - printf "\nAvailable ZIP files in the directory: [${GRNct}${FW_ZIP_DIR}${NOct}]:\n\n" + if "$isGNUtonFW"; then printf "\nAvailable update files in the directory: [${GRNct}${FW_ZIP_DIR}${NOct}]:\n\n" + else printf "\nAvailable ZIP files in the directory: [${GRNct}${FW_ZIP_DIR}${NOct}]:\n\n"; fi - fileList="$(ls -A1 "$FW_ZIP_DIR"/*.zip 2>/dev/null)" + if "$isGNUtonFW"; then fileList="$(ls -A "$FW_ZIP_DIR"/*.w "$FW_ZIP_DIR"/*.pkgtb 2>/dev/null)" + else fileList="$(ls -A "$FW_ZIP_DIR"/*.zip 2>/dev/null)"; fi fileCount=1 for file in $fileList do @@ -4620,7 +5140,8 @@ _SelectOfflineUpdateFile_() # Prompt user to select a file # printf "\n---------------------------------------------------\n" - printf "\n[${theMUExitStr}] Enter the number of the ZIP file you want to select: " + if "$isGNUtonFW"; then printf "\n[${theMUExitStr}] Enter the number of the update file you want to select: " + else printf "\n[${theMUExitStr}] Enter the number of the ZIP file you want to select: "; fi read -r selection if [ -z "$selection" ] @@ -4682,6 +5203,78 @@ _SelectOfflineUpdateFile_() fi } +_GnutonBuildSelection_() +{ + ##------------------------------------------## + ## Modified by ExtremeFiretop [2024-Apr-18] ## + ##------------------------------------------## + # Check if PRODUCT_ID is for a TUF model and requires user choice + if echo "$PRODUCT_ID" | grep -q "^TUF-"; then + # Fetch the previous choice from the settings file + local previous_choice="$(Get_Custom_Setting "TUFBuild")" + + if [ "$previous_choice" = "y" ]; then + echo "TUF Build selected for flashing" + firmware_choice="tuf" + elif [ "$previous_choice" = "n" ]; then + echo "Pure Build selected for flashing" + firmware_choice="pure" + elif [ "$inMenuMode" = true ]; then + printf "${REDct}Found TUF build for: $PRODUCT_ID.${NOct}\n" + printf "${REDct}Would you like to use the TUF build?${NOct}\n" + printf "Enter your choice (y/n): " + read -r choice + if [ "$choice" = "y" ] || [ "$choice" = "Y" ]; then + echo "TUF Build selected for flashing" + firmware_choice="tuf" + Update_Custom_Settings "TUFBuild" "y" + else + echo "Pure Build selected for flashing" + firmware_choice="pure" + Update_Custom_Settings "TUFBuild" "n" + fi + else + echo "Defaulting to Pure Build due to non-interactive mode." + firmware_choice="pure" + Update_Custom_Settings "TUFBuild" "n" + fi + elif echo "$PRODUCT_ID" | grep -q "^GT-" + then + # Fetch the previous choice from the settings file + local previous_choice="$(Get_Custom_Setting "ROGBuild")" + + if [ "$previous_choice" = "y" ]; then + echo "ROG Build selected for flashing" + firmware_choice="rog" + elif [ "$previous_choice" = "n" ]; then + echo "Pure Build selected for flashing" + firmware_choice="pure" + elif [ "$inMenuMode" = true ]; then + printf "${REDct}Found ROG build for: $PRODUCT_ID.${NOct}\n" + printf "${REDct}Would you like to use the ROG build?${NOct}\n" + printf "Enter your choice (y/n): " + read -r choice + if [ "$choice" = "y" ] || [ "$choice" = "Y" ]; then + echo "ROG Build selected for flashing" + firmware_choice="rog" + Update_Custom_Settings "ROGBuild" "y" + else + echo "Pure Build selected for flashing" + firmware_choice="pure" + Update_Custom_Settings "ROGBuild" "n" + fi + else + echo "Defaulting to Pure Build due to non-interactive mode." + firmware_choice="pure" + Update_Custom_Settings "ROGBuild" "n" + fi + else + # If not a TUF model, process as usual + firmware_choice="pure" + fi + return 0 +} + ##------------------------------------------## ## Modified by ExtremeFiretop [2024-Jul-23] ## ##------------------------------------------## @@ -4833,44 +5426,52 @@ _RunOfflineUpdateNow_() offlineUpdateTrigger=true theMenuReturnPromptMsg="$advnMenuReturnPromptStr" - if _Set_FW_UpdateZIP_DirectoryPath_ + clear + # Create directory for downloading & extracting firmware # + if ! _CreateDirectory_ "$FW_ZIP_DIR" + then + _ClearOfflineUpdateState_ 1 ; return 1 + fi + printf "\n---------------------------------------------------\n" + if "$isGNUtonFW"; then printf "\nPlease copy your firmware update file (.w or .pkgtb) using the *original* ZIP filename to this directory:" + else printf "\nPlease copy your firmware ZIP file (using the *original* ZIP filename) to this directory:"; fi + printf "\n[${GRNct}$FW_ZIP_DIR${NOct}]\n" + printf "\nPress '${GRNct}Y${NOct}' when completed, or '${REDct}N${NOct}' to cancel.\n" + printf "\n---------------------------------------------------\n" + if _WaitForYESorNO_ then clear - # Create directory for downloading & extracting firmware # - if ! _CreateDirectory_ "$FW_ZIP_DIR" - then - _ClearOfflineUpdateState_ 1 ; return 1 - fi printf "\n---------------------------------------------------\n" - printf "\nPlease copy your firmware ZIP file (using the *original* ZIP filename) to this directory:" - printf "\n[${GRNct}$FW_ZIP_DIR${NOct}]\n" - printf "\nPress '${GRNct}Y${NOct}' when completed, or '${REDct}N${NOct}' to cancel.\n" - printf "\n---------------------------------------------------\n" - if _WaitForYESorNO_ + printf "\nContinuing to the update file selection process.\n" + if _SelectOfflineUpdateFile_ then - clear - printf "\n---------------------------------------------------\n" - printf "\nContinuing to the update file selection process.\n" - if _SelectOfflineUpdateFile_ + if "$isGNUtonFW" then - set -- $(_GetLatestFWUpdateVersionFromWebsite_ "$FW_URL_RELEASE") - if [ $? -eq 0 ] && [ $# -eq 2 ] && \ - [ "$1" != "**ERROR**" ] && [ "$2" != "**NO_URL**" ] - then - release_link="$2" - _RunFirmwareUpdateNow_ - _ClearOfflineUpdateState_ - else - Say "${REDct}**ERROR**${NOct}: No firmware release URL was found for [$PRODUCT_ID] router model." - _ClearOfflineUpdateState_ 1 - return 1 - fi + # Extract the filename from the path + original_filename=$(basename "$selected_file") + # Sanitize filename by removing problematic characters (if necessary) + sanitized_filename=$(echo "$original_filename" | sed 's/[^a-zA-Z0-9._-]//g') + # Extract the file extension + extension="${sanitized_filename##*.}" + FW_DL_FPATH="${FW_ZIP_DIR}/${FW_FileName}.${extension}" + _GnutonBuildSelection_ + set -- $(_GetLatestFWUpdateVersionFromGithub_ "$FW_GITURL_RELEASE" "$firmware_choice") else + set -- $(_GetLatestFWUpdateVersionFromWebsite_ "$FW_SFURL_RELEASE") + fi + if [ $? -eq 0 ] && [ $# -eq 2 ] && \ + [ "$1" != "**ERROR**" ] && [ "$2" != "**NO_URL**" ] + then + release_link="$2" + _RunFirmwareUpdateNow_ + _ClearOfflineUpdateState_ + else + Say "${REDct}**ERROR**${NOct}: No firmware release URL was found for [$PRODUCT_ID] router model." _ClearOfflineUpdateState_ 1 return 1 fi else - _ClearOfflineUpdateState_ "Offline update process was cancelled. Exiting.\n" + _ClearOfflineUpdateState_ 1 return 1 fi else @@ -5007,8 +5608,20 @@ Please manually update to version $MinSupportedFirmwareVers or higher to use thi fi # Use set to read the output of the function into variables - set -- $(_GetLatestFWUpdateVersionFromWebsite_ "$FW_URL_RELEASE") - if [ $? -eq 0 ] && [ $# -eq 2 ] && \ + if "$isGNUtonFW" + then + Say "Using release information for Gnuton Firmware." + _GnutonBuildSelection_ + md5_url=$(GetLatestFirmwareMD5Url "$FW_GITURL_RELEASE" "$firmware_choice") + Gnuton_changelogurl=$(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="$?" + fi + if [ "$retCode" -eq 0 ] && [ $# -eq 2 ] && \ [ "$1" != "**ERROR**" ] && [ "$2" != "**NO_URL**" ] then release_version="$1" @@ -5075,19 +5688,24 @@ Please manually update to version $MinSupportedFirmwareVers or higher to use thi Say "Downloading ${GRNct}${release_link}${NOct}" echo - ##----------------------------------------## - ## Modified by Martinski W. [2024-Feb-28] ## - ##----------------------------------------## + ##------------------------------------------## + ## Modified by ExtremeFiretop [2024-Apl-24] ## + ##------------------------------------------## # Avoid error message about HSTS database # wgetHstsFile="/tmp/home/root/.wget-hsts" [ -f "$wgetHstsFile" ] && chmod 0644 "$wgetHstsFile" - wget --timeout=5 --tries=4 --waitretry=5 --retry-connrefused \ - -O "$FW_ZIP_FPATH" "$release_link" - - if [ ! -f "$FW_ZIP_FPATH" ] + if "$isGNUtonFW" + then + _DownloadForGnuton_ + retCode="$?" + else + _DownloadForMerlin_ + retCode="$?" + fi + if [ "$retCode" -eq 1 ] then - Say "${REDct}**ERROR**${NOct}: Firmware ZIP file [$FW_ZIP_FPATH] was not downloaded." + Say "${REDct}**ERROR**${NOct}: Firmware files were not downloaded successfully." "$inMenuMode" && _WaitForEnterKey_ "$mainMenuReturnPromptStr" _Reset_LEDs_ return 1 @@ -5103,50 +5721,18 @@ Please manually update to version $MinSupportedFirmwareVers or higher to use thi check_memory_and_prompt_reboot "$requiredRAM_kb" "$availableRAM_kb" ##------------------------------------------## - ## Modified by ExtremeFiretop [2024-Mar-19] ## + ## Modified by ExtremeFiretop [2024-Apr-21] ## ##------------------------------------------## - Say "-----------------------------------------------------------" - # List & log the contents of the ZIP file # - unzip -l "$FW_ZIP_FPATH" 2>&1 | \ - while IFS= read -r uzLINE ; do Say "$uzLINE" ; done - Say "-----------------------------------------------------------" - - # Extracting the firmware binary image # - if unzip -o "$FW_ZIP_FPATH" -d "$FW_BIN_DIR" -x README* 2>&1 | \ - while IFS= read -r line ; do Say "$line" ; done + if "$isGNUtonFW" then - Say "-----------------------------------------------------------" - #---------------------------------------------------------------# - # Check if ZIP file was downloaded to a USB-attached drive. - # Take into account special case for Entware "/opt/" paths. - #---------------------------------------------------------------# - if ! echo "$FW_ZIP_FPATH" | grep -qE "^(/tmp/mnt/|/tmp/opt/|/opt/)" - then - # It's not on a USB drive, so it's safe to delete it # - rm -f "$FW_ZIP_FPATH" - elif ! _ValidateUSBMountPoint_ "$FW_ZIP_BASE_DIR" 1 - then - #-------------------------------------------------------------# - # This should not happen because we already checked for it - # at the very beginning of this function, but just in case - # it does (drive going bad suddenly?) we'll report it here. - #-------------------------------------------------------------# - Say "Expected directory path $FW_ZIP_BASE_DIR is NOT found." - Say "${REDct}**ERROR**${NOct}: Required USB storage device is not connected or not mounted correctly." - "$inMenuMode" && _WaitForEnterKey_ - # Consider how to handle this error. For now, we'll not delete the ZIP file. - else - keepZIPfile=1 - fi + _CopyGnutonFiles_ + retCode="$?" else - #------------------------------------------------------------# - # Remove ZIP file here because it may have been corrupted. - # Better to download it again and start all over, instead - # of trying to figure out why uncompressing it failed. - #------------------------------------------------------------# - rm -f "$FW_ZIP_FPATH" - _SendEMailNotification_ FAILED_FW_UNZIP_STATUS - Say "${REDct}**ERROR**${NOct}: Unable to decompress the firmware ZIP file [$FW_ZIP_FPATH]." + _UnzipMerlin_ + retCode="$?" + fi + if [ "$retCode" -eq 1 ] + then "$inMenuMode" && _WaitForEnterKey_ "$theMenuReturnPromptMsg" _Reset_LEDs_ return 1 @@ -5163,14 +5749,16 @@ Please manually update to version $MinSupportedFirmwareVers or higher to use thi ##------------------------------------------## ## Modified by ExtremeFiretop [2024-May-25] ## ##------------------------------------------## - _ChangelogVerificationCheck_ "interactive" - retCode="$?" + if ! { "$isGNUtonFW" && "$offlineUpdateTrigger" ; } then + _ChangelogVerificationCheck_ "interactive" + retCode="$?" - if [ "$retCode" -eq 1 ] - then - "$inMenuMode" && _WaitForEnterKey_ "$theMenuReturnPromptMsg" - _Reset_LEDs_ - return 1 + if [ "$retCode" -eq 1 ] + then + "$inMenuMode" && _WaitForEnterKey_ "$theMenuReturnPromptMsg" + _Reset_LEDs_ + return 1 + fi fi freeRAM_kb="$(_GetFreeRAM_KB_)" @@ -5252,16 +5840,30 @@ Please manually update to version $MinSupportedFirmwareVers or higher to use thi fi ##------------------------------------------## - ## Modified by ExtremeFiretop [2024-Jul-23] ## + ## Modified by ExtremeFiretop [2024-Aug-11] ## ##------------------------------------------## if "$offlineUpdateTrigger" then - _CheckOfflineFirmwareSHA256_ - retCode="$?" + if ! "$isGNUtonFW" + then + _CheckOfflineFirmwareSHA256_ + retCode="$?" + elif [ -f "${FW_BIN_DIR}/${FW_FileName}.md5" ]; then + _CheckFirmwareMD5_ + retCode="$?" + else + retCode=0 # Skip if the MD5 file does not exist + fi else - _CheckOnlineFirmwareSHA256_ - retCode="$?" + if "$isGNUtonFW"; then + _CheckFirmwareMD5_ + retCode="$?" + else + _CheckOnlineFirmwareSHA256_ + retCode="$?" + fi fi + if [ "$retCode" -eq 1 ] then "$inMenuMode" && _WaitForEnterKey_ "$theMenuReturnPromptMsg" @@ -5288,7 +5890,7 @@ Please manually update to version $MinSupportedFirmwareVers or higher to use thi if ! _WaitForYESorNO_ "Continue?" then Say "F/W Update was cancelled by user." - _DoCleanUp_ 1 "$keepZIPfile" + _DoCleanUp_ 1 "$keepZIPfile" "$keepWfile" return 1 fi fi @@ -5437,7 +6039,7 @@ Please manually update to version $MinSupportedFirmwareVers or higher to use thi 2. Update credentials by selecting \"Set Router Login Credentials\" from the Main Menu." _SendEMailNotification_ FAILED_FW_UPDATE_STATUS - _DoCleanUp_ 1 "$keepZIPfile" + _DoCleanUp_ 1 "$keepZIPfile" "$keepWfile" _EntwareServicesHandler_ start if [ -f /opt/bin/diversion ] then @@ -5858,7 +6460,8 @@ _ProcessMeshNodes_() } keepZIPfile=0 -trap '_DoCleanUp_ 0 "$keepZIPfile" ; _DoExit_ 0' HUP INT QUIT ABRT TERM +keepWfile=0 +trap '_DoCleanUp_ 0 "$keepZIPfile" "$keepWfile" ; _DoExit_ 0' HUP INT QUIT ABRT TERM ##----------------------------------------## ## Modified by Martinski W. [2024-Feb-28] ## @@ -6326,6 +6929,13 @@ _ShowMainMenu_() then notificationStr="${REDct}NOT SET${NOct}" else notificationStr="${GRNct}$(_SimpleNotificationDate_ "$notifyDate")${NOct}" fi + # Use the global variable + if "$isGNUtonFW" + then + FirmwareFlavor="${MAGENTAct}GNUton${NOct}" + else + FirmwareFlavor="${BLUEct}Merlin${NOct}" + fi printf "${SEPstr}" if [ "$HIDE_ROUTER_SECTION" = "false" ] @@ -6336,6 +6946,7 @@ _ShowMainMenu_() fi printf "\n Router's Product Name/Model ID: ${FW_RouterModelID}${padStr}(H)ide" printf "\n USB-Attached Storage Connected: $USBConnected" + printf "\n F/W Variant Configuration Found: $FirmwareFlavor" printf "\n F/W Version Currently Installed: $FW_InstalledVerStr" printf "\n F/W Update Version Available: $FW_NewUpdateVerStr" printf "\n F/W Update Estimated Run Date: $ExpectedFWUpdateRuntime" @@ -6455,26 +7066,96 @@ _ShowAdvancedOptionsMenu_() fi fi - if [ "$fwInstalledBaseVers" -le 3004 ] + if "$isGNUtonFW" then - # Retrieve the current build type setting - local current_build_type="$(Get_Custom_Setting "ROGBuild")" - - # Convert the setting to a descriptive text - if [ "$current_build_type" = "y" ]; then - current_build_type_menu="ROG Build" - elif [ "$current_build_type" = "n" ]; then - current_build_type_menu="Pure Build" - else - current_build_type_menu="NOT SET" - fi + if [ "$fwInstalledBaseVers" -le 3004 ] + then + # Retrieve the current build type setting + local current_build_type="$(Get_Custom_Setting "TUFBuild")" + + # Convert the setting to a descriptive text + if [ "$current_build_type" = "y" ]; then + current_build_type_menu="TUF Build" + elif [ "$current_build_type" = "n" ]; then + current_build_type_menu="Pure Build" + else + current_build_type_menu="NOT SET" + fi + + if echo "$PRODUCT_ID" | grep -q "^TUF-" + then + printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type" + if [ "$current_build_type_menu" = "NOT SET" ] + then printf "\n${padStr}[Current Build Type: ${REDct}${current_build_type_menu}${NOct}]\n" + else printf "\n${padStr}[Current Build Type: ${GRNct}${current_build_type_menu}${NOct}]\n" + fi + fi + elif [ "$fwInstalledBaseVers" -ge 3006 ] + then + # Retrieve the current build type setting + local current_build_typerog="$(Get_Custom_Setting "ROGBuild")" + + # Convert the setting to a descriptive text + if [ "$current_build_typerog" = "y" ]; then + current_build_type_menurog="ROG Build" + elif [ "$current_build_typerog" = "n" ]; then + current_build_type_menurog="Pure Build" + else + current_build_type_menurog="NOT SET" + fi + + if echo "$PRODUCT_ID" | grep -q "^GT-" + then + printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type" + if [ "$current_build_type_menurog" = "NOT SET" ] + then printf "\n${padStr}[Current Build Type: ${REDct}${current_build_type_menurog}${NOct}]\n" + else printf "\n${padStr}[Current Build Type: ${GRNct}${current_build_type_menurog}${NOct}]\n" + fi + fi + + # Retrieve the current build type setting + local current_build_typetuf="$(Get_Custom_Setting "TUFBuild")" + + # Convert the setting to a descriptive text + if [ "$current_build_typetuf" = "y" ]; then + current_build_type_menutuf="TUF Build" + elif [ "$current_build_typetuf" = "n" ]; then + current_build_type_menutuf="Pure Build" + else + current_build_type_menutuf="NOT SET" + fi - if echo "$PRODUCT_ID" | grep -q "^GT-" + if echo "$PRODUCT_ID" | grep -q "^TUF-" + then + printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type" + if [ "$current_build_type_menutuf" = "NOT SET" ] + then printf "\n${padStr}[Current Build Type: ${REDct}${current_build_type_menutuf}${NOct}]\n" + else printf "\n${padStr}[Current Build Type: ${GRNct}${current_build_type_menutuf}${NOct}]\n" + fi + fi + fi + else + if [ "$fwInstalledBaseVers" -le 3004 ] then - printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type" - if [ "$current_build_type_menu" = "NOT SET" ] - then printf "\n${padStr}[Current Build Type: ${REDct}${current_build_type_menu}${NOct}]\n" - else printf "\n${padStr}[Current Build Type: ${GRNct}${current_build_type_menu}${NOct}]\n" + # Retrieve the current build type setting + local current_build_type="$(Get_Custom_Setting "ROGBuild")" + + # Convert the setting to a descriptive text + if [ "$current_build_type" = "y" ]; then + current_build_type_menu="ROG Build" + elif [ "$current_build_type" = "n" ]; then + current_build_type_menu="Pure Build" + else + current_build_type_menu="NOT SET" + fi + + if echo "$PRODUCT_ID" | grep -q "^GT-" + then + printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type" + if [ "$current_build_type_menu" = "NOT SET" ] + then printf "\n${padStr}[Current Build Type: ${REDct}${current_build_type_menu}${NOct}]\n" + else printf "\n${padStr}[Current Build Type: ${GRNct}${current_build_type_menu}${NOct}]\n" + fi fi fi fi @@ -6612,7 +7293,12 @@ _AdvancedLogsOptions_() _InvalidMenuSelection_ fi ;; - cl) _ManageChangelog_ "view" + cl) if "$isGNUtonFW" + then + _ManageChangelogGnuton_ "view" + else + _ManageChangelogMerlin_ "view" + fi ;; e|exit) break ;; @@ -6637,7 +7323,7 @@ _AdvancedOptionsMenu_() case "$theUserInputStr" in 1) _Set_FW_UpdateZIP_DirectoryPath_ ;; - 2) _Set_FW_UpdateCronSchedule_ + 2) _Set_FW_UpdateCronSchedule_ ;; 3) _Toggle_FW_UpdatesFromBeta_ ;; @@ -6648,9 +7334,14 @@ _AdvancedOptionsMenu_() else _InvalidMenuSelection_ fi ;; - bt) if [ "$fwInstalledBaseVers" -le 3004 ] && \ + bt) if echo "$PRODUCT_ID" | grep -q "^TUF-" + then _ChangeBuildType_TUF_ + elif [ "$fwInstalledBaseVers" -le 3004 ] && \ + echo "$PRODUCT_ID" | grep -q "^GT-" + then _ChangeBuildType_ROG_ + elif [ "$fwInstalledBaseVers" -ge 3006 ] && "$isGNUtonFW" && \ echo "$PRODUCT_ID" | grep -q "^GT-" - then change_build_type + then _ChangeBuildType_ROG_ else _InvalidMenuSelection_ fi ;; diff --git a/README.md b/README.md index 137f6518..8a392729 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # MerlinAU - AsusWRT-Merlin Firmware Auto Updater -## v1.2.7 +## v1.3.0 ## 2024-08-08 ![image](https://github.com/user-attachments/assets/2b2b886c-0719-4d0a-861a-7fec94087e1e) diff --git a/version.txt b/version.txt index c04c650a..f0bb29e7 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.2.7 +1.3.0