#!/bin/sh ###################################################### ## __ __ _ _ ## ## | \/ | | |(_) ## ## ___ ___ | \ / | ___ _ __ | | _ _ __ ## ## / __| / __|| |\/| | / _ \| '__|| || || '_ \ ## ## \__ \| (__ | | | || __/| | | || || | | | ## ## |___/ \___||_| |_| \___||_| |_||_||_| |_| ## ## ## ## https://github.com/jackyaz/scMerlin ## ## ## ###################################################### # Last Modified: 2024-Mar-12 #----------------------------------------------------- ########## Shellcheck directives ########### # shellcheck disable=SC2016 # shellcheck disable=SC2018 # shellcheck disable=SC2019 # shellcheck disable=SC2059 # shellcheck disable=SC2034 # shellcheck disable=SC2155 ###################################################### ### Start of script variables ### readonly SCRIPT_NAME="scMerlin" readonly SCRIPT_NAME_LOWER="$(echo "$SCRIPT_NAME" | tr 'A-Z' 'a-z' | sed 's/d//')" readonly SCM_VERSION="v2.4.1" readonly SCRIPT_VERSION="v2.4.1" SCRIPT_BRANCH="master" SCRIPT_REPO="https://jackyaz.io/$SCRIPT_NAME/$SCRIPT_BRANCH" readonly SCRIPT_DIR="/jffs/addons/$SCRIPT_NAME_LOWER.d" readonly SCRIPT_WEBPAGE_DIR="$(readlink /www/user)" readonly SCRIPT_WEB_DIR="$SCRIPT_WEBPAGE_DIR/$SCRIPT_NAME_LOWER" readonly SHARED_DIR="/jffs/addons/shared-jy" readonly SHARED_REPO="https://jackyaz.io/shared-jy/master" readonly SHARED_WEB_DIR="$SCRIPT_WEBPAGE_DIR/shared-jy" readonly NTP_WATCHDOG_FILE="$SCRIPT_DIR/.watchdogenabled" readonly TAIL_TAINTED_FILE="$SCRIPT_DIR/.tailtaintdnsenabled" [ -z "$(nvram get odmpid)" ] && ROUTER_MODEL=$(nvram get productid) || ROUTER_MODEL=$(nvram get odmpid) ### End of script variables ### ### Start of output format variables ### readonly CRIT="\\e[41m" readonly ERR="\\e[31m" readonly WARN="\\e[33m" readonly PASS="\\e[32m" readonly BOLD="\\e[1m" readonly SETTING="${BOLD}\\e[36m" readonly CLEARFORMAT="\\e[0m" ### End of output format variables ### ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-09] ## ##----------------------------------------------## readonly BEGIN_InsertTag="/\*\*BEGIN:scMerlin\*\*/" readonly ENDIN_InsertTag="/\*\*END:scMerlin\*\*/" readonly SUPPORTstr="$(nvram get rc_support)" if echo "$SUPPORTstr" | grep -qw '2.4G' then Band_24G_Support=true else Band_24G_Support=false fi if echo "$SUPPORTstr" | grep -qw '5G' then Band_5G_1_Support=true else Band_5G_1_Support=false fi if echo "$SUPPORTstr" | grep -qw '5G-2' then Band_5G_2_support=true else Band_5G_2_support=false fi if echo "$SUPPORTstr" | grep -qw 'wifi6e' then Band_6G_1_Support=true else Band_6G_1_Support=false fi ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-03] ## ##----------------------------------------------## GetIFaceName() { if [ $# -eq 0 ] || [ -z "$1" ] ; then echo "" ; return 1 ; fi theIFnamePrefix="" case "$1" in "2.4GHz") if "$Band_24G_Support" then if [ "$ROUTER_MODEL" = "GT-AXE16000" ] then theIFnamePrefix="wl3" else theIFnamePrefix="wl0" fi fi ;; "5GHz_1") if "$Band_5G_1_Support" then if [ "$ROUTER_MODEL" = "GT-AXE16000" ] then theIFnamePrefix="wl0" else theIFnamePrefix="wl1" fi fi ;; "5GHz_2") if "$Band_5G_2_support" then if [ "$ROUTER_MODEL" = "GT-AXE16000" ] then theIFnamePrefix="wl1" else theIFnamePrefix="wl2" fi fi ;; "6GHz_1") if [ "$ROUTER_MODEL" = "GT-AXE16000" ] || "$Band_6G_1_Support" then theIFnamePrefix="wl2" ; fi ;; esac if [ -z "$theIFnamePrefix" ] then echo "" else echo "$(nvram get "${theIFnamePrefix}_ifname")" fi } ##-------------------------------------## ## Added by Martinski W. [2023-Jun-02] ## ##-------------------------------------## GetTemperatureValue() { theIFname="$(GetIFaceName "$1")" if [ -z "$theIFname" ] then echo "[N/A]" else echo "$(wl -i "$theIFname" phy_tempsense | awk '{print $1/2+20}')" fi } # $1 = print to syslog, $2 = message to print, $3 = log level Print_Output(){ if [ "$1" = "true" ]; then logger -t "$SCRIPT_NAME" "$2" fi printf "${BOLD}${3}%s${CLEARFORMAT}\\n\\n" "$2" } Firmware_Version_Check(){ if nvram get rc_support | grep -qF "am_addons"; then return 0 else return 1 fi } ### Code for these functions inspired by https://github.com/Adamm00 - credit to @Adamm ### Check_Lock(){ if [ -f "/tmp/$SCRIPT_NAME_LOWER.lock" ]; then ageoflock=$(($(date +%s) - $(date +%s -r "/tmp/$SCRIPT_NAME_LOWER.lock"))) if [ "$ageoflock" -gt 60 ]; then Print_Output true "Stale lock file found (>60 seconds old) - purging lock" "$ERR" kill "$(sed -n '1p' "/tmp/$SCRIPT_NAME_LOWER.lock")" >/dev/null 2>&1 Clear_Lock echo "$$" > "/tmp/$SCRIPT_NAME_LOWER.lock" return 0 else Print_Output true "Lock file found (age: $ageoflock seconds)" "$ERR" if [ -z "$1" ]; then exit 1 else return 1 fi fi else echo "$$" > "/tmp/$SCRIPT_NAME_LOWER.lock" return 0 fi } Clear_Lock(){ rm -f "/tmp/$SCRIPT_NAME_LOWER.lock" 2>/dev/null return 0 } ############################################## Set_Version_Custom_Settings(){ SETTINGSFILE="/jffs/addons/custom_settings.txt" case "$1" in local) if [ -f "$SETTINGSFILE" ]; then if [ "$(grep -c "scmerlin_version_local" $SETTINGSFILE)" -gt 0 ]; then if [ "$2" != "$(grep "scmerlin_version_local" /jffs/addons/custom_settings.txt | cut -f2 -d' ')" ]; then sed -i "s/scmerlin_version_local.*/scmerlin_version_local $2/" "$SETTINGSFILE" fi else echo "scmerlin_version_local $2" >> "$SETTINGSFILE" fi else echo "scmerlin_version_local $2" >> "$SETTINGSFILE" fi ;; server) if [ -f "$SETTINGSFILE" ]; then if [ "$(grep -c "scmerlin_version_server" $SETTINGSFILE)" -gt 0 ]; then if [ "$2" != "$(grep "scmerlin_version_server" /jffs/addons/custom_settings.txt | cut -f2 -d' ')" ]; then sed -i "s/scmerlin_version_server.*/scmerlin_version_server $2/" "$SETTINGSFILE" fi else echo "scmerlin_version_server $2" >> "$SETTINGSFILE" fi else echo "scmerlin_version_server $2" >> "$SETTINGSFILE" fi ;; esac } Update_Check(){ echo 'var updatestatus = "InProgress";' > "$SCRIPT_WEB_DIR/detect_update.js" doupdate="false" localver=$(grep "SCRIPT_VERSION=" "/jffs/scripts/$SCRIPT_NAME_LOWER" | grep -m1 -oE 'v[0-9]{1,2}([.][0-9]{1,2})([.][0-9]{1,2})') /usr/sbin/curl -fsL --retry 3 "$SCRIPT_REPO/404/$SCRIPT_NAME_LOWER.sh" | grep -qF "jackyaz" || { Print_Output true "404 error detected - stopping update" "$ERR"; return 1; } serverver=$(/usr/sbin/curl -fsL --retry 3 "$SCRIPT_REPO/version/$SCRIPT_NAME_LOWER.sh" | grep "SCRIPT_VERSION=" | grep -m1 -oE 'v[0-9]{1,2}([.][0-9]{1,2})([.][0-9]{1,2})') if [ "$localver" != "$serverver" ]; then doupdate="version" Set_Version_Custom_Settings server "$serverver" echo 'var updatestatus = "'"$serverver"'";' > "$SCRIPT_WEB_DIR/detect_update.js" else localmd5="$(md5sum "/jffs/scripts/$SCRIPT_NAME_LOWER" | awk '{print $1}')" remotemd5="$(curl -fsL --retry 3 "$SCRIPT_REPO/md5/$SCRIPT_NAME_LOWER.sh" | md5sum | awk '{print $1}')" if [ "$localmd5" != "$remotemd5" ]; then doupdate="md5" Set_Version_Custom_Settings server "$serverver-hotfix" echo 'var updatestatus = "'"$serverver-hotfix"'";' > "$SCRIPT_WEB_DIR/detect_update.js" fi fi if [ "$doupdate" = "false" ]; then echo 'var updatestatus = "None";' > "$SCRIPT_WEB_DIR/detect_update.js" fi echo "$doupdate,$localver,$serverver" } Update_Version(){ if [ -z "$1" ]; then updatecheckresult="$(Update_Check)" isupdate="$(echo "$updatecheckresult" | cut -f1 -d',')" localver="$(echo "$updatecheckresult" | cut -f2 -d',')" serverver="$(echo "$updatecheckresult" | cut -f3 -d',')" if [ "$isupdate" = "version" ]; then Print_Output true "New version of $SCRIPT_NAME available - $serverver" "$PASS" elif [ "$isupdate" = "md5" ]; then Print_Output true "MD5 hash of $SCRIPT_NAME does not match - hotfix available - $serverver" "$PASS" fi if [ "$isupdate" != "false" ]; then printf "\\n${BOLD}Do you want to continue with the update? (y/n)${CLEARFORMAT} " read -r confirm case "$confirm" in y|Y) printf "\\n" Update_File shared-jy.tar.gz Update_File scmerlin_www.asp Update_File sitemap.asp Update_File tailtop Update_File tailtopd Update_File tailtaintdns Update_File tailtaintdnsd Update_File sc.func Update_File S99tailtop Update_File S95tailtaintdns Download_File "$SCRIPT_REPO/update/$SCRIPT_NAME_LOWER.sh" "/jffs/scripts/$SCRIPT_NAME_LOWER" && Print_Output true "$SCRIPT_NAME successfully updated" chmod 0755 "/jffs/scripts/$SCRIPT_NAME_LOWER" Set_Version_Custom_Settings local "$serverver" Set_Version_Custom_Settings server "$serverver" Clear_Lock PressEnter exec "$0" exit 0 ;; *) printf "\\n" Clear_Lock return 1 ;; esac else Print_Output true "No updates available - latest is $localver" "$WARN" Clear_Lock fi fi if [ "$1" = "force" ]; then serverver=$(/usr/sbin/curl -fsL --retry 3 "$SCRIPT_REPO/version/$SCRIPT_NAME_LOWER.sh" | grep "SCRIPT_VERSION=" | grep -m1 -oE 'v[0-9]{1,2}([.][0-9]{1,2})([.][0-9]{1,2})') Print_Output true "Downloading latest version ($serverver) of $SCRIPT_NAME" "$PASS" Update_File shared-jy.tar.gz Update_File scmerlin_www.asp Update_File sitemap.asp Update_File tailtop Update_File tailtopd Update_File tailtaintdns Update_File tailtaintdnsd Update_File sc.func Update_File S99tailtop Update_File S95tailtaintdns Download_File "$SCRIPT_REPO/update/$SCRIPT_NAME_LOWER.sh" "/jffs/scripts/$SCRIPT_NAME_LOWER" && Print_Output true "$SCRIPT_NAME successfully updated" chmod 0755 "/jffs/scripts/$SCRIPT_NAME_LOWER" Set_Version_Custom_Settings local "$serverver" Set_Version_Custom_Settings server "$serverver" Clear_Lock if [ -z "$2" ]; then PressEnter exec "$0" elif [ "$2" = "unattended" ]; then exec "$0" postupdate fi exit 0 fi } Update_File(){ if [ "$1" = "scmerlin_www.asp" ] || [ "$1" = "sitemap.asp" ] ; then tmpfile="/tmp/$1" Download_File "$SCRIPT_REPO/files/$1" "$tmpfile" if ! diff -q "$tmpfile" "$SCRIPT_DIR/$1" >/dev/null 2>&1; then if [ -f "$SCRIPT_DIR/$1" ]; then Get_WebUI_Page "$SCRIPT_DIR/$1" sed -i "\\~$MyPage~d" /tmp/menuTree.js rm -f "$SCRIPT_WEBPAGE_DIR/$MyPage" 2>/dev/null fi Download_File "$SCRIPT_REPO/files/$1" "$SCRIPT_DIR/$1" Print_Output true "New version of $1 downloaded" "$PASS" Mount_WebUI fi rm -f "$tmpfile" elif [ "$1" = "shared-jy.tar.gz" ]; then if [ ! -f "$SHARED_DIR/$1.md5" ]; then Download_File "$SHARED_REPO/$1" "$SHARED_DIR/$1" Download_File "$SHARED_REPO/$1.md5" "$SHARED_DIR/$1.md5" tar -xzf "$SHARED_DIR/$1" -C "$SHARED_DIR" rm -f "$SHARED_DIR/$1" Print_Output true "New version of $1 downloaded" "$PASS" else localmd5="$(cat "$SHARED_DIR/$1.md5")" remotemd5="$(curl -fsL --retry 3 "$SHARED_REPO/$1.md5")" if [ "$localmd5" != "$remotemd5" ]; then Download_File "$SHARED_REPO/$1" "$SHARED_DIR/$1" Download_File "$SHARED_REPO/$1.md5" "$SHARED_DIR/$1.md5" tar -xzf "$SHARED_DIR/$1" -C "$SHARED_DIR" rm -f "$SHARED_DIR/$1" Print_Output true "New version of $1 downloaded" "$PASS" fi fi elif [ "$1" = "S99tailtop" ]; then tmpfile="/tmp/$1" Download_File "$SCRIPT_REPO/files/$1" "$tmpfile" if ! diff -q "$tmpfile" "$SCRIPT_DIR/$1" >/dev/null 2>&1; then if [ -f "$SCRIPT_DIR/S99tailtop" ]; then "$SCRIPT_DIR/S99tailtop" stop >/dev/null 2>&1 sleep 2 fi Download_File "$SCRIPT_REPO/files/$1" "$SCRIPT_DIR/$1" chmod 0755 "$SCRIPT_DIR/$1" "$SCRIPT_DIR/S99tailtop" start >/dev/null 2>&1 Print_Output true "New version of $1 downloaded" "$PASS" fi rm -f "$tmpfile" elif [ "$1" = "tailtop" ] || [ "$1" = "tailtopd" ]; then tmpfile="/tmp/$1" Download_File "$SCRIPT_REPO/files/$1" "$tmpfile" if ! diff -q "$tmpfile" "$SCRIPT_DIR/$1" >/dev/null 2>&1; then if [ -f "$SCRIPT_DIR/S99tailtop" ]; then "$SCRIPT_DIR/S99tailtop" stop >/dev/null 2>&1 sleep 2 fi Download_File "$SCRIPT_REPO/files/$1" "$SCRIPT_DIR/$1" chmod 0755 "$SCRIPT_DIR/$1" "$SCRIPT_DIR/S99tailtop" start >/dev/null 2>&1 Print_Output true "New version of $1 downloaded" "$PASS" fi rm -f "$tmpfile" elif [ "$1" = "S95tailtaintdns" ]; then tmpfile="/tmp/$1" Download_File "$SCRIPT_REPO/files/$1" "$tmpfile" if ! diff -q "$tmpfile" "$SCRIPT_DIR/$1" >/dev/null 2>&1; then if [ -f "$SCRIPT_DIR/S95tailtaintdns" ]; then "$SCRIPT_DIR/S95tailtaintdns" stop >/dev/null 2>&1 sleep 2 fi Download_File "$SCRIPT_REPO/files/$1" "$SCRIPT_DIR/$1" chmod 0755 "$SCRIPT_DIR/$1" if [ "$(NTPBootWatchdog check)" = "ENABLED" ]; then "$SCRIPT_DIR/S95tailtaintdns" start >/dev/null 2>&1 fi Print_Output true "New version of $1 downloaded" "$PASS" fi rm -f "$tmpfile" elif [ "$1" = "tailtaintdns" ] || [ "$1" = "tailtaintdnsd" ]; then tmpfile="/tmp/$1" Download_File "$SCRIPT_REPO/files/$1" "$tmpfile" if ! diff -q "$tmpfile" "$SCRIPT_DIR/$1" >/dev/null 2>&1; then if [ -f "$SCRIPT_DIR/S95tailtaintdns" ]; then "$SCRIPT_DIR/S95tailtaintdns" stop >/dev/null 2>&1 sleep 2 fi Download_File "$SCRIPT_REPO/files/$1" "$SCRIPT_DIR/$1" chmod 0755 "$SCRIPT_DIR/$1" if [ "$(NTPBootWatchdog check)" = "ENABLED" ]; then "$SCRIPT_DIR/S95tailtaintdns" start >/dev/null 2>&1 fi Print_Output true "New version of $1 downloaded" "$PASS" fi rm -f "$tmpfile" elif [ "$1" = "sc.func" ]; then tmpfile="/tmp/$1" Download_File "$SCRIPT_REPO/files/$1" "$tmpfile" if ! diff -q "$tmpfile" "$SCRIPT_DIR/$1" >/dev/null 2>&1; then Download_File "$SCRIPT_REPO/files/$1" "$SCRIPT_DIR/$1" chmod 0755 "$SCRIPT_DIR/$1" Print_Output true "New version of $1 downloaded" "$PASS" fi rm -f "$tmpfile" else return 1 fi } Validate_Number(){ if [ "$1" -eq "$1" ] 2>/dev/null; then return 0 else return 1 fi } Create_Dirs(){ if [ ! -d "$SCRIPT_DIR" ]; then mkdir -p "$SCRIPT_DIR" fi if [ ! -d "$SHARED_DIR" ]; then mkdir -p "$SHARED_DIR" fi if [ ! -d "$SCRIPT_WEBPAGE_DIR" ]; then mkdir -p "$SCRIPT_WEBPAGE_DIR" fi if [ ! -d "$SCRIPT_WEB_DIR" ]; then mkdir -p "$SCRIPT_WEB_DIR" fi } Create_Symlinks(){ rm -rf "${SCRIPT_WEB_DIR:?}/"* 2>/dev/null ln -s /tmp/scmerlin-top "$SCRIPT_WEB_DIR/top.htm" 2>/dev/null ln -s /tmp/addonwebpages.tmp "$SCRIPT_WEB_DIR/addonwebpages.htm" 2>/dev/null ln -s /tmp/scmcronjobs.tmp "$SCRIPT_WEB_DIR/scmcronjobs.htm" 2>/dev/null ln -s "$NTP_WATCHDOG_FILE" "$SCRIPT_WEB_DIR/watchdogenabled.htm" 2>/dev/null ln -s "$TAIL_TAINTED_FILE" "$SCRIPT_WEB_DIR/tailtaintdnsenabled.htm" 2>/dev/null if [ ! -d "$SHARED_WEB_DIR" ]; then ln -s "$SHARED_DIR" "$SHARED_WEB_DIR" 2>/dev/null fi } Auto_ServiceEvent(){ case $1 in create) if [ -f /jffs/scripts/service-event ]; then STARTUPLINECOUNT=$(grep -c '# '"$SCRIPT_NAME" /jffs/scripts/service-event) STARTUPLINECOUNTEX=$(grep -cx 'if echo "$2" | /bin/grep -q "'"$SCRIPT_NAME_LOWER"'"; then { /jffs/scripts/'"$SCRIPT_NAME_LOWER"' service_event "$@" & }; fi # '"$SCRIPT_NAME" /jffs/scripts/service-event) if [ "$STARTUPLINECOUNT" -gt 1 ] || { [ "$STARTUPLINECOUNTEX" -eq 0 ] && [ "$STARTUPLINECOUNT" -gt 0 ]; }; then sed -i -e '/# '"$SCRIPT_NAME"'/d' /jffs/scripts/service-event fi if [ "$STARTUPLINECOUNTEX" -eq 0 ]; then echo 'if echo "$2" | /bin/grep -q "'"$SCRIPT_NAME_LOWER"'"; then { /jffs/scripts/'"$SCRIPT_NAME_LOWER"' service_event "$@" & }; fi # '"$SCRIPT_NAME" >> /jffs/scripts/service-event fi else echo "#!/bin/sh" > /jffs/scripts/service-event echo "" >> /jffs/scripts/service-event echo 'if echo "$2" | /bin/grep -q "'"$SCRIPT_NAME_LOWER"'"; then { /jffs/scripts/'"$SCRIPT_NAME_LOWER"' service_event "$@" & }; fi # '"$SCRIPT_NAME" >> /jffs/scripts/service-event chmod 0755 /jffs/scripts/service-event fi ;; delete) if [ -f /jffs/scripts/service-event ]; then STARTUPLINECOUNT=$(grep -i -c '# '"$SCRIPT_NAME" /jffs/scripts/service-event) if [ "$STARTUPLINECOUNT" -gt 0 ]; then sed -i -e '/# '"$SCRIPT_NAME"'/d' /jffs/scripts/service-event fi fi ;; esac } ##----------------------------------------## ## Modified by Martinski W. [2024-Mar-12] ## ##----------------------------------------## Auto_Startup(){ case $1 in create) if [ -f /jffs/scripts/post-mount ]; then STARTUPLINECOUNT=$(grep -i -c '# '"$SCRIPT_NAME$" /jffs/scripts/post-mount) if [ "$STARTUPLINECOUNT" -gt 0 ]; then sed -i -e '/# '"$SCRIPT_NAME$"'/d' /jffs/scripts/post-mount fi fi if [ -f /jffs/scripts/services-start ]; then STARTUPLINECOUNT=$(grep -i -c '# '"$SCRIPT_NAME$" /jffs/scripts/services-start) STARTUPLINECOUNTEX=$(grep -i -cx "/jffs/scripts/$SCRIPT_NAME_LOWER startup"' & # '"$SCRIPT_NAME$" /jffs/scripts/services-start) if [ "$STARTUPLINECOUNT" -gt 1 ] || { [ "$STARTUPLINECOUNTEX" -eq 0 ] && [ "$STARTUPLINECOUNT" -gt 0 ]; }; then sed -i -e '/# '"$SCRIPT_NAME$"'/d' /jffs/scripts/services-start fi if [ "$STARTUPLINECOUNTEX" -eq 0 ]; then echo "/jffs/scripts/$SCRIPT_NAME_LOWER startup"' & # '"$SCRIPT_NAME" >> /jffs/scripts/services-start fi else echo "#!/bin/sh" > /jffs/scripts/services-start echo "" >> /jffs/scripts/services-start echo "/jffs/scripts/$SCRIPT_NAME_LOWER startup"' & # '"$SCRIPT_NAME" >> /jffs/scripts/services-start chmod 0755 /jffs/scripts/services-start fi ;; delete) if [ -f /jffs/scripts/post-mount ]; then STARTUPLINECOUNT=$(grep -i -c '# '"$SCRIPT_NAME$" /jffs/scripts/post-mount) if [ "$STARTUPLINECOUNT" -gt 0 ]; then sed -i -e '/# '"$SCRIPT_NAME$"'/d' /jffs/scripts/post-mount fi fi if [ -f /jffs/scripts/services-start ]; then STARTUPLINECOUNT=$(grep -i -c '# '"$SCRIPT_NAME$" /jffs/scripts/services-start) if [ "$STARTUPLINECOUNT" -gt 0 ]; then sed -i -e '/# '"$SCRIPT_NAME$"'/d' /jffs/scripts/services-start fi fi ;; esac } Download_File(){ /usr/sbin/curl -fsL --retry 3 "$1" -o "$2" } Get_WebUI_Page(){ MyPage="none" for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do page="/www/user/user$i.asp" if [ -f "$page" ] && [ "$(md5sum < "$1")" = "$(md5sum < "$page")" ]; then MyPage="user$i.asp" return elif [ "$MyPage" = "none" ] && [ ! -f "$page" ]; then MyPage="user$i.asp" fi done } ### function based on @dave14305's FlexQoS webconfigpage function ### Get_WebUI_URL(){ urlpage="" urlproto="" urldomain="" urlport="" urlpage="$(sed -nE "/$SCRIPT_NAME/ s/.*url\: \"(user[0-9]+\.asp)\".*/\1/p" /tmp/menuTree.js)" if [ "$(nvram get http_enable)" -eq 1 ]; then urlproto="https" else urlproto="http" fi if [ -n "$(nvram get lan_domain)" ]; then urldomain="$(nvram get lan_hostname).$(nvram get lan_domain)" else urldomain="$(nvram get lan_ipaddr)" fi if [ "$(nvram get ${urlproto}_lanport)" -eq 80 ] || [ "$(nvram get ${urlproto}_lanport)" -eq 443 ]; then urlport="" else urlport=":$(nvram get ${urlproto}_lanport)" fi if echo "$urlpage" | grep -qE "user[0-9]+\.asp"; then echo "${urlproto}://${urldomain}${urlport}/${urlpage}" | tr "A-Z" "a-z" else echo "WebUI page not found" fi } ### ### ##----------------------------------------## ## Modified by Martinski W. [2023-Jun-09] ## ##----------------------------------------## ### locking mechanism code credit to Martineau (@MartineauUK) ### Mount_WebUI(){ realpage="" Print_Output true "Mounting WebUI tabs for $SCRIPT_NAME" "$PASS" LOCKFILE=/tmp/addonwebui.lock FD=386 eval exec "$FD>$LOCKFILE" flock -x "$FD" Get_WebUI_Page "$SCRIPT_DIR/scmerlin_www.asp" if [ "$MyPage" = "none" ]; then Print_Output true "Unable to mount $SCRIPT_NAME WebUI page, exiting" "$CRIT" flock -u "$FD" return 1 fi cp -f "$SCRIPT_DIR/scmerlin_www.asp" "$SCRIPT_WEBPAGE_DIR/$MyPage" echo "$SCRIPT_NAME" > "$SCRIPT_WEBPAGE_DIR/$(echo $MyPage | cut -f1 -d'.').title" if [ "$(uname -o)" = "ASUSWRT-Merlin" ]; then if [ ! -f /tmp/index_style.css ]; then cp -f /www/index_style.css /tmp/ fi if ! grep -q '.menu_Addons' /tmp/index_style.css ; then echo ".menu_Addons { background: url(ext/shared-jy/addons.png); background-size: contain; }" >> /tmp/index_style.css fi if grep -q '.menu_Addons' /tmp/index_style.css && ! grep -q 'url(ext/shared-jy/addons.png); background-size: contain;' /tmp/index_style.css; then sed -i 's/addons.png);/addons.png); background-size: contain;/' /tmp/index_style.css fi if grep -q '.dropdown-content {display: block;}' /tmp/index_style.css ; then sed -i '/dropdown-content/d' /tmp/index_style.css fi if ! grep -q '.dropdown-content {visibility: visible;}' /tmp/index_style.css ; then { echo ".dropdown-content {top: 0px; left: 185px; visibility: hidden; position: absolute; background-color: #3a4042; min-width: 165px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1000;}" echo ".dropdown-content a {padding: 6px 8px; text-decoration: none; display: block; height: 100%; min-height: 20px; max-height: 40px; font-weight: bold; text-shadow: 1px 1px 0px black; font-family: Verdana, MS UI Gothic, MS P Gothic, Microsoft Yahei UI, sans-serif; font-size: 12px; border: 1px solid #6B7071;}" echo ".dropdown-content a:hover {background-color: #77a5c6;}" echo ".dropdown:hover .dropdown-content {visibility: visible;}" } >> /tmp/index_style.css fi umount /www/index_style.css 2>/dev/null mount -o bind /tmp/index_style.css /www/index_style.css if [ ! -f /tmp/menuTree.js ]; then cp -f /www/require/modules/menuTree.js /tmp/ fi sed -i "\\~$MyPage~d" /tmp/menuTree.js ## Use the same BEGIN/END insert tags here as those used in the "Menu_Uninstall()" function ## if ! grep -qE '^menuName: "Addons"' /tmp/menuTree.js then lineinsbefore="$(($(grep -n "^exclude:" /tmp/menuTree.js | cut -f1 -d':') - 1))" sed -i "$lineinsbefore""i\ ${BEGIN_InsertTag}\n\ ,\n{\n\ menuName: \"Addons\",\n\ index: \"menu_Addons\",\n\ tab: [\n\ {url: \"javascript:var helpwindow=window.open('\/ext\/shared-jy\/redirect.htm')\", tabName: \"Help & Support\"},\n\ {url: \"NULL\", tabName: \"__INHERIT__\"}\n\ ]\n}\n\ ${ENDIN_InsertTag}" /tmp/menuTree.js fi sed -i "/url: \"javascript:var helpwindow=window.open('\/ext\/shared-jy\/redirect.htm'/i {url: \"$MyPage\", tabName: \"$SCRIPT_NAME\"}," /tmp/menuTree.js realpage="$MyPage" if [ -f "$SCRIPT_DIR/sitemap.asp" ]; then Get_WebUI_Page "$SCRIPT_DIR/sitemap.asp" if [ "$MyPage" = "none" ]; then Print_Output true "Unable to mount $SCRIPT_NAME sitemap page, exiting" "$CRIT" flock -u "$FD" return 1 fi cp -f "$SCRIPT_DIR/sitemap.asp" "$SCRIPT_WEBPAGE_DIR/$MyPage" sed -i "\\~$MyPage~d" /tmp/menuTree.js sed -i "/url: \"javascript:var helpwindow=window.open('\/ext\/shared-jy\/redirect.htm'/a {url: \"$MyPage\", tabName: \"Sitemap\"}," /tmp/menuTree.js umount /www/state.js 2>/dev/null cp -f /www/state.js /tmp/ sed -i 's~~Sitemap<\/a>\ \|\ ~' /tmp/state.js cat << 'EOF' >> /tmp/state.js var myMenu = []; function AddDropdowns(){ if(myMenu.length == 0){ setTimeout(AddDropdowns,1000); return; } for(var i = 0; i < myMenu.length; i++){ var sitemapstring = '