#!/bin/sh ########################################################## ## ## ## __ __ _____ _ _ _____ _____ ## ## \ \ / / | __ \ | | | | / ____|| __ \ ## ## \ \_/ /__ _ ____| | | || |__| || | | |__) | ## ## \ // _` ||_ /| | | || __ || | | ___/ ## ## | || (_| | / / | |__| || | | || |____ | | ## ## |_| \__,_|/___||_____/ |_| |_| \_____||_| ## ## ## ## https://github.com/jackyaz/YazDHCP/ ## ## ## ########################################################## # Last Modified: 2023-Nov-17 #--------------------------------------------------------- ############################################# # shellcheck disable=SC2012 # shellcheck disable=SC2016 # shellcheck disable=SC2059 # shellcheck disable=SC2155 # shellcheck disable=SC3043 # shellcheck disable=SC3045 ############################################# ### Start of script variables ### readonly SCRIPT_NAME="YazDHCP" readonly SCRIPT_VERSION="v1.0.6" SCRIPT_BRANCH="master" SCRIPT_REPO="https://jackyaz.io/$SCRIPT_NAME/$SCRIPT_BRANCH" readonly SCRIPT_DIR="/jffs/addons/$SCRIPT_NAME.d" readonly SCRIPT_CONF="$SCRIPT_DIR/DHCP_clients" readonly SCRIPT_WEBPAGE_DIR="$(readlink /www/user)" readonly SCRIPT_WEB_DIR="$SCRIPT_WEBPAGE_DIR/$SCRIPT_NAME" 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" ### 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" ### End of output format variables ### ### Start of router environment variables ### [ -z "$(nvram get odmpid)" ] && ROUTER_MODEL=$(nvram get productid) || ROUTER_MODEL=$(nvram get odmpid) ### End of router environment variables ### ##----------------------------------------------## ## Added/modified by Martinski W. [2023-May-28] ## ##----------------------------------------------## # DHCP Lease Time: Min & Max Values in seconds. # 2 minutes=120 to 90 days=7776000 (inclusive). # Single '0' or 'I' indicates "infinite" value. # For NVRAM the "infinite" value (in secs.) is # 1092 days (i.e. 156 weeks, or ~=3 years). #------------------------------------------------# readonly MinDHCPLeaseTime=120 readonly MaxDHCPLeaseTime=7776000 readonly InfiniteLeaseTimeTag="I" readonly InfiniteLeaseTimeSecs=94348800 readonly YazDHCP_LEASEtag="DHCP_LEASE" readonly DHCP_LEASE_KEYN="dhcp_lease" readonly DHCP_LEASE_FILE="DHCP_Lease" readonly SCRIPT_DHCP_LEASE_CONF="${SCRIPT_DIR}/$DHCP_LEASE_FILE" ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-16] ## ##----------------------------------------------## ## Start of script variables for the "Save Custom User Icons" feature ## ##--------------------------------------------------------------------## readonly theJFFSdir="/jffs" readonly userIconsDIRname="usericon" readonly userIconsDIRpath="${theJFFSdir}/$userIconsDIRname" readonly userIconsSavedFLEextn="tar.gzip" readonly userIconsSavedFLEname="CustomUserIcons" readonly userIconsSavedDIRname="SavedUserIcons" readonly userIconsSavedCFGname="CustomUserIconsConfig" readonly userIconsSavedSTAname="CustomUserIconsStatus" readonly defUserIconsBackupDir="/opt/var/$userIconsSavedDIRname" readonly altUserIconsBackupDir="/jffs/configs/$userIconsSavedDIRname" readonly userIconsVarPrefix="Icons_" readonly savedFileDateTimeStr="%Y-%m-%d_%H-%M-%S" readonly NVRAM_Folder="${theJFFSdir}/nvram" readonly NVRAM_ClientsKeyName="custom_clientlist" readonly NVRAM_ClientsKeyVARsaved="${userIconsDIRpath}/NVRAMvar_${NVRAM_ClientsKeyName}.TMP" readonly NVRAM_ClientsKeyFLEsaved="${userIconsDIRpath}/NVRAMfile_${NVRAM_ClientsKeyName}.TMP" readonly SCRIPT_USER_ICONS_STATUS="/tmp/$userIconsSavedSTAname" readonly SCRIPT_USER_ICONS_CONFIG="${SCRIPT_DIR}/$userIconsSavedCFGname" readonly userIconsCFGCommentLine="## DO *NOT* EDIT THIS FILE BELOW THIS LINE. IT'S DYNAMICALLY UPDATED ##" readonly userIconsBKPListHeader="From directory:" readonly userIconsSavedBKPList="CustomUserIconsBackupList" readonly SCRIPT_USER_ICONS_BKPLST="/tmp/$userIconsSavedBKPList" readonly theHighWaterMarkThreshold=5 readonly theMinUserIconsBackupFiles=5 readonly theMaxUserIconsBackupFiles=50 readonly defMaxUserIconsBackupFiles=20 readonly NOct="\033[0m" readonly BOLDtext="\033[1m" readonly DarkRED="\033[0;31m" readonly LghtGREEN="\033[1;32m" readonly LghtYELLOW="\033[1;33m" readonly REDct="${DarkRED}${BOLDtext}" readonly GRNct="${LghtGREEN}${BOLDtext}" readonly YLWct="${LghtYELLOW}${BOLDtext}" readonly MaxBckupsOpt="mx" readonly BackupDirOpt="dp" readonly BkupIconsOpt="bk" readonly RestIconsOpt="rt" readonly DeltIconsOpt="de" readonly ListIconsOpt="ls" iconsFound=false backupsFound=false waitToConfirm=false inStartupMode=false maxUserIconsBackupFiles="$defMaxUserIconsBackupFiles" theUserIconsBackupDir="$defUserIconsBackupDir" prefUserIconsBackupDir="$theUserIconsBackupDir" userIconsBackupFPath="${theUserIconsBackupDir}/$userIconsSavedFLEname" theBackupFilesMatch="${userIconsBackupFPath}_*.$userIconsSavedFLEextn" ##------------------------------------------------------------------## ## End of script variables for the "Save Custom User Icons" feature ## ##==================================================================## # $1 = print to syslog, $2 = message to print, $3 = log level Print_Output(){ if [ "$1" = "true" ]; then logger -t "$SCRIPT_NAME" "$2" printf "\\e[1m$3%s: $2\\e[0m\\n\\n" "$SCRIPT_NAME" else printf "\\e[1m$3%s: $2\\e[0m\\n\\n" "$SCRIPT_NAME" fi } Firmware_Version_Check(){ if nvram get rc_support | grep -qF "am_addons"; then return 0 else return 1 fi } ### Code for this function courtesy of https://github.com/decoderman- credit to @thelonelycoder ### Firmware_Version_Number(){ echo "$1" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }' } ############################################################################ ### Code for these functions inspired by https://github.com/Adamm00 - credit to @Adamm ### Check_Lock(){ if [ -f "/tmp/$SCRIPT_NAME.lock" ]; then ageoflock=$(($(date +%s) - $(date +%s -r /tmp/$SCRIPT_NAME.lock))) if [ "$ageoflock" -gt 600 ]; then Print_Output true "Stale lock file found (>600 seconds old) - purging lock" "$ERR" kill "$(sed -n '1p' /tmp/$SCRIPT_NAME.lock)" >/dev/null 2>&1 Clear_Lock echo "$$" > "/tmp/$SCRIPT_NAME.lock" return 0 else Print_Output true "Lock file found (age: $ageoflock seconds) - stopping to prevent duplicate runs" "$ERR" if [ -z "$1" ]; then exit 1 else if [ "$1" = "webui" ]; then exit 1 fi return 1 fi fi else echo "$$" > "/tmp/$SCRIPT_NAME.lock" return 0 fi } Clear_Lock(){ rm -f "/tmp/$SCRIPT_NAME.lock" 2>/dev/null return 0 } ############################################################################ Validate_IP(){ if expr "$1" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then for i in 1 2 3 4; do if [ "$(echo "$1" | cut -d. -f$i)" -gt 255 ]; then Print_Output false "Octet $i ($(echo "$1" | cut -d. -f$i)) - is invalid, must be less than 255" "$ERR" return 1 fi done else Print_Output false "$1 - is not a valid IPv4 address, valid format is 1.2.3.4" "$ERR" return 1 fi } ##----------------------------------------------## ## Added/modified by Martinski W. [2023-Jan-30] ## ##----------------------------------------------## # The DHCP Lease Time values can be given in: # seconds, minutes, hours, days, or weeks. # Single '0' or 'I' indicates "infinite" value. #------------------------------------------------# DHCP_LeaseValueToSeconds() { if [ $# -eq 0 ] || [ -z "$1" ] then echo "-1" ; return 1 ; fi timeUnits="X" timeFactor=1 timeNumber="$1" if [ "$1" = "0" ] || [ "$1" = "$InfiniteLeaseTimeTag" ] then echo "$InfiniteLeaseTimeSecs" ; return 0 ; fi if echo "$1" | grep -q "^0.*" then echo "-1" ; return 1 ; fi if echo "$1" | grep -q "^[0-9]\{1,7\}$" then timeUnits="s" timeNumber="$1" elif echo "$1" | grep -q "^[0-9]\{1,6\}[smhdw]\{1\}$" then timeUnits="$(echo "$1" | awk '{print substr($0,length($0),1)}')" timeNumber="$(echo "$1" | awk '{print substr($0,0,length($0)-1)}')" fi case "$timeUnits" in s) timeFactor=1 ;; m) timeFactor=60 ;; h) timeFactor=3600 ;; d) timeFactor=86400 ;; w) timeFactor=604800 ;; esac if ! echo "$timeNumber" | grep -q "^[0-9]\{1,7\}$" then echo "-1" ; return 1 ; fi timeValue="$((timeNumber * timeFactor))" echo "$timeValue" } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-May-28] ## ##----------------------------------------------## Check_DHCP_LeaseTime() { NVRAM_LeaseTime="$(nvram get $DHCP_LEASE_KEYN)" if [ ! -f "$SCRIPT_DHCP_LEASE_CONF" ] then echo "## DO *NOT* EDIT THIS FILE. IT'S DYNAMICALLY UPDATED ##" > "$SCRIPT_DHCP_LEASE_CONF" echo "DHCP_LEASE=$NVRAM_LeaseTime" >> "$SCRIPT_DHCP_LEASE_CONF" return 1 fi if ! grep -q "^DHCP_LEASE=" "$SCRIPT_DHCP_LEASE_CONF" then echo "DHCP_LEASE=$NVRAM_LeaseTime" >> "$SCRIPT_DHCP_LEASE_CONF" return 1 fi LeaseValue="$(grep "^DHCP_LEASE=" "$SCRIPT_DHCP_LEASE_CONF" | awk -F '=' '{print $2}')" if [ -z "$LeaseValue" ] then sed -i "s/DHCP_LEASE=.*/DHCP_LEASE=$NVRAM_LeaseTime/" "$SCRIPT_DHCP_LEASE_CONF" return 1 fi LeaseTime="$(DHCP_LeaseValueToSeconds "$LeaseValue")" if [ "$LeaseTime" = "$InfiniteLeaseTimeSecs" ] && \ [ "$LeaseTime" != "$NVRAM_LeaseTime" ] then nvram set ${DHCP_LEASE_KEYN}="$LeaseTime" DO_NVRAM_COMMIT=true RESTART_DNSMASQ=true return 0 fi if [ "$LeaseTime" = "-1" ] || \ [ "$LeaseTime" -lt "$MinDHCPLeaseTime" ] || \ [ "$LeaseTime" -gt "$MaxDHCPLeaseTime" ] || \ [ "$LeaseTime" -eq "$NVRAM_LeaseTime" ] then return 1 ; fi nvram set ${DHCP_LEASE_KEYN}="$LeaseTime" DO_NVRAM_COMMIT=true RESTART_DNSMASQ=true return 0 } ##-------------------------------------## ## Added by Martinski W. [2023-Apr-01] ## ##-------------------------------------## GetFromCustomUserIconsConfig() { keyName="${userIconsVarPrefix}$1" if [ $# -eq 0 ] || [ -z "$1" ] || \ [ ! -f "$SCRIPT_USER_ICONS_CONFIG" ] || \ ! grep -q "^${keyName}=" "$SCRIPT_USER_ICONS_CONFIG" then echo "" ; return 1 ; fi keyValue="$(grep "^${keyName}=" "$SCRIPT_USER_ICONS_CONFIG" | awk -F '=' '{print $2}')" echo "$keyValue" ; return 0 } FixCustomUserIconsConfig() { if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ] ; then return 1; fi keyName="${userIconsVarPrefix}$1" if ! grep -q "^${keyName}=" "$SCRIPT_USER_ICONS_CONFIG" then echo "${keyName}=$2" >> "$SCRIPT_USER_ICONS_CONFIG" return 0 fi keyValue="$(grep "^${keyName}=" "$SCRIPT_USER_ICONS_CONFIG" | awk -F '=' '{print $2}')" if [ -z "$keyValue" ] then fixedVal="$(echo "$2" | sed 's/[\/.*-]/\\&/g')" sed -i "s/${keyName}=.*/${keyName}=${fixedVal}/" "$SCRIPT_USER_ICONS_CONFIG" fi } ClearCustomUserIconsStatus() { rm -f "$SCRIPT_USER_ICONS_STATUS" ; } UpdateCustomUserIconsStatus() { if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ] ; then return 1; fi if [ "$2" = "NONE" ] || [ ! -f "$2" ] then echo "${userIconsVarPrefix}${1}=NONE" > "$SCRIPT_USER_ICONS_STATUS" else echo "${userIconsVarPrefix}DIRP=${2%/*}" > "$SCRIPT_USER_ICONS_STATUS" echo "${userIconsVarPrefix}FILE=${2##*/}" >> "$SCRIPT_USER_ICONS_STATUS" echo "${userIconsVarPrefix}${1}=OK" >> "$SCRIPT_USER_ICONS_STATUS" fi } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-14] ## ##----------------------------------------------## UpdateCustomUserIconsConfig() { if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ] ; then return 1; fi if [ "$1" = "SAVED_DIR" ] then theUserIconsBackupDir="$2" userIconsBackupFPath="${2}/$userIconsSavedFLEname" theBackupFilesMatch="${userIconsBackupFPath}_*.$userIconsSavedFLEextn" fi if [ "$1" = "PREFS_DIR" ] then prefUserIconsBackupDir="$2" fi if [ $# -eq 3 ] && [ "$3" = "STATUSupdate" ] && \ { [ "$1" = "SAVED" ] || [ "$1" = "RESTD" ] ; } && \ { [ "$2" = "NONE" ] || [ -f "$2" ] ; } then UpdateCustomUserIconsStatus "$1" "$2" ; fi keyName="${userIconsVarPrefix}$1" if ! grep -q "^${keyName}=" "$SCRIPT_USER_ICONS_CONFIG" then echo "${keyName}=$2" >> "$SCRIPT_USER_ICONS_CONFIG" return 0 fi keyValue="$(grep "^${keyName}=" "$SCRIPT_USER_ICONS_CONFIG" | awk -F '=' '{print $2}')" if [ -z "$keyValue" ] || [ "$keyValue" != "$2" ] then fixedVal="$(echo "$2" | sed 's/[\/.*-]/\\&/g')" sed -i "s/${keyName}=.*/${keyName}=${fixedVal}/" "$SCRIPT_USER_ICONS_CONFIG" fi } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-14] ## ##----------------------------------------------## InitCustomUserIconsConfig() { thePrefix="$userIconsVarPrefix" if [ ! -f "$SCRIPT_USER_ICONS_CONFIG" ] then { echo "$userIconsCFGCommentLine" echo "${thePrefix}SAVED_MAX=20" echo "${thePrefix}SAVED_DIR=NONE" echo "${thePrefix}PREFS_DIR=NONE" echo "${thePrefix}FOUND=FALSE" echo "${thePrefix}SAVED=NONE" echo "${thePrefix}RESTD=NONE" } > "$SCRIPT_USER_ICONS_CONFIG" return 0 fi commentStr="$(echo "$userIconsCFGCommentLine" | sed 's/[.*-]/\\&/g')" nFoundStr="$(grep -n "^${commentStr}" "$SCRIPT_USER_ICONS_CONFIG")" if [ -z "$nFoundStr" ] || \ [ "$(echo "$nFoundStr" | awk -F ':' '{print $1}')" -ne 1 ] then sed -i "\\~${commentStr}~d" "$SCRIPT_USER_ICONS_CONFIG" sed -i "1 i ${userIconsCFGCommentLine}" "$SCRIPT_USER_ICONS_CONFIG" fi if ! grep -q "^${thePrefix}SAVED_DIR=" "$SCRIPT_USER_ICONS_CONFIG" then sed -i "2 i ${thePrefix}SAVED_DIR=NONE" "$SCRIPT_USER_ICONS_CONFIG" fi if ! grep -q "^${thePrefix}SAVED_MAX=" "$SCRIPT_USER_ICONS_CONFIG" then sed -i "2 i ${thePrefix}SAVED_MAX=20" "$SCRIPT_USER_ICONS_CONFIG" fi if ! grep -q "^${thePrefix}PREFS_DIR=" "$SCRIPT_USER_ICONS_CONFIG" then sed -i "4 i ${thePrefix}PREFS_DIR=NONE" "$SCRIPT_USER_ICONS_CONFIG" fi return 1 } ##-------------------------------------## ## Added by Martinski W. [2023-Jun-15] ## ##-------------------------------------## ValidateUserIconsBackupDirectory() { if [ $# -eq 0 ] || [ -z "$1" ] ; then return 1; fi [ ! -d "$theUserIconsBackupDir" ] && mkdir -m 755 "$theUserIconsBackupDir" 2>/dev/null if [ ! -d "$theUserIconsBackupDir" ] then Print_Output true "**ERROR**: Backup directory [$theUserIconsBackupDir] NOT FOUND." "$ERR" theUserIconsBackupDir="$1" Print_Output true "Trying again with directory [$theUserIconsBackupDir]" "$PASS" switchBackupDir=true return 1 fi return 0 } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-16] ## ##----------------------------------------------## GetUserIconsSavedVars() { switchBackupDir=false savdUserIconsBackupDir="$(GetFromCustomUserIconsConfig "SAVED_DIR")" prefUserIconsBackupDir="$(GetFromCustomUserIconsConfig "PREFS_DIR")" if [ -z "$savdUserIconsBackupDir" ] || [ "$savdUserIconsBackupDir" = "NONE" ] then savdUserIconsBackupDir="$defUserIconsBackupDir" ; fi if [ -z "$prefUserIconsBackupDir" ] || [ "$prefUserIconsBackupDir" = "NONE" ] then prefUserIconsBackupDir="$savdUserIconsBackupDir" UpdateCustomUserIconsConfig PREFS_DIR "$prefUserIconsBackupDir" fi theUserIconsBackupDir="$prefUserIconsBackupDir" for nextBKdir in "$savdUserIconsBackupDir" "$defUserIconsBackupDir" "$altUserIconsBackupDir" do ValidateUserIconsBackupDirectory "$nextBKdir" && break ; done mkdir -m 755 "$theUserIconsBackupDir" 2>/dev/null if [ ! -d "$theUserIconsBackupDir" ] then Print_Output true "**ERROR**: Backup directory [$theUserIconsBackupDir] NOT FOUND." "$ERR" return 1 fi if "$switchBackupDir" then if "$inStartupMode" then LogMsg="*WARNING*: Temporary Backup directory [$theUserIconsBackupDir]" else LogMsg="*WARNING*: Alternative Backup directory [$theUserIconsBackupDir]" fi Print_Output true "$LogMsg" "$WARN" _WaitForEnterKey_ fi ! "$inStartupMode" && UpdateCustomUserIconsConfig SAVED_DIR "$theUserIconsBackupDir" maxUserIconsBackupFiles="$(GetFromCustomUserIconsConfig "SAVED_MAX")" if [ -z "$maxUserIconsBackupFiles" ] || \ ! echo "$maxUserIconsBackupFiles" | grep -qE "^[0-9]{1,}$" then maxUserIconsBackupFiles="$defMaxUserIconsBackupFiles" ; fi if [ "$maxUserIconsBackupFiles" -lt "$theMinUserIconsBackupFiles" ] then maxUserIconsBackupFiles="$theMinUserIconsBackupFiles" ; fi if [ "$maxUserIconsBackupFiles" -gt "$theMaxUserIconsBackupFiles" ] then maxUserIconsBackupFiles="$theMaxUserIconsBackupFiles" ; fi UpdateCustomUserIconsConfig SAVED_MAX "$maxUserIconsBackupFiles" return 0 } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-14] ## ##----------------------------------------------## Check_CustomUserIconsConfig() { if ! InitCustomUserIconsConfig then FixCustomUserIconsConfig FOUND FALSE FixCustomUserIconsConfig SAVED NONE FixCustomUserIconsConfig RESTD NONE FixCustomUserIconsConfig SAVED_MAX "$defMaxUserIconsBackupFiles" FixCustomUserIconsConfig SAVED_DIR "$defUserIconsBackupDir" FixCustomUserIconsConfig PREFS_DIR "$defUserIconsBackupDir" fi GetUserIconsSavedVars } ##----------------------------------------## ## Modified by Martinski W. [2023-May-31] ## ##----------------------------------------## Conf_FromSettings() { SETTINGSFILE="/jffs/addons/custom_settings.txt" TMPFILE="/tmp/yazdhcp_clients.tmp" if [ -f "$SETTINGSFILE" ]; then if [ "$(grep -E "yazdhcp_|^$YazDHCP_LEASEtag" $SETTINGSFILE | grep -v "version" -c)" -gt 0 ]; then Print_Output true "Updated DHCP information from WebUI found, merging into $SCRIPT_CONF" "$PASS" cp -a "$SCRIPT_CONF" "$SCRIPT_CONF.bak" grep -E "yazdhcp_|^$YazDHCP_LEASEtag" "$SETTINGSFILE" | grep -v "version" > "$TMPFILE" sed -i "s/yazdhcp_//g;s/ /=/g" "$TMPFILE" DHCPCLIENTS="" while IFS='' read -r line || [ -n "$line" ] do if echo "$line" | grep -q "^${YazDHCP_LEASEtag}=" then LEASE_VALUE="$(echo "$line" | cut -d '=' -f2)" sed -i "s/DHCP_LEASE=.*/DHCP_LEASE=$LEASE_VALUE/" "$SCRIPT_DHCP_LEASE_CONF" continue fi DHCPCLIENTS="${DHCPCLIENTS}$(echo "$line" | cut -f2 -d'=')" done < "$TMPFILE" echo "$DHCPCLIENTS" | sed 's/|/:/g;s/>/ /g;s/ /tmp/yazdhcp_clients_parsed.tmp DO_NVRAM_COMMIT=false echo "MAC,IP,HOSTNAME,DNS" > "$SCRIPT_CONF" while IFS='' read -r line || [ -n "$line" ] do if ! CheckAgainstNVRAMvar "$line" ; then DO_NVRAM_COMMIT=true ; fi if [ "$(echo "$line" | wc -w)" -eq 4 ]; then echo "$line" | awk '{ print ""$1","$2","$3","$4""; }' >> "$SCRIPT_CONF" elif [ "$(echo "$line" | wc -w)" -gt 1 ]; then if [ "$(echo "$line" | cut -d " " -f3 | wc -L)" -eq 0 ]; then echo "$line" | awk '{ print ""$1","$2","","$3""; }' >> "$SCRIPT_CONF" else printf "%s,\\n" "$(echo "$line" | sed 's/ /,/g')" >> "$SCRIPT_CONF" fi fi done < /tmp/yazdhcp_clients_parsed.tmp LANSUBNET="$(nvram get lan_ipaddr | cut -d'.' -f1-3)" LANNETMASK="$(nvram get lan_netmask)" if [ "$LANNETMASK" = "255.255.255.0" ]; then awk -F "," -v lansub="$LANSUBNET" 'FNR==1{print $0; next} BEGIN {OFS = ","} $2=lansub"."$2' "$SCRIPT_CONF" > "$SCRIPT_CONF.tmp" else cp "$SCRIPT_CONF" "$SCRIPT_CONF.tmp" fi sort -t . -k 3,3n -k 4,4n "$SCRIPT_CONF.tmp" > "$SCRIPT_CONF" rm -f "$SCRIPT_CONF.tmp" grep 'yazdhcp_version' "$SETTINGSFILE" > "$TMPFILE" sed -i "\\~yazdhcp_~d" "$SETTINGSFILE" sed -i "\\~${YazDHCP_LEASEtag}~d" "$SETTINGSFILE" mv "$SETTINGSFILE" "$SETTINGSFILE.bak" cat "$SETTINGSFILE.bak" "$TMPFILE" > "$SETTINGSFILE" rm -f /tmp/yazdhcp* rm -f "$SETTINGSFILE.bak" RESTART_DNSMASQ="$DO_NVRAM_COMMIT" Check_DHCP_LeaseTime Update_Hostnames Update_Staticlist Update_Optionslist if "$DO_NVRAM_COMMIT" ; then nvram commit ; fi Print_Output true "Merge of updated DHCP client information from WebUI completed successfully" "$PASS" if "$RESTART_DNSMASQ" then Print_Output true "Restarting dnsmasq for new DHCP settings to take effect." "$PASS" ## Delay restarting dnsmasq until the one from WebGUI is completed ## (sleep 2 ; service restart_dnsmasq >/dev/null 2>&1) & fi else Print_Output false "No updated DHCP information from WebUI found, no merge into $SCRIPT_CONF necessary" "$PASS" fi fi } Set_Version_Custom_Settings(){ SETTINGSFILE="/jffs/addons/custom_settings.txt" case "$1" in local) if [ -f "$SETTINGSFILE" ]; then if [ "$(grep -c "yazdhcp_version_local" $SETTINGSFILE)" -gt 0 ]; then if [ "$SCRIPT_VERSION" != "$(grep "yazdhcp_version_local" /jffs/addons/custom_settings.txt | cut -f2 -d' ')" ]; then sed -i "s/yazdhcp_version_local.*/yazdhcp_version_local $SCRIPT_VERSION/" "$SETTINGSFILE" fi else echo "yazdhcp_version_local $SCRIPT_VERSION" >> "$SETTINGSFILE" fi else echo "yazdhcp_version_local $SCRIPT_VERSION" >> "$SETTINGSFILE" fi ;; server) if [ -f "$SETTINGSFILE" ]; then if [ "$(grep -c "yazdhcp_version_server" $SETTINGSFILE)" -gt 0 ]; then if [ "$2" != "$(grep "yazdhcp_version_server" /jffs/addons/custom_settings.txt | cut -f2 -d' ')" ]; then sed -i "s/yazdhcp_version_server.*/yazdhcp_version_server $2/" "$SETTINGSFILE" fi else echo "yazdhcp_version_server $2" >> "$SETTINGSFILE" fi else echo "yazdhcp_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" | 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.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.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" | awk '{print $1}')" remotemd5="$(curl -fsL --retry 3 "$SCRIPT_REPO/md5/$SCRIPT_NAME.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" } ##----------------------------------------## ## Modified by Martinski W. [2023-May-28] ## ##----------------------------------------## Update_Version(){ if [ $# -eq 0 ] || [ -z "$1" ] || [ "$1" = "unattended" ]; 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 - updating to $serverver" "$PASS" elif [ "$isupdate" = "md5" ]; then Print_Output true "MD5 hash of $SCRIPT_NAME does not match - downloading updated $serverver" "$PASS" fi Update_File shared-jy.tar.gz if [ "$isupdate" != "false" ]; then Update_File Advanced_DHCP_Content.asp Download_File "$SCRIPT_REPO/update/$SCRIPT_NAME.sh" "/jffs/scripts/$SCRIPT_NAME" && Print_Output true "$SCRIPT_NAME successfully updated" "$PASS" chmod 0755 /jffs/scripts/"$SCRIPT_NAME" Clear_Lock if [ -z "$1" ]; then exec "$0" setversion elif [ "$1" = "unattended" ]; then exec "$0" setversion unattended fi exit 0 else Print_Output true "No new version - latest is $localver" "$WARN" Clear_Lock fi fi if [ $# -gt 0 ] && [ "$1" = "force" ]; then serverver=$(/usr/sbin/curl -fsL --retry 3 "$SCRIPT_REPO/version/$SCRIPT_NAME.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 Advanced_DHCP_Content.asp Update_File shared-jy.tar.gz Download_File "$SCRIPT_REPO/update/$SCRIPT_NAME.sh" "/jffs/scripts/$SCRIPT_NAME" && Print_Output true "$SCRIPT_NAME successfully updated" "$PASS" chmod 0755 /jffs/scripts/"$SCRIPT_NAME" Clear_Lock if [ $# -eq 1 ] || [ -z "$2" ]; then exec "$0" setversion elif [ "$2" = "unattended" ]; then exec "$0" setversion unattended fi exit 0 fi } Update_File(){ if [ "$1" = "Advanced_DHCP_Content.asp" ]; 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" 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 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 } ##----------------------------------------------## ## Added/modified by Martinski W. [2023-May-28] ## ##----------------------------------------------## Create_DHCP_LeaseConfig() { Check_DHCP_LeaseTime && nvram commit ln -sf "$SCRIPT_DHCP_LEASE_CONF" "${SCRIPT_WEB_DIR}/${DHCP_LEASE_FILE}.htm" 2>/dev/null } ##----------------------------------------------## ## Added/modified by Martinski W. [2023-Apr-16] ## ##----------------------------------------------## Create_CustomUserIconsConfig() { Check_CustomUserIconsConfig ln -sf "$SCRIPT_USER_ICONS_CONFIG" "${SCRIPT_WEB_DIR}/${userIconsSavedCFGname}.htm" 2>/dev/null ln -sf "$SCRIPT_USER_ICONS_STATUS" "${SCRIPT_WEB_DIR}/${userIconsSavedSTAname}.htm" 2>/dev/null ln -sf "$SCRIPT_USER_ICONS_BKPLST" "${SCRIPT_WEB_DIR}/${userIconsSavedBKPList}.htm" 2>/dev/null } ##----------------------------------------## ## Modified by Martinski W. [2023-Apr-01] ## ##----------------------------------------## Create_Symlinks(){ rm -rf "${SCRIPT_WEB_DIR:?}/"* 2>/dev/null ln -s "$SCRIPT_CONF" "$SCRIPT_WEB_DIR/DHCP_clients.htm" 2>/dev/null Create_DHCP_LeaseConfig Create_CustomUserIconsConfig if [ ! -d "$SHARED_WEB_DIR" ]; then ln -s "$SHARED_DIR" "$SHARED_WEB_DIR" 2>/dev/null fi } ##----------------------------------------## ## Modified by Martinski W. [2023-Mar-14] ## ##----------------------------------------## 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"'" ; then { /jffs/scripts/'"$SCRIPT_NAME"' 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"'" ; then { /jffs/scripts/'"$SCRIPT_NAME"' 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"'" ; then { /jffs/scripts/'"$SCRIPT_NAME"' 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 -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 } Auto_Startup(){ case $1 in create) if [ -f /jffs/scripts/services-start ]; then STARTUPLINECOUNT=$(grep -c '# '"$SCRIPT_NAME" /jffs/scripts/services-start) STARTUPLINECOUNTEX=$(grep -cx "/jffs/scripts/$SCRIPT_NAME 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 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 startup"' "$@" & # '"$SCRIPT_NAME" >> /jffs/scripts/services-start chmod 0755 /jffs/scripts/services-start fi ;; delete) if [ -f /jffs/scripts/services-start ]; then STARTUPLINECOUNT=$(grep -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 } Auto_DNSMASQ(){ case $1 in create) if [ -f /jffs/configs/dnsmasq.conf.add ]; then CONFCHANGED="false" STARTUPLINECOUNT=$(grep -c "# ${SCRIPT_NAME}_hostnames" /jffs/configs/dnsmasq.conf.add) STARTUPLINECOUNTEX=$(grep -cx "addn-hosts=$SCRIPT_DIR/.hostnames # ${SCRIPT_NAME}_hostnames" /jffs/configs/dnsmasq.conf.add) if [ "$STARTUPLINECOUNT" -gt 1 ] || { [ "$STARTUPLINECOUNTEX" -eq 0 ] && [ "$STARTUPLINECOUNT" -gt 0 ]; }; then sed -i -e '/# '"${SCRIPT_NAME}_hostnames"'/d' /jffs/configs/dnsmasq.conf.add fi if [ "$STARTUPLINECOUNTEX" -eq 0 ]; then echo "addn-hosts=$SCRIPT_DIR/.hostnames # ${SCRIPT_NAME}_hostnames" >> /jffs/configs/dnsmasq.conf.add CONFCHANGED="true" fi STARTUPLINECOUNT=$(grep -c "# ${SCRIPT_NAME}_staticlist" /jffs/configs/dnsmasq.conf.add) STARTUPLINECOUNTEX=$(grep -cx "dhcp-hostsfile=$SCRIPT_DIR/.staticlist # ${SCRIPT_NAME}_staticlist" /jffs/configs/dnsmasq.conf.add) if [ "$STARTUPLINECOUNT" -gt 1 ] || { [ "$STARTUPLINECOUNTEX" -eq 0 ] && [ "$STARTUPLINECOUNT" -gt 0 ]; }; then sed -i -e '/# '"${SCRIPT_NAME}_staticlist"'/d' /jffs/configs/dnsmasq.conf.add fi if [ "$STARTUPLINECOUNTEX" -eq 0 ]; then echo "dhcp-hostsfile=$SCRIPT_DIR/.staticlist # ${SCRIPT_NAME}_staticlist" >> /jffs/configs/dnsmasq.conf.add CONFCHANGED="true" fi STARTUPLINECOUNT=$(grep -c "# ${SCRIPT_NAME}_optionslist" /jffs/configs/dnsmasq.conf.add) STARTUPLINECOUNTEX=$(grep -cx "dhcp-optsfile=$SCRIPT_DIR/.optionslist # ${SCRIPT_NAME}_optionslist" /jffs/configs/dnsmasq.conf.add) if [ "$STARTUPLINECOUNT" -gt 1 ] || { [ "$STARTUPLINECOUNTEX" -eq 0 ] && [ "$STARTUPLINECOUNT" -gt 0 ]; }; then sed -i -e '/# '"${SCRIPT_NAME}_optionslist"'/d' /jffs/configs/dnsmasq.conf.add fi if [ "$STARTUPLINECOUNTEX" -eq 0 ]; then echo "dhcp-optsfile=$SCRIPT_DIR/.optionslist # ${SCRIPT_NAME}_optionslist" >> /jffs/configs/dnsmasq.conf.add CONFCHANGED="true" fi if [ "$CONFCHANGED" = "true" ]; then service restart_dnsmasq >/dev/null 2>&1 fi else { echo ""; echo "addn-hosts=$SCRIPT_DIR/.hostnames # ${SCRIPT_NAME}_hostnames"; echo "dhcp-hostsfile=$SCRIPT_DIR/.staticlist # ${SCRIPT_NAME}_staticlist"; echo "dhcp-optsfile=$SCRIPT_DIR/.optionslist # ${SCRIPT_NAME}_optionslist"; } >> /jffs/configs/dnsmasq.conf.add chmod 0644 /jffs/configs/dnsmasq.conf.add service restart_dnsmasq >/dev/null 2>&1 fi ;; delete) if [ -f /jffs/configs/dnsmasq.conf.add ]; then CONFCHANGED="false" STARTUPLINECOUNT=$(grep -c "# ${SCRIPT_NAME}_hostnames" /jffs/configs/dnsmasq.conf.add) if [ "$STARTUPLINECOUNT" -gt 0 ]; then sed -i -e '/# '"${SCRIPT_NAME}_hostnames"'/d' /jffs/configs/dnsmasq.conf.add CONFCHANGED="true" fi STARTUPLINECOUNT=$(grep -c "# ${SCRIPT_NAME}_staticlist" /jffs/configs/dnsmasq.conf.add) if [ "$STARTUPLINECOUNT" -gt 0 ]; then sed -i -e '/# '"${SCRIPT_NAME}_staticlist"'/d' /jffs/configs/dnsmasq.conf.add CONFCHANGED="true" fi STARTUPLINECOUNT=$(grep -c "# ${SCRIPT_NAME}_optionslist" /jffs/configs/dnsmasq.conf.add) if [ "$STARTUPLINECOUNT" -gt 0 ]; then sed -i -e '/# '"${SCRIPT_NAME}_optionslist"'/d' /jffs/configs/dnsmasq.conf.add CONFCHANGED="true" fi if [ "$CONFCHANGED" = "true" ]; then service restart_dnsmasq >/dev/null 2>&1 fi fi ;; esac } Download_File(){ /usr/sbin/curl -fsL --retry 3 "$1" -o "$2" } Mount_WebUI(){ umount /www/Advanced_DHCP_Content.asp 2>/dev/null mount -o bind "$SCRIPT_DIR/Advanced_DHCP_Content.asp" /www/Advanced_DHCP_Content.asp } Shortcut_Script(){ case $1 in create) if [ -d /opt/bin ] && [ ! -f "/opt/bin/$SCRIPT_NAME" ] && [ -f "/jffs/scripts/$SCRIPT_NAME" ]; then ln -s /jffs/scripts/"$SCRIPT_NAME" /opt/bin chmod 0755 /opt/bin/"$SCRIPT_NAME" fi ;; delete) if [ -f "/opt/bin/$SCRIPT_NAME" ]; then rm -f /opt/bin/"$SCRIPT_NAME" fi ;; esac } PressEnter(){ while true; do printf "Press enter to continue..." read -r key case "$key" in *) break ;; esac done return 0 } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Nov-16] ## ##----------------------------------------------## #-------------------------------------------------------# # NOTE for disabling shellcheck 2086 [Martinski W.] # The first parameter [$1] MUST be UNQUOTED because it # can be a file path argument that contains a wildcard # char [*] which when quoted is taken as a _literal_ # asterisk, and that leads to a failed execution. # GOOD call example: # mv -f /PATH/TO/DIR/FileName_*.tar "/PATH/TO/NEW/DIR" #-------------------------------------------------------# # shellcheck disable=SC2086 _movef_() { if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ] then return 1 ; fi local prevIFS="$IFS" IFS="$(printf '\n\t')" mv -f $1 "$2" ; retcode="$?" IFS="$prevIFS" return "$retcode" } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Nov-16] ## ##----------------------------------------------## #-------------------------------------------------------# # NOTE for disabling shellcheck 2086 [Martinski W.] # The single parameter [$1] MUST be UNQUOTED because it # can be a file path argument that contains a wildcard # char [*] which when quoted is taken as a _literal_ # asterisk, and that leads to a failed execution. # GOOD call example: # rm -f /PATH/TO/DIR/FileName_*.tar #-------------------------------------------------------# # shellcheck disable=SC2086 _remf_() { if [ $# -lt 1 ] || [ -z "$1" ] || [ "$1" = "*" ] then return 1 ; fi local prevIFS="$IFS" IFS="$(printf '\n\t')" rm -f $1 ; retcode="$?" IFS="$prevIFS" return "$retcode" } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Nov-16] ## ##----------------------------------------------## #-------------------------------------------------------# # NOTE for disabling shellcheck 2086 [Martinski W.] # Both parameters [$1 $2] MUST be UNQUOTED because the # 1st one can consist of some optional arguments for # the 'ls' command (e.g. "ls -lt ..."), and 2nd param # can be a file path argument that contains a wildcard # char [*] which when quoted is taken as a _literal_ # asterisk, and that leads to a failed execution. # GOOD call example: # ls -lt /PATH/TO/DIR/FileName_*.tar #-------------------------------------------------------# # shellcheck disable=SC2086 _list2_() { if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ] then return 1 ; fi local prevIFS="$IFS" IFS="$(printf '\n\t')" ls $1 $2 ; retcode="$?" IFS="$prevIFS" return "$retcode" } ##-------------------------------------## ## Added by Martinski W. [2023-Apr-01] ## ##-------------------------------------## _WaitForEnterKey_() { ! "$waitToConfirm" && return 0 echo ; read -rsp "Press enter key to continue..." ; echo } _WaitForConfirmation_() { ! "$waitToConfirm" && return 0 read -rn 3 -p "$1 [yY|nN] N? " YESorNO ; echo if echo "$YESorNO" | grep -qE '^(Y|y|yes)$' then return 0 ; else return 1 ; fi } _NVRAM_IconsCleanupFiles_() { rm -f "$NVRAM_ClientsKeyVARsaved" "$NVRAM_ClientsKeyFLEsaved" ; } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-10] ## ##----------------------------------------------## _NVRAM_IconsSaveKeyValue_() { NVRAM_SavedOK=false if [ -s "${NVRAM_Folder}/$NVRAM_ClientsKeyName" ] then if cp -fp "${NVRAM_Folder}/$NVRAM_ClientsKeyName" "$NVRAM_ClientsKeyFLEsaved" then NVRAM_SavedOK=true ; fi fi theKeyValue="$(nvram get "$NVRAM_ClientsKeyName")" if [ -n "$theKeyValue" ] then if ! echo "$theKeyValue" | grep -qE "^<.*" then theKeyValue="<$theKeyValue" ; fi echo "$theKeyValue" > "$NVRAM_ClientsKeyVARsaved" NVRAM_SavedOK=true fi "$NVRAM_SavedOK" && return 0 Print_Output true "*WARNING*: NVRAM variable \"${NVRAM_ClientsKeyName}\" is EMPTY or NOT FOUND." "$WARN" return 1 } _NVRAM_IconsRestoreKeyValue_() { NVRAM_RestoredOK=false if [ -d "$NVRAM_Folder" ] && [ -f "$NVRAM_ClientsKeyFLEsaved" ] && \ [ "$(ls -1 "$NVRAM_Folder" 2>/dev/null | wc -l)" -gt 0 ] then mv -f "$NVRAM_ClientsKeyFLEsaved" "${NVRAM_Folder}/$NVRAM_ClientsKeyName" nvram set ${NVRAM_ClientsKeyName}="$(cat "${NVRAM_Folder}/$NVRAM_ClientsKeyName")" NVRAM_RestoredOK=true fi if [ -f "$NVRAM_ClientsKeyVARsaved" ] then theKeyValueSaved="$(cat "$NVRAM_ClientsKeyVARsaved")" if [ "$(nvram get "$NVRAM_ClientsKeyName")" != "$theKeyValueSaved" ] then nvram set ${NVRAM_ClientsKeyName}="$theKeyValueSaved" NVRAM_RestoredOK=true fi fi _NVRAM_IconsCleanupFiles_ "$NVRAM_RestoredOK" && nvram commit && return 0 Print_Output true "*WARNING*: NVRAM variable \"${NVRAM_ClientsKeyName}\" was NOT restored." "$WARN" return 1 } CheckForCustomIconFiles() { if [ -d "$userIconsDIRpath" ] && \ [ "$(ls -1 ${userIconsDIRpath}/*.log 2>/dev/null | wc -l)" -gt 0 ] then iconsFound=true UpdateCustomUserIconsConfig FOUND TRUE return 0 else iconsFound=false UpdateCustomUserIconsConfig FOUND FALSE return 1 fi } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-04] ## ##----------------------------------------------## CheckForSavedIconFiles() { theFileCount="$(_list2_ -1 "$theBackupFilesMatch" 2>/dev/null | wc -l)" if [ ! -d "$theUserIconsBackupDir" ] || [ "$theFileCount" -eq 0 ] then backupsFound=false UpdateCustomUserIconsConfig SAVED NONE UpdateCustomUserIconsConfig RESTD NONE return 1 fi backupsFound=true theBackupFile="" if [ $# -gt 0 ] && [ -n "$1" ] && "$1" then while IFS="$(printf '\n\t')" read -r FILE do theBackupFile="$FILE" ; break done </dev/null) EOT UpdateCustomUserIconsConfig SAVED "$theBackupFile" UpdateCustomUserIconsConfig RESTD "$theBackupFile" fi return 0 } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Sep-04] ## ##----------------------------------------------## CheckForMaxIconsSavedFiles() { if ! CheckForSavedIconFiles "$@" || \ [ "$theFileCount" -le "$maxUserIconsBackupFiles" ] then return 0 ; fi if [ "$maxUserIconsBackupFiles" -ge "$defMaxUserIconsBackupFiles" ] then highWaterMark="$maxUserIconsBackupFiles" else highWaterMark="$((maxUserIconsBackupFiles + theHighWaterMarkThreshold))" fi if [ "$highWaterMark" -gt "$theMaxUserIconsBackupFiles" ] then highWaterMark="$theMaxUserIconsBackupFiles" ; fi if [ $# -gt 0 ] && [ -n "$1" ] && "$1" && \ [ "$theFileCount" -gt "$highWaterMark" ] then ## Remove the OLDEST backup file ## while IFS="$(printf '\n\t')" read -r FILE do _remf_ "$FILE" && theFileCount="$((theFileCount - 1))" break done </dev/null) EOT if [ "$theFileCount" -le "$maxUserIconsBackupFiles" ] then return 0 ; fi fi ! "$waitToConfirm" && return 1 printf "\n\n${YLWct}**WARNING**${NOct}\n" printf "The number of backup files [${REDct}${theFileCount}${NOct}] exceeds the maximum [${GRNct}${maxUserIconsBackupFiles}${NOct}].\n" printf "It's highly recommended that you either delete old backup files,\n" printf "or move them from the current directory to a different location.\n" _WaitForEnterKey_ return 1 } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-03] ## ##----------------------------------------------## BackupCustomUserIcons() { local retCode if ! CheckForCustomIconFiles then UpdateCustomUserIconsConfig SAVED NONE STATUSupdate Print_Output true "**ERROR**: Directory [$userIconsDIRpath] is EMPTY or NOT FOUND." "$ERR" return 1 fi UpdateCustomUserIconsConfig SAVED WAIT _NVRAM_IconsSaveKeyValue_ theFilePath="${userIconsBackupFPath}_$(date +"$savedFileDateTimeStr").$userIconsSavedFLEextn" if ! tar -czf "$theFilePath" -C "$theJFFSdir" "./$userIconsDIRname" then retCode=1 UpdateCustomUserIconsConfig SAVED NONE STATUSupdate Print_Output true "**ERROR**: Could NOT save icon files." "$ERR" else retCode=0 chmod 664 "$theFilePath" UpdateCustomUserIconsConfig SAVED "$theFilePath" STATUSupdate printf "All icon files were successfully saved in:\n[${GRNct}${theFilePath}${NOct}]\n" fi _NVRAM_IconsCleanupFiles_ CheckForMaxIconsSavedFiles true && _WaitForEnterKey_ return "$retCode" } ##----------------------------------------------## ## Added/modified by Martinski W. [2023-Nov-17] ## ##----------------------------------------------## _GetFileSelectionIndex_() { if [ $# -eq 0 ] || [ -z "$1" ] ; then return 1 ; fi local selectStr promptStr numRegEx indexNum indexList local multiIndexListOK theAllStr="${GRNct}all${NOct}" if [ "$1" -eq 1 ] then selectStr="${GRNct}1${NOct}" else selectStr="${GRNct}1${NOct}-${GRNct}${1}${NOct}" fi if [ $# -lt 2 ] || [ "$2" != "-MULTIOK" ] then multiIndexListOK=false promptStr="Enter selection [${selectStr}] [${theExitStr}]?" else multiIndexListOK=true promptStr="Enter selection [${selectStr} | ${theAllStr}] [${theExitStr}]?" fi fileIndex=0 multiIndex=false numRegEx="([1-9]|[1-9][0-9])" while true do printf "${promptStr} " ; read -r userInput if [ -z "$userInput" ] || \ echo "$userInput" | grep -qE "^(e|exit|Exit)$" then fileIndex="NONE" ; break ; fi if "$multiIndexListOK" && \ echo "$userInput" | grep -qE "^(all|All)$" then fileIndex="ALL" ; break ; fi if echo "$userInput" | grep -qE "^${numRegEx}$" && \ [ "$userInput" -gt 0 ] && [ "$userInput" -le "$1" ] then fileIndex="$userInput" ; break ; fi if "$multiIndexListOK" && \ echo "$userInput" | grep -qE "^${numRegEx}\-${numRegEx}[ ]*$" then ## Index Range ## index1st="$(echo "$userInput" | awk -F '-' '{print $1}')" indexMax="$(echo "$userInput" | awk -F '-' '{print $2}')" if [ "$index1st" -lt "$indexMax" ] && \ [ "$index1st" -gt 0 ] && [ "$index1st" -le "$1" ] && \ [ "$indexMax" -gt 0 ] && [ "$indexMax" -le "$1" ] then indexNum="$index1st" indexList="$indexNum" while [ "$indexNum" -lt "$indexMax" ] do indexNum="$((indexNum+1))" indexList="${indexList},${indexNum}" done userInput="$indexList" fi fi if "$multiIndexListOK" && \ echo "$userInput" | grep -qE "^${numRegEx}(,[ ]*${numRegEx}[ ]*)+$" then ## Index List ## indecesOK=true indexList="$(echo "$userInput" | sed 's/ //g' | sed 's/,/ /g')" for theIndex in $indexList do if [ "$theIndex" -eq 0 ] || [ "$theIndex" -gt "$1" ] then indecesOK=false ; break ; fi done "$indecesOK" && fileIndex="$indexList" && multiIndex=true && break fi printf "${REDct}INVALID selection.${NOct}\n" done } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-04] ## ##----------------------------------------------## _GetFileSelection_() { if [ $# -eq 0 ] || [ -z "$1" ] ; then return 1 ; fi if [ $# -lt 2 ] || [ "$2" != "-MULTIOK" ] then indexType="" ; else indexType="$2" ; fi theFilePath="" theFileName="" fileTemp="" fileCount=0 fileIndex=0 multiIndex=false printf "\n${1}\n[Directory: ${GRNct}${theUserIconsBackupDir}${NOct}]\n\n" while IFS="$(printf '\n\t')" read -r backupFilePath do fileCount=$((fileCount+1)) fileVar="file_${fileCount}_Name" eval file_${fileCount}_Name="${backupFilePath##*/}" printf "${GRNct}%3d${NOct}. " "$fileCount" eval echo "\$${fileVar}" done </dev/null) EOT echo _GetFileSelectionIndex_ "$fileCount" "$indexType" if [ "$fileIndex" = "ALL" ] || [ "$fileIndex" = "NONE" ] then theFilePath="$fileIndex" ; return 0 ; fi if [ "$indexType" = "-MULTIOK" ] && "$multiIndex" then for index in $fileIndex do fileVar="file_${index}_Name" eval fileTemp="\$${fileVar}" if [ -z "$theFilePath" ] then theFilePath="${theUserIconsBackupDir}/$fileTemp" else theFilePath="${theFilePath}|${theUserIconsBackupDir}/$fileTemp" fi done else fileVar="file_${fileIndex}_Name" eval theFileName="\$${fileVar}" theFilePath="${theUserIconsBackupDir}/$theFileName" fi return 0 } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-04] ## ##----------------------------------------------## GetSavedBackupFilesList() { GetUserIconsSavedVars rm -f "$SCRIPT_USER_ICONS_BKPLST" if ! CheckForSavedIconFiles then echo "NONE" > "$SCRIPT_USER_ICONS_BKPLST" return 1 fi echo "## [$(date +"$savedFileDateTimeStr")] ##" > "$SCRIPT_USER_ICONS_BKPLST" echo "$userIconsBKPListHeader $theUserIconsBackupDir" >> "$SCRIPT_USER_ICONS_BKPLST" fileCount=0 fileName="" while IFS="$(printf '\n\t')" read -r backupFilePath do fileCount=$((fileCount+1)) fileName="${backupFilePath##*/}" printf "%3d. ${fileName}\n" "$fileCount" >> "$SCRIPT_USER_ICONS_BKPLST" done </dev/null) EOT return 0 } ##----------------------------------------------## ## Added/modified by Martinski W. [2023-Apr-24] ## ##----------------------------------------------## RestoreUserIconFilesReq() { GetUserIconsSavedVars if ! CheckForSavedIconFiles || [ ! -f "$SCRIPT_USER_ICONS_BKPLST" ] then UpdateCustomUserIconsConfig RESTD NONE STATUSupdate Print_Output true "**ERROR**: Backup file(s) [$theBackupFilesMatch] NOT found." "$ERR" return 1 fi if [ $# -eq 0 ] || [ -z "$1" ] || \ ! echo "$1" | grep -qE "^${SCRIPT_NAME}restoreIcons_reqNum_[1-9]+" then UpdateCustomUserIconsConfig RESTD NONE STATUSupdate Print_Output true "**ERROR**: INVALID index to backup file path was provided." "$ERR" return 1 fi UpdateCustomUserIconsConfig RESTD WAIT local retCode fileCount=0 theFilePath="" fileIndex="$(echo "$1" | awk -F '_' '{print $3}')" while read -r theFileName do if echo "$theFileName" | grep -qE "^##" || \ echo "$theFileName" | grep -qE "^$userIconsBKPListHeader" then continue ; fi fileCount=$((fileCount+1)) if [ "$fileCount" -eq "$fileIndex" ] then theFilePath="${theUserIconsBackupDir}/${theFileName#* }" break fi done < "$SCRIPT_USER_ICONS_BKPLST" rm -f "$SCRIPT_USER_ICONS_BKPLST" if [ "$fileIndex" -gt "$fileCount" ] then UpdateCustomUserIconsConfig RESTD NONE STATUSupdate Print_Output true "**ERROR**: Archive file index [$fileIndex] is INVALID." "$ERR" return 1 fi if [ -z "$theFilePath" ] || [ ! -f "$theFilePath" ] then UpdateCustomUserIconsConfig RESTD NONE STATUSupdate Print_Output true "**ERROR**: Archive file [$theFilePath] NOT FOUND." "$ERR" return 1 fi Print_Output true "Restoring icon files from: [${fileIndex}. $theFilePath]" "$PASS" if ! tar -xzf "$theFilePath" -C "$theJFFSdir" then retCode=1 UpdateCustomUserIconsConfig RESTD NONE STATUSupdate Print_Output true "**ERROR**: Could NOT restore icon files from [$theFilePath]." "$ERR" else retCode=0 _NVRAM_IconsRestoreKeyValue_ UpdateCustomUserIconsConfig RESTD "$theFilePath" STATUSupdate Print_Output true "All icon files were restored successfully." "$PASS" fi return "$retCode" } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Nov-17] ## ##----------------------------------------------## RestoreCustomUserIcons() { local retCode theFilePath="" theFileCount=0 if ! CheckForSavedIconFiles then UpdateCustomUserIconsConfig RESTD NONE STATUSupdate Print_Output true "**ERROR**: Backup file(s) [$theBackupFilesMatch] NOT FOUND." "$ERR" return 1 fi UpdateCustomUserIconsConfig RESTD WAIT if [ $# -gt 0 ] && [ -n "$1" ] && "$1" then ## Restore from the MOST recent backup file ## while IFS="$(printf '\n\t')" read -r FILE do theFilePath="$FILE" ; break done </dev/null) EOT else _GetFileSelection_ "Select a backup file to restore the icon files from:" fi if [ "$theFilePath" = "NONE" ] || [ ! -f "$theFilePath" ] then UpdateCustomUserIconsConfig RESTD NONE STATUSupdate return 1 fi printf "Restoring icon files from:\n[${GRNct}$theFilePath${NOct}]\n" if ! _WaitForConfirmation_ "Please confirm selection" then printf "Icon file(s) ${REDct}NOT${NOct} restored.\n" _WaitForEnterKey_ return 99 fi if ! tar -xzf "$theFilePath" -C "$theJFFSdir" then retCode=99 UpdateCustomUserIconsConfig RESTD NONE STATUSupdate Print_Output true "**ERROR**: Could NOT restore icon files." "$ERR" else retCode=0 _NVRAM_IconsRestoreKeyValue_ UpdateCustomUserIconsConfig RESTD "$theFilePath" STATUSupdate printf "All icon files were restored ${GRNct}successfully${NOct}.\n\n" ls -AlF "$userIconsDIRpath" fi _WaitForEnterKey_ return "$retCode" } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Nov-17] ## ##----------------------------------------------## ListContentsOfSavedIconsFile() { local retCode theFilePath="" theFileCount=0 if ! CheckForSavedIconFiles then Print_Output true "**ERROR**: Backup file(s) [$theBackupFilesMatch] NOT FOUND." "$ERR" return 1 fi _GetFileSelection_ "Select a backup file to list contents of:" if [ "$theFilePath" = "NONE" ] || [ ! -f "$theFilePath" ] then return 1 ; fi printf "Listing contents of backup file:\n[${GRNct}${theFilePath}${NOct}]\n\n" if tar -tzf "$theFilePath" -C "$theJFFSdir" then retCode=0 printf "\nContents were listed ${GRNct}successfully${NOct}.\n" else retCode=99 printf "\n${REDct}**ERROR**:${NOct} Could NOT list contents.\n" fi _WaitForEnterKey_ return "$retCode" } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Nov-17] ## ##----------------------------------------------## DeleteSavedIconsFile() { local retCode theFilePath="" fileIndex=0 multiIndex=false if ! CheckForSavedIconFiles then Print_Output true "**ERROR**: Backup file(s) [$theBackupFilesMatch] NOT FOUND." "$ERR" return 1 fi _GetFileSelection_ "Select a backup file to delete:" -MULTIOK if [ "$theFilePath" = "NONE" ] ; then return 1 ; fi if [ "$theFilePath" != "ALL" ] && ! "$multiIndex" && [ ! -f "$theFilePath" ] then return 1 ; fi if [ "$theFilePath" != "ALL" ] then fileToDelete="$theFilePath" delMsg="Deleting backup file(s):" else fileToDelete="$theBackupFilesMatch" delMsg="Deleting ${REDct}ALL${NOct} backup(s):" fi if ! "$multiIndex" then theFileList="$fileToDelete" else theFileList="$(echo "$fileToDelete" | sed 's/|/\n/g')" fileToDelete="$theFileList" fi printf "${delMsg}\n${GRNct}${theFileList}${NOct}\n" if ! _WaitForConfirmation_ "Please confirm deletion" then printf "File(s) ${REDct}NOT${NOct} deleted.\n" _WaitForEnterKey_ return 99 fi fileDelOK=true local prevIFS="$IFS" IFS="$(printf '\n\t')" for thisFile in $fileToDelete do if ! _remf_ "$thisFile" ; then fileDelOK=false ; fi ; done IFS="$prevIFS" if "$fileDelOK" then retCode=0 printf "File deletion completed ${GRNct}successfully${NOct}.\n" else retCode=99 printf "\n${REDct}**ERROR**:${NOct} Could NOT delete file(s).\n" fi _WaitForEnterKey_ return "$retCode" } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Nov-17] ## ##----------------------------------------------## SetMaxNumberOfBackupFiles() { local numRegEx="([1-9]|[1-9][0-9])" newMaxNumOfBackups="DEFAULT" echo while true do printf "Enter the maximum number of backups of user icons to keep.\n" printf "[${GRNct}${theMinUserIconsBackupFiles}${NOct}-${GRNct}${theMaxUserIconsBackupFiles}${NOct}] | [DEFAULT: ${GRNct}${maxUserIconsBackupFiles}${NOct}] [${theExitStr}]? " read -r userInput if [ -z "$userInput" ] || \ echo "$userInput" | grep -qE "^(e|exit|Exit)$" then newMaxNumOfBackups="DEFAULT" ; break ; fi if echo "$userInput" | grep -qE "^${numRegEx}$" && \ [ "$userInput" -ge "$theMinUserIconsBackupFiles" ] && \ [ "$userInput" -le "$theMaxUserIconsBackupFiles" ] then newMaxNumOfBackups="$userInput" ; break ; fi printf "${REDct}INVALID input.${NOct}\n" done if [ "$newMaxNumOfBackups" != "DEFAULT" ] then maxUserIconsBackupFiles="$newMaxNumOfBackups" UpdateCustomUserIconsConfig SAVED_MAX "$maxUserIconsBackupFiles" fi return 0 } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Nov-17] ## ##----------------------------------------------## SetCustomUserIconsBackupDirectory() { local newBackupDirPath="DEFAULT" echo while true do printf "Enter the directory path where the backups subdirectory [${GRNct}${userIconsSavedDIRname}${NOct}] will be stored.\n" printf "[DEFAULT: ${GRNct}${theUserIconsBackupDir%/*}${NOct}] [${theExitStr}]? " read -r userInput if [ -z "$userInput" ] || \ echo "$userInput" | grep -qE "^(e|exit|Exit)$" then newBackupDirPath="DEFAULT" ; break ; fi if echo "$userInput" | grep -q '/$' then userInput="${userInput%/*}" ; fi if echo "$userInput" | grep -q '//' || \ echo "$userInput" | grep -q '/$' || \ ! echo "$userInput" | grep -q '^/' || \ [ "${#userInput}" -lt 4 ] || \ [ "$(echo "$userInput" | awk -F '/' '{print NF-1}')" -lt 2 ] then printf "${REDct}INVALID input.${NOct}\n" continue fi if [ -d "$userInput" ] then newBackupDirPath="$userInput" ; break ; fi rootDir="${userInput%/*}" if [ ! -d "$rootDir" ] then printf "${REDct}**ERROR**:${NOct} Root directory path [$rootDir] does NOT exist.\n" printf "${REDct}INVALID input.${NOct}\n" continue fi printf "The directory path '${REDct}${userInput}${NOct}' does NOT exist.\n" if ! _WaitForConfirmation_ "Do you want to create it now" then printf "Directory was ${REDct}NOT${NOct} created.\n\n" else mkdir -m 755 "$userInput" 2>/dev/null if [ -d "$userInput" ] then newBackupDirPath="$userInput" ; break else printf "\n${REDct}**ERROR**: Could NOT create directory [$userInput]${NOct}.\n\n" fi fi done if [ "$newBackupDirPath" != "DEFAULT" ] && [ -d "$newBackupDirPath" ] then if [ "${newBackupDirPath##*/}" != "$userIconsSavedDIRname" ] then newBackupDirPath="${newBackupDirPath}/$userIconsSavedDIRname" ; fi mkdir -m 755 "$newBackupDirPath" 2>/dev/null if [ ! -d "$newBackupDirPath" ] then printf "\n${REDct}**ERROR**${NOct}: Could NOT create directory [${REDct}${newBackupDirPath}${NOct}].\n" _WaitForEnterKey_ ; return 1 fi if CheckForSavedIconFiles && [ "$newBackupDirPath" != "$theUserIconsBackupDir" ] then printf "\nMoving existing backup files to directory:\n[${GRNct}$newBackupDirPath${NOct}]\n" if _movef_ "$theBackupFilesMatch" "$newBackupDirPath" && \ ! CheckForSavedIconFiles then rmdir "$theUserIconsBackupDir" 2>/dev/null ; fi fi UpdateCustomUserIconsConfig SAVED_DIR "$newBackupDirPath" UpdateCustomUserIconsConfig PREFS_DIR "$newBackupDirPath" CheckForSavedIconFiles true fi return 0 } ##----------------------------------------------## ## Added/modified by Martinski W. [2023-Apr-15] ## ##----------------------------------------------## ShowIconsMenuOptions() { SEPstr="--------------------------------------------------------------------" printf "\n${SEPstr}\n" CheckForCustomIconFiles ; CheckForSavedIconFiles if ! "$iconsFound" && ! "$backupsFound" then printf "\nNo custom user icon files and no previously saved backup files were found.\n" printf "${REDct}Exiting to main menu...${NOct}\n" _WaitForEnterKey_ printf "\n${SEPstr}\n" return 1 fi printf "\n ${YLWct}${MaxBckupsOpt}${NOct}. Maximum number of backups of icon files to keep." printf "\n [Current Max: ${GRNct}${maxUserIconsBackupFiles}${NOct}]\n" printf "\n ${YLWct}${BackupDirOpt}${NOct}. Directory path where backups of icon files are stored." printf "\n [Current Path: ${GRNct}${theUserIconsBackupDir}${NOct}]\n" if "$iconsFound" && [ -d "$theUserIconsBackupDir" ] then printf "\n ${YLWct}${BkupIconsOpt}${NOct}. Back up the icon files found in the ${GRNct}${userIconsDIRpath}${NOct} directory.\n" fi if "$backupsFound" then printf "\n ${YLWct}${RestIconsOpt}${NOct}. Restore the icon files into the ${GRNct}${userIconsDIRpath}${NOct} directory.\n" printf "\n ${YLWct}${DeltIconsOpt}${NOct}. Delete a previously saved backup of icon files.\n" printf "\n ${YLWct}${ListIconsOpt}${NOct}. List contents of a previously saved backup of icon files.\n" fi printf "\n ${YLWct}e${NOct}. Exit to main menu.\n" printf "\n${SEPstr}\n" return 0 } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Nov-17] ## ##----------------------------------------------## IconsMenuSelectionHandler() { local exitMenu=false retCode local theExitStr="${GRNct}e${NOct}=Exit" until ! ShowIconsMenuOptions do while true do printf "Choose an option: " ; read -r userOption if [ -z "$userOption" ] ; then echo ; continue ; fi if echo "$userOption" | grep -qE "^(e|exit|Exit)$" then exitMenu=true ; break ; fi if [ "$userOption" = "$MaxBckupsOpt" ] then SetMaxNumberOfBackupFiles; break ; fi if [ "$userOption" = "$BackupDirOpt" ] then SetCustomUserIconsBackupDirectory ; break ; fi if [ "$userOption" = "$BkupIconsOpt" ] && \ "$iconsFound" && [ -d "$theUserIconsBackupDir" ] then BackupCustomUserIcons ; break ; fi if [ "$userOption" = "$RestIconsOpt" ] && "$backupsFound" then while true do RestoreCustomUserIcons ; retCode="$?" if [ "$retCode" -eq 99 ] then continue ; else break ; fi done break fi if [ "$userOption" = "$DeltIconsOpt" ] && "$backupsFound" then while true do DeleteSavedIconsFile ; retCode="$?" if [ "$retCode" -eq 99 ] then continue ; else break ; fi done break fi if [ "$userOption" = "$ListIconsOpt" ] && "$backupsFound" then while true do ListContentsOfSavedIconsFile ; retCode="$?" if [ "$retCode" -eq 99 ] || [ "$retCode" -eq 0 ] then continue ; else break ; fi done break fi printf "${REDct}INVALID option.${NOct}\n" done "$exitMenu" && break done } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-14] ## ##----------------------------------------------## Menu_CustomUserIconsOps() { waitToConfirm=true if GetUserIconsSavedVars then CheckForMaxIconsSavedFiles IconsMenuSelectionHandler CheckForMaxIconsSavedFiles fi Clear_Lock } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-14] ## ##----------------------------------------------## CheckUserIconFiles() { waitToConfirm=false GetUserIconsSavedVars CheckForCustomIconFiles CheckForSavedIconFiles true } BackUpUserIconFiles() { waitToConfirm=false ClearCustomUserIconsStatus GetUserIconsSavedVars BackupCustomUserIcons CheckForSavedIconFiles } RestoreUserIconFiles() { waitToConfirm=false ClearCustomUserIconsStatus GetUserIconsSavedVars RestoreCustomUserIcons "$1" CheckForCustomIconFiles } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-Jun-10] ## ##----------------------------------------------## CheckAgainstNVRAMvar() { if [ $# -eq 0 ] || [ -z "$1" ] ; then return 0 ; fi if [ ! -s /jffs/nvram/dhcp_staticlist ] then theKeyVal="$(nvram get dhcp_staticlist)" else theKeyVal="$(cat /jffs/nvram/dhcp_staticlist)" fi if [ -z "$theKeyVal" ] ; then return 0 ; fi if ! echo "$theKeyVal" | grep -qE "^<.*" then theKeyVal="<$theKeyVal" ; fi retCode=0 MACx_Addrs="$(echo "$1" | awk -F ' ' '{print $1}')" IPv4_Addrs="$(echo "$1" | awk -F ' ' '{print $2}')" IPv4_RegEx="([0-9]{1,3}\.){3}([0-9]{1,3})" MACx_RegEx="([a-fA-F0-9]{2}\:){5}([a-fA-F0-9]{2})" theRegExp1="<${MACx_Addrs}>${IPv4_RegEx}>[^<]*" theRegExp2="<${MACx_RegEx}>${IPv4_Addrs}>[^<]*" keyEntry="" if echo "$theKeyVal" | grep -qiE "$theRegExp1" then keyEntry="$(echo "$theKeyVal" | grep -ioE "$theRegExp1")" elif echo "$theKeyVal" | grep -qiE "$theRegExp2" then keyEntry="$(echo "$theKeyVal" | grep -ioE "$theRegExp2")" fi if [ -n "$keyEntry" ] then tempFile="/tmp/yazdhcp_nvramstr.tmp" echo "$theKeyVal" | sed "s/${keyEntry}//g" | sed '/^$/d' > "$tempFile" nvram set dhcp_staticlist="$(cat "$tempFile")" rm -f $tempFile retCode=1 fi return $retCode } ##----------------------------------------------## ## Added/Modified by Martinski W. [2023-May-28] ## ##----------------------------------------------## ValidateNVRAMentry() { if [ $# -eq 0 ] || [ -z "$1" ] ; then return 1 ; fi retCode=0 dupInfoMsg="" MACx_Addrs="$(echo "$1" | awk -F '|' '{print $1}')" IPv4_Addrs="$(echo "$1" | awk -F '|' '{print $2}')" theClientx="${MACx_Addrs},${IPv4_Addrs}" if grep -qi "^${theClientx}" "$SCRIPT_CONF" then dupInfoMsg="Client entry [$theClientx] is already found" elif grep -qi "^${MACx_Addrs}," "$SCRIPT_CONF" then dupInfoMsg="Client MAC address [$MACx_Addrs] is already found" elif grep -qi ",${IPv4_Addrs}," "$SCRIPT_CONF" then dupInfoMsg="Client IP address [$IPv4_Addrs] is already assigned" fi if [ -n "$dupInfoMsg" ] then Print_Output true "$dupInfoMsg in $SCRIPT_CONF file" "$WARN" Print_Output true "NVRAM entry will be skipped/ignored." "$WARN" retCode=1 fi return $retCode } ##----------------------------------------## ## Modified by Martinski W. [2023-Jun-10] ## ##----------------------------------------## ### nvram parsing code based on dhcpstaticlist.sh by @Xentrk ### Export_FW_DHCP_JFFS() { printf "\\n\\e[1mDo you want to export DHCP assignments and hostnames from NVRAM to %s DHCP client files? (y/n)\\e[0m\\n" "$SCRIPT_NAME" printf "%s will backup NVRAM/jffs DHCP data as part of the export\\n" "$SCRIPT_NAME" printf "\\n\\e[1mEnter answer (y/n): \\e[0m" read -r confirm case "$confirm" in y|Y) : ;; *) Clear_Lock return 1 ;; esac if [ "$(nvram get dhcp_staticlist | wc -m)" -le 1 ]; then Print_Output true "DHCP static assignments not exported from NVRAM, no data found" "$PASS" Clear_Lock return 1 fi if [ "$(Firmware_Version_Number "$(nvram get buildno)")" -lt "$(Firmware_Version_Number 386.4)" ]; then if [ -f /jffs/nvram/dhcp_hostnames ]; then if [ "$(wc -m < /jffs/nvram/dhcp_hostnames)" -le 1 ]; then Print_Output true "DHCP hostnames not exported from NVRAM, no data found" "$PASS" Clear_Lock return 1 fi elif [ "$(nvram get dhcp_hostnames | wc -m)" -le 1 ]; then Print_Output true "DHCP hostnames not exported from NVRAM, no data found" "$PASS" Clear_Lock return 1 fi if [ -f /jffs/nvram/dhcp_staticlist ]; then sed 's// /g;s/ /tmp/yazdhcp-ips.tmp else nvram get dhcp_staticlist | sed 's// /g;s/ /tmp/yazdhcp-ips.tmp fi if [ -f /jffs/nvram/dhcp_hostnames ]; then HOSTNAME_LIST=$(sed 's/>undefined//' /jffs/nvram/dhcp_hostnames) else HOSTNAME_LIST=$(nvram get dhcp_hostnames | sed 's/>undefined//') fi OLDIFS=$IFS IFS="<" for HOST in $HOSTNAME_LIST; do if [ "$HOST" = "" ]; then continue fi MAC=$(echo "$HOST" | cut -d ">" -f1) HOSTNAME=$(echo "$HOST" | cut -d ">" -f2) echo "$MAC $HOSTNAME" >> /tmp/yazdhcp-hosts.tmp done IFS=$OLDIFS sed -i 's/ $//' /tmp/yazdhcp-ips.tmp sed -i 's/ $//' /tmp/yazdhcp-hosts.tmp awk 'NR==FNR { k[$1]=$2; next } { print $0, k[$1] }' /tmp/yazdhcp-hosts.tmp /tmp/yazdhcp-ips.tmp > /tmp/yazdhcp.tmp echo "MAC,IP,HOSTNAME,DNS" > "$SCRIPT_CONF" sort -t . -k 3,3n -k 4,4n /tmp/yazdhcp.tmp > /tmp/yazdhcp_sorted.tmp while IFS='' read -r line || [ -n "$line" ]; do if [ "$(echo "$line" | wc -w)" -eq 4 ]; then echo "$line" | awk '{ print ""$1","$2","$4","$3""; }' >> "$SCRIPT_CONF" else if ! Validate_IP "$(echo "$line" | cut -d " " -f3)" >/dev/null 2>&1; then printf "%s,\\n" "$(echo "$line" | sed 's/ /,/g')" >> "$SCRIPT_CONF" else echo "$line" | awk '{ print ""$1","$2","","$3""; }' >> "$SCRIPT_CONF" fi fi done < /tmp/yazdhcp_sorted.tmp rm -f /tmp/yazdhcp*.tmp if [ -f /jffs/nvram/dhcp_hostnames ]; then cp /jffs/nvram/dhcp_hostnames "$SCRIPT_DIR/.nvram_jffs_dhcp_hostnames" rm -f /jffs/nvram/dhcp_hostnames fi nvram get dhcp_hostnames > "$SCRIPT_DIR/.nvram_dhcp_hostnames" nvram unset dhcp_hostnames else if [ -f /jffs/nvram/dhcp_staticlist ]; then sed 's//|/g;s/ /tmp/yazdhcp.tmp else nvram get dhcp_staticlist | sed 's//|/g;s/ /tmp/yazdhcp.tmp fi if [ ! -f "$SCRIPT_CONF" ] || [ ! -s "$SCRIPT_CONF" ] then echo "MAC,IP,HOSTNAME,DNS" > "$SCRIPT_CONF" ; fi sort -t . -k 3,3n -k 4,4n /tmp/yazdhcp.tmp > /tmp/yazdhcp_sorted.tmp while IFS='' read -r line || [ -n "$line" ] do if ! ValidateNVRAMentry "$line" ; then continue ; fi echo "$line" | awk 'FS="|" { print ""$1","$2","$4","$3""; }' >> "$SCRIPT_CONF" done < /tmp/yazdhcp_sorted.tmp rm -f /tmp/yazdhcp*.tmp fi if [ -f /jffs/nvram/dhcp_staticlist ]; then cp /jffs/nvram/dhcp_staticlist "$SCRIPT_DIR/.nvram_jffs_dhcp_staticlist" fi theKeyVal="$(nvram get dhcp_staticlist)" if ! echo "$theKeyVal" | grep -qE "^<.*" then theKeyVal="<$theKeyVal" ; fi echo "$theKeyVal" > "$SCRIPT_DIR/.nvram_dhcp_staticlist" nvram unset dhcp_staticlist nvram commit Print_Output true "DHCP information successfully exported from NVRAM" "$PASS" RESTART_DNSMASQ=true Update_Hostnames Update_Staticlist Update_Optionslist if "$RESTART_DNSMASQ" then Print_Output true "Restarting dnsmasq for exported DHCP settings to take effect." "$PASS" service restart_dnsmasq >/dev/null 2>&1 fi Clear_Lock } ################################################################## ##----------------------------------------## ## Modified by Martinski W. [2023-Mar-14] ## ##----------------------------------------## Update_Hostnames(){ existingmd5="" if [ -f "$SCRIPT_DIR/.hostnames" ]; then existingmd5="$(md5sum "$SCRIPT_DIR/.hostnames" | awk '{print $1}')" fi tail -n +2 "$SCRIPT_CONF" | awk -F',' '$3 != "" { print ""$2" "$3""; }' > "$SCRIPT_DIR/.hostnames" updatedmd5="$(md5sum "$SCRIPT_DIR/.hostnames" | awk '{print $1}')" if [ "$existingmd5" != "$updatedmd5" ]; then Print_Output true "DHCP hostname list updated successfully" "$PASS" RESTART_DNSMASQ=true else Print_Output true "DHCP hostname list unchanged" "$WARN" fi } ##----------------------------------------## ## Modified by Martinski W. [2023-Mar-14] ## ##----------------------------------------## Update_Staticlist(){ existingmd5="" if [ -f "$SCRIPT_DIR/.staticlist" ]; then existingmd5="$(md5sum "$SCRIPT_DIR/.staticlist" | awk '{print $1}')" fi tail -n +2 "$SCRIPT_CONF" | awk -F',' '{ print ""$1",set:"$1","$2""; }' > "$SCRIPT_DIR/.staticlist" updatedmd5="$(md5sum "$SCRIPT_DIR/.staticlist" | awk '{print $1}')" if [ "$existingmd5" != "$updatedmd5" ]; then Print_Output true "DHCP static assignment list updated successfully" "$PASS" RESTART_DNSMASQ=true else Print_Output true "DHCP static assignment list unchanged" "$WARN" fi } ##----------------------------------------## ## Modified by Martinski W. [2023-Mar-14] ## ##----------------------------------------## Update_Optionslist(){ existingmd5="" if [ -f "$SCRIPT_DIR/.optionslist" ]; then existingmd5="$(md5sum "$SCRIPT_DIR/.optionslist" | awk '{print $1}')" fi tail -n +2 "$SCRIPT_CONF" | awk -F',' '$4 != "" { print "tag:"$1",6,"$4""; }' > "$SCRIPT_DIR/.optionslist" updatedmd5="$(md5sum "$SCRIPT_DIR/.optionslist" | awk '{print $1}')" if [ "$existingmd5" != "$updatedmd5" ]; then Print_Output true "DHCP options list updated successfully" "$PASS" RESTART_DNSMASQ=true else Print_Output true "DHCP options list unchanged" "$WARN" fi } ScriptHeader(){ clear printf "\\n" printf "\\e[1m##########################################################\\e[0m\\n" printf "\\e[1m## ##\\e[0m\\n" printf "\\e[1m## __ __ _____ _ _ _____ _____ ##\\e[0m\\n" printf "\\e[1m## \ \ / / | __ \ | | | | / ____|| __ \ ##\\e[0m\\n" printf "\\e[1m## \ \_/ /__ _ ____| | | || |__| || | | |__) | ##\\e[0m\\n" printf "\\e[1m## \ // _ ||_ /| | | || __ || | | ___/ ##\\e[0m\\n" printf "\\e[1m## | || (_| | / / | |__| || | | || |____ | | ##\\e[0m\\n" printf "\\e[1m## |_| \__,_|/___||_____/ |_| |_| \_____||_| ##\\e[0m\\n" printf "\\e[1m## ##\\e[0m\\n" printf "\\e[1m## %s on %-9s ##\\e[0m\\n" "$SCRIPT_VERSION" "$ROUTER_MODEL" printf "\\e[1m## ##\\e[0m\\n" printf "\\e[1m## https://github.com/jackyaz/%s ##\\e[0m\\n" "$SCRIPT_NAME" printf "\\e[1m## ##\\e[0m\\n" printf "\\e[1m##########################################################\\e[0m\\n" printf "\\n" } ##----------------------------------------## ## Modified by Martinski W. [2023-May-28] ## ##----------------------------------------## MainMenu() { printf "1. Process %s\\n\\n" "$SCRIPT_CONF" if CheckForCustomIconFiles || CheckForSavedIconFiles then printf "2. Save/Restore custom user icons found in the ${GRNct}${userIconsDIRpath}${NOct} directory.\n\n" fi showexport="true" if [ "$(nvram get dhcp_staticlist | wc -m)" -le 1 ]; then showexport="false" fi if [ "$(Firmware_Version_Number "$(nvram get buildno)")" -lt "$(Firmware_Version_Number 386.4)" ] then if [ -f /jffs/nvram/dhcp_hostnames ]; then if [ "$(wc -m < /jffs/nvram/dhcp_hostnames)" -le 1 ]; then showexport="false" fi elif [ "$(nvram get dhcp_hostnames | wc -m)" -le 1 ]; then showexport="false" fi fi if [ "$showexport" = "true" ]; then printf "x. Export nvram to %s\\n\\n" "$SCRIPT_NAME" fi printf "u. Check for updates\\n" printf "uf. Update %s with latest version (force update)\\n\\n" "$SCRIPT_NAME" printf "e. Exit %s\\n\\n" "$SCRIPT_NAME" printf "z. Uninstall %s\\n" "$SCRIPT_NAME" printf "\\n" printf "\\e[1m##########################################################\\e[0m\\n" printf "\\n" while true; do printf "Choose an option: " read -r menu case "$menu" in 1) printf "\\n" if Check_Lock menu; then Menu_ProcessDHCPClients fi PressEnter break ;; 2) if "$iconsFound" || "$backupsFound" then printf "\n" if Check_Lock menu; then Menu_CustomUserIconsOps else PressEnter fi break else printf "\nPlease choose a valid option\n\n" fi ;; x) if "$showexport" then printf "\\n" if Check_Lock menu; then Export_FW_DHCP_JFFS fi PressEnter break else printf "\nPlease choose a valid option\n\n" fi ;; u) printf "\\n" if Check_Lock menu; then Menu_Update fi PressEnter break ;; uf) printf "\\n" if Check_Lock menu; then Menu_ForceUpdate fi PressEnter break ;; e) ScriptHeader printf "\\n\\e[1mThanks for using %s!\\e[0m\\n\\n\\n" "$SCRIPT_NAME" exit 0 ;; z) while true; do printf "\\n\\e[1mAre you sure you want to uninstall %s? (y/n)\\e[0m\\n" "$SCRIPT_NAME" read -r confirm case "$confirm" in y|Y) Menu_Uninstall exit 0 ;; *) break ;; esac done break ;; *) printf "\\nPlease choose a valid option\\n\\n" ;; esac done ScriptHeader MainMenu } Menu_Install(){ Print_Output true "Welcome to $SCRIPT_NAME $SCRIPT_VERSION, a script by JackYaz" sleep 1 Print_Output true "Checking your router meets the requirements for $SCRIPT_NAME" if ! Check_Requirements; then Print_Output true "Requirements for $SCRIPT_NAME not met, please see above for the reason(s)" "$CRIT" PressEnter Clear_Lock rm -f "/jffs/scripts/$SCRIPT_NAME" 2>/dev/null exit 1 fi Create_Dirs Set_Version_Custom_Settings local Set_Version_Custom_Settings server "$SCRIPT_VERSION" Create_Symlinks httpstring="https" portstring=":$(nvram get https_lanport)" if [ "$(nvram get http_enable)" -eq 0 ]; then httpstring="http" portstring="" fi printf "%s will backup nvram/jffs DHCP data as part of the export, but you may wish to screenshot %s://%s%s/Advanced_DHCP_Content.asp\\e[0m\\n" "$SCRIPT_NAME" "$httpstring" "$(nvram get lan_ipaddr)" "$portstring" printf "\\n\\e[1mIf you wish to screenshot, please do so now as the WebUI page will be updated by %s\\e[0m\\n" "$SCRIPT_NAME" printf "\\n\\e[1mPress any key when you are ready to continue\\e[0m\\n" while true; do read -r key case "$key" in *) break ;; esac done Update_File Advanced_DHCP_Content.asp Update_File shared-jy.tar.gz Auto_Startup create 2>/dev/null Auto_ServiceEvent create 2>/dev/null Auto_DNSMASQ create 2>/dev/null Shortcut_Script create echo "MAC,IP,HOSTNAME,DNS" > "$SCRIPT_CONF" Export_FW_DHCP_JFFS Print_Output true "$SCRIPT_NAME installed successfully!" "$PASS" Clear_Lock } ##----------------------------------------## ## Modified by Martinski W. [2023-Mar-14] ## ##----------------------------------------## Menu_ProcessDHCPClients(){ RESTART_DNSMASQ=false Update_Hostnames Update_Staticlist Update_Optionslist if "$RESTART_DNSMASQ" ; then service restart_dnsmasq >/dev/null 2>&1 ; fi Clear_Lock } ##----------------------------------------## ## Modified by Martinski W. [2023-Jun-16] ## ##----------------------------------------## Menu_Startup(){ inStartupMode=true Create_Dirs Set_Version_Custom_Settings "local" Create_Symlinks Auto_Startup create 2>/dev/null Auto_ServiceEvent create 2>/dev/null Auto_DNSMASQ create 2>/dev/null Shortcut_Script create Mount_WebUI Clear_Lock } Menu_Update(){ Update_Version Clear_Lock } Menu_ForceUpdate(){ Update_Version force Clear_Lock } ##----------------------------------------## ## Modified by Martinski W. [2023-May-28] ## ##----------------------------------------## Menu_Uninstall(){ Print_Output true "Removing $SCRIPT_NAME..." "$PASS" Auto_Startup delete 2>/dev/null Auto_ServiceEvent delete 2>/dev/null Auto_DNSMASQ delete 2>/dev/null Shortcut_Script delete umount /www/Advanced_DHCP_Content.asp 2>/dev/null rm -f "$SCRIPT_DIR/Advanced_DHCP_Content.asp" commitNVRAM=false max7daySecs=604800 if [ "$(nvram get $DHCP_LEASE_KEYN)" -gt "$max7daySecs" ] then # Reset NVRAM variable to WebGUI maximum secs # nvram set ${DHCP_LEASE_KEYN}="$max7daySecs" commitNVRAM=true fi printf "\\n\\e[1mDo you want to restore the original NVRAM values from before %s was installed? (y/n): \\e[0m" "$SCRIPT_NAME" read -r confirm case "$confirm" in y|Y) if [ -f "$SCRIPT_DIR/.nvram_jffs_dhcp_staticlist" ]; then nvram set dhcp_staticlist="$(cat "$SCRIPT_DIR/.nvram_jffs_dhcp_staticlist")" commitNVRAM=true fi if [ -f "$SCRIPT_DIR/.nvram_jffs_dhcp_hostnames" ]; then nvram set dhcp_hostnames="$(cat "$SCRIPT_DIR/.nvram_jffs_dhcp_hostnames")" commitNVRAM=true fi if [ -f "$SCRIPT_DIR/.nvram_dhcp_staticlist" ]; then nvram set dhcp_staticlist="$(cat "$SCRIPT_DIR/.nvram_dhcp_staticlist")" commitNVRAM=true fi if [ -f "$SCRIPT_DIR/.nvram_dhcp_hostnames" ]; then nvram set dhcp_hostnames="$(cat "$SCRIPT_DIR/.nvram_dhcp_hostnames")" commitNVRAM=true fi ;; *) : ;; esac if "$commitNVRAM" ; then nvram commit ; fi printf "\\n\\e[1mDo you want to delete %s DHCP clients and NVRAM backup files? (y/n): \\e[0m" "$SCRIPT_NAME" read -r confirm case "$confirm" in y|Y) rm -rf "$SCRIPT_DIR" 2>/dev/null ;; *) : ;; esac rm -rf "$SCRIPT_WEB_DIR" 2>/dev/null rm -f "/jffs/scripts/$SCRIPT_NAME" 2>/dev/null Clear_Lock Print_Output true "Uninstall completed" "$PASS" if "$commitNVRAM" then Print_Output true "Restarting dnsmasq to restore DHCP settings." "$PASS" service restart_dnsmasq >/dev/null 2>&1 fi } Check_Requirements(){ CHECKSFAILED="false" if [ "$(nvram get jffs2_scripts)" -ne 1 ]; then nvram set jffs2_scripts=1 nvram commit Print_Output true "Custom JFFS Scripts enabled" "$WARN" fi if ! Firmware_Version_Check; then Print_Output true "Unsupported firmware version detected" "$ERR" Print_Output true "$SCRIPT_NAME requires Merlin 384.15/384.13_4 or Fork 43E5 (or later)" "$ERR" CHECKSFAILED="true" fi if [ "$CHECKSFAILED" = "false" ]; then return 0 else return 1 fi } ##-------------------------------------## ## Added by Martinski W. [2023-Apr-03] ## ##-------------------------------------## # Catch unexpected exit to release lock # trap 'Clear_Lock; exit 10' EXIT HUP INT TERM if [ $# -eq 0 ] || [ -z "$1" ]; then Create_Dirs Set_Version_Custom_Settings local Create_Symlinks Auto_Startup create 2>/dev/null Auto_ServiceEvent create 2>/dev/null Auto_DNSMASQ create 2>/dev/null Shortcut_Script create ScriptHeader MainMenu exit 0 fi case "$1" in install) Check_Lock Menu_Install exit 0 ;; startup) Check_Lock if [ $# -gt 1 ] && [ "$2" != "force" ]; then sleep 5 fi Menu_Startup exit 0 ;; ##----------------------------------------## ## Modified by Martinski W. [2023-Apr-16] ## ##----------------------------------------## service_event) if [ "$2" = "start" ] then case "$3" in "$SCRIPT_NAME") Conf_FromSettings ;; "${SCRIPT_NAME}checkupdate") Update_Check ;; "${SCRIPT_NAME}doupdate") Update_Version force unattended ;; "${SCRIPT_NAME}checkIcons") CheckUserIconFiles ;; "${SCRIPT_NAME}backupIcons") BackUpUserIconFiles ;; "${SCRIPT_NAME}restoreIcons_reqList") GetSavedBackupFilesList ;; "${SCRIPT_NAME}restoreIcons_reqNum_"*) RestoreUserIconFilesReq "$3" ;; esac fi exit 0 ;; ##----------------------------------------------## ## Added/modified by Martinski W. [2023-Apr-15] ## ##----------------------------------------------## backupicons) BackUpUserIconFiles exit 0 ;; restoreicons) option="$([ $# -gt 1 ] && [ "$2" = "true" ] && echo "$2" || echo false)" RestoreUserIconFiles "$option" exit 0 ;; update) Update_Version unattended exit 0 ;; forceupdate) Update_Version force unattended exit 0 ;; setversion) Set_Version_Custom_Settings local Set_Version_Custom_Settings server "$SCRIPT_VERSION" if [ -z "$2" ]; then exec "$0" fi exit 0 ;; checkupdate) Update_Check exit 0 ;; uninstall) Check_Lock Menu_Uninstall exit 0 ;; develop) SCRIPT_BRANCH="develop" SCRIPT_REPO="https://jackyaz.io/$SCRIPT_NAME/$SCRIPT_BRANCH" Update_Version force exit 0 ;; stable) SCRIPT_BRANCH="master" SCRIPT_REPO="https://jackyaz.io/$SCRIPT_NAME/$SCRIPT_BRANCH" Update_Version force exit 0 ;; *) echo "Command not recognised, please try again" exit 1 ;; esac