#!/usr/bin/env bash set -u # Unbound variable errors are not allowed rploaderver="1.0.6.0" build="master" redpillmake="prod" modalias4="https://raw.githubusercontent.com/PeterSuh-Q3/tinycore-redpill/$build/modules.alias.4.json.gz" modalias3="https://raw.githubusercontent.com/PeterSuh-Q3/tinycore-redpill/$build/modules.alias.3.json.gz" timezone="UTC" ntpserver="pool.ntp.org" userconfigfile="/home/tc/user_config.json" gitdomain="raw.githubusercontent.com" mshellgz="my.sh.gz" mshtarfile="https://raw.githubusercontent.com/PeterSuh-Q3/tinycore-redpill/master/my.sh.gz" #Defaults smallfixnumber="0" function history() { cat < Options: update, postupdate, noconfig, noclean, manual, realmac, userdts - update : Option to handle updates to the m shell. - postupdate : Option to patch the restore loop after applying DSM 7.1.0-42661 after Update 2, no additional build required. - noconfig: SKIP automatic detection change processing such as SN/Mac/Vid/Pid/SataPortMap of user_config.json file. - noclean: SKIP the 💊 RedPill LKM/LOAD directory without clearing it with the Clean command. However, delete the Cache directory and loader.img. - manual: Options for manual extension processing and manual dtc processing in build action (skipping extension auto detection). - realmac : Option to use the NIC's real mac address instead of creating a virtual one. - userdts : Option to use the user-defined platform.dts file instead of auto-discovery mapping with dtcpatch. Please type Synology Model Name after ./$(basename ${0}) - for friend mode ./$(basename ${0}) DS918+-7.2.1-69057 ./$(basename ${0}) DS3617xs-7.2.1-69057 ./$(basename ${0}) DS3615xs-7.2.1-69057 ./$(basename ${0}) DS3622xs+-7.2.1-69057 ./$(basename ${0}) DVA3221-7.2.1-69057 ./$(basename ${0}) DS920+-7.2.1-69057 ./$(basename ${0}) DS1621+-7.2.1-69057 ./$(basename ${0}) DS2422+-7.2.1-69057 ./$(basename ${0}) DVA1622-7.2.1-69057 ./$(basename ${0}) DS1520+-7.2.1-69057 ./$(basename ${0}) FS2500-7.2.1-69057 ./$(basename ${0}) DS1621xs+-7.2.1-69057 ./$(basename ${0}) RS4021xs+-7.2.1-69057 ./$(basename ${0}) DVA3219-7.2.1-69057 ./$(basename ${0}) RS3618xs-7.2.1-69057 ./$(basename ${0}) DS1019+-7.2.1-69057 ./$(basename ${0}) DS923+-7.2.1-69057 ./$(basename ${0}) DS723+-7.2.1-69057 ./$(basename ${0}) SA6400-7.2.1-69057 ./$(basename ${0}) DS720+-7.2.1-69057 ./$(basename ${0}) RS1221+-7.2.1-69057 ./$(basename ${0}) RS2423+-7.2.1-69057 ./$(basename ${0}) RS1619xs+-7.2.1-69057 ./$(basename ${0}) RS3621xs+-7.2.1-69057 ./$(basename ${0}) SA6400-7.2.1-69057 ./$(basename ${0}) DS916+-7.2.1-69057 ./$(basename ${0}) DS1821+-7.2.1-69057 ./$(basename ${0}) DS1819+-7.2.1-69057 ./$(basename ${0}) DS1823xs+-7.2.1-69057 ./$(basename ${0}) DS620slim+-7.2.1-69057 ex) Except for postupdate and userdts that must be used alone, the rest of the options can be used in combination. - When you want to build the loader while maintaining the already set SN/Mac/Vid/Pid/SataPortMap ./my DS3622xs+H noconfig - When you want to build the loader while maintaining the already set SN/Mac/Vid/Pid/SataPortMap and without deleting the downloaded DSM pat file. ./my DS3622xs+H noconfig noclean - When you want to build the loader while using the real MAC address of the NIC, with extended auto-detection disabled ./my DS3622xs+H realmac manual EOF } function getloaderdisk() { loaderdisk="" for edisk in $(sudo fdisk -l | grep "Disk /dev/sd" | awk '{print $2}' | sed 's/://' ); do if [ $(sudo fdisk -l | grep "83 Linux" | grep ${edisk} | wc -l ) -eq 3 ]; then loaderdisk="$(blkid | grep ${edisk} | grep "6234-C863" | cut -c 1-8 | awk -F\/ '{print $3}')" fi done if [ -z "${loaderdisk}" ]; then for edisk in $(sudo fdisk -l | grep -e "Disk /dev/nvme" -e "Disk /dev/mmc" | awk '{print $2}' | sed 's/://' ); do if [ $(sudo fdisk -l | grep "83 Linux" | grep ${edisk} | wc -l ) -eq 3 ]; then loaderdisk="$(blkid | grep ${edisk} | grep "6234-C863" | cut -c 1-12 | awk -F\/ '{print $3}')" fi done fi if [ -z "${loaderdisk}" ]; then for edisk in $(sudo fdisk -l | grep "Disk /dev/loop" | awk '{print $2}' | sed 's/://' ); do if [ $(sudo fdisk -l | grep "83 Linux" | grep ${edisk} | wc -l ) -eq 3 ]; then loaderdisk="$(echo ${edisk} | cut -c 1-12 | awk -F\/ '{print $3}')" fi done fi } # ============================================================================== # Color Function # ============================================================================== function cecho () { # if [ -n "$3" ] # then # case "$3" in # black | bk) bgcolor="40";; # red | r) bgcolor="41";; # green | g) bgcolor="42";; # yellow | y) bgcolor="43";; # blue | b) bgcolor="44";; # purple | p) bgcolor="45";; # cyan | c) bgcolor="46";; # gray | gr) bgcolor="47";; # esac # else bgcolor="0" # fi code="\033[" case "$1" in black | bk) color="${code}${bgcolor};30m";; red | r) color="${code}${bgcolor};31m";; green | g) color="${code}${bgcolor};32m";; yellow | y) color="${code}${bgcolor};33m";; blue | b) color="${code}${bgcolor};34m";; purple | p) color="${code}${bgcolor};35m";; cyan | c) color="${code}${bgcolor};36m";; gray | gr) color="${code}${bgcolor};37m";; esac text="$color$2${code}0m" echo -e "$text" } function getvarsmshell() { SUVP="" ORIGIN_PLATFORM="" tem="${1}" MODEL="$(echo ${tem} |cut -d '-' -f 1)" TARGET_REVISION="$(echo ${tem} |cut -d '-' -f 3)" if [ "$TARGET_REVISION" == "64570" ]; then TARGET_VERSION="$(echo ${tem} |cut -d '-' -f 2 | cut -c 1-3)" else TARGET_VERSION="$(echo ${tem} |cut -d '-' -f 2)" fi #echo "MODEL is $MODEL" TARGET_PLATFORM=$(echo "$MODEL" | sed 's/DS/ds/' | sed 's/RS/rs/' | sed 's/+/p/' | sed 's/DVA/dva/' | sed 's/FS/fs/' | sed 's/SA/sa/' ) SYNOMODEL="${TARGET_PLATFORM}_${TARGET_REVISION}" MODELS="DS3615xs DS218+ DS1019+ DS620slim DS1520+ DS1522+ DS220+ DS2419+ DS423+ DS718+ DS1621+ DS1821+ DS1823xs+ DS1621xs+ DS2422+ DS3617xs DS3622xs+ DS720+ DS723+ DS918+ DS920+ DS923+ DS1819+ DVA3219 DVA3221 DVA1622 FS2500 RS1221+ RS1619xs+ RS2423+ RS3413xs+ RS3618xs RS3621xs+ RS4021xs+ SA3410 SA3610 SA6400" if [ $(echo ${MODELS} | grep ${MODEL} | wc -l ) -eq 0 ]; then echo "This synology model not supported by TCRP." exit 99 fi if [ "$TARGET_REVISION" == "42218" ]; then KVER="4.4.180" SUVP="" elif [ "$TARGET_REVISION" == "42962" ]; then KVER="4.4.180" MODELS6="DS423+ DS723+ DS923+ DS1823xs+ RS3621xs+ RS4021xs+ RS3618xs SA6400" if [ $(echo ${MODELS6} | grep ${MODEL} | wc -l ) -gt 0 ]; then SUVP="-6" else SUVP="-1" fi elif [ "$TARGET_REVISION" == "64570" ]; then KVER="4.4.302" SUVP="-1" elif [ "$TARGET_REVISION" == "69057" ]; then KVER="4.4.302" SUVP="" if [ "${MODEL}" = "DS218+" ]; then SUVP="-1" fi elif [ "$TARGET_REVISION" == "72806" ]; then KVER="4.4.302" SUVP="" else echo "Synology model revision not supported by TCRP." exit 0 fi case ${MODEL} in DS218+ | DS718+ | DS918+ | DS1019+ | DS620slim ) ORIGIN_PLATFORM="apollolake" ;; DS3615xs | RS3413xs+ ) ORIGIN_PLATFORM="bromolow" KVER="3.10.108" ;; DS3617xs | RS3618xs ) ORIGIN_PLATFORM="broadwell" ;; DS3622xs+ | DS1621xs+ | SA3400 | SA3600 | RS1619xs+ | RS3621xs+ | RS4021xs+ ) ORIGIN_PLATFORM="broadwellnk" ;; SA3410 | SA3610 ) ORIGIN_PLATFORM="broadwellnkv2" ;; DVA3221 | DVA3219 | DS1819+ | DS2419+ ) ORIGIN_PLATFORM="denverton" ;; DVA1622 | DS220+ | DS423+ | DS920+ | DS1520+ | DS720+ ) ORIGIN_PLATFORM="geminilake" ;; DS923+ | DS723+ | DS1522+ ) ORIGIN_PLATFORM="r1000" ;; DS1621+ | DS1821+ | DS1823xs+ | DS2422+ | FS2500 | RS1221+ | RS2423+ ) ORIGIN_PLATFORM="v1000" ;; SA6400 ) ORIGIN_PLATFORM="epyc7002" KVER="5.10.55" ;; esac case ${MODEL} in DS1019+) permanent="PDN" serialstart="1780 1790 1860 1980" suffix="numeric" ;; DS1520+) permanent="TRR" serialstart="2270" suffix="alpha" ;; DS1522+) permanent="TRR" serialstart="2270" suffix="alpha" ;; DS1621+) permanent="S7R" serialstart="2080" suffix="alpha" ;; DS1621xs+) permanent="S7R" serialstart="2080" suffix="alpha" ;; DS1819+) permanent="RFR" serialstart="1930 1940" suffix="alpha" ;; DS1821+) permanent="S7R" serialstart="2080" suffix="alpha" ;; DS1823xs+) permanent="V5R" serialstart="22B0" suffix="alpha" ;; DS220+) permanent="XXX" serialstart="0000" suffix="alpha" ;; DS2419+) permanent="QZA" serialstart="1880" suffix="alpha" ;; DS2422+) permanent="S7R" serialstart="2080" suffix="alpha" ;; DS3615xs) permanent="LWN" serialstart="1130 1230 1330 1430" suffix="numeric" ;; DS3617xs) permanent="ODN" serialstart="1130 1230 1330 1430" suffix="numeric" ;; DS3622xs+) permanent="SQR" serialstart="2030 2040 20C0 2150" suffix="alpha" ;; DS423+) permanent="VKR" serialstart="22A0" suffix="alpha" ;; DS218+) permanent="PDN" serialstart="1780 1790 1860 1980" suffix="numeric" ;; DS620slim) permanent="PDN" serialstart="1780 1790 1860 1980" suffix="numeric" ;; DS718+) permanent="PEN" serialstart="1930" suffix="numeric" ;; DS720+) permanent="SBR" serialstart="2030 2040 20C0 2150" suffix="alpha" ;; DS723+) permanent="TQR" serialstart="2270" suffix="alpha" ;; DS916+) permanent="NZN" serialstart="1130 1230 1330 1430" suffix="numeric" ;; DS918+) permanent="PDN" serialstart="1780 1790 1860 1980" suffix="numeric" ;; DS920+) permanent="SBR" serialstart="2030 2040 20C0 2150" suffix="alpha" ;; DS923+) permanent="TQR" serialstart="2270" suffix="alpha" ;; DVA1622) permanent="UBR" serialstart="2030 2040 20C0 2150" suffix="alpha" ;; DVA3219) permanent="RFR" serialstart="1930 1940" suffix="alpha" ;; DVA3221) permanent="SJR" serialstart="2030 2040 20C0 2150" suffix="alpha" ;; FS2500) permanent="PSN" serialstart="1960" suffix="numeric" ;; FS6400) permanent="PSN" serialstart="1960" suffix="numeric" ;; RS1221+) permanent="RWR" serialstart="20B0" suffix="alpha" ;; RS2423+) permanent="XXX" serialstart="0000" suffix="alpha" ;; RS1619xs+) permanent="QPR" serialstart="1920" suffix="alpha" ;; RS3413xs+) permanent="S7R" serialstart="2080" suffix="alpha" ;; RS3618xs) permanent="ODN" serialstart="1130 1230 1330 1430" suffix="numeric" ;; RS3621xs+) permanent="SZR" serialstart="20A0" suffix="alpha" ;; RS4021xs+) permanent="T2R" serialstart="2250" suffix="alpha" ;; SA3400) permanent="RJR" serialstart="1920" suffix="alpha" ;; SA3600) permanent="RJR" serialstart="1920" suffix="alpha" ;; SA6400) permanent="TQR" serialstart="2270" suffix="alpha" ;; *) permanent="XXX" serialstart="0000" suffix="alpha" ;; esac } # Function READ_YN, cecho # Made by FOXBI # 2022.04.14 # # ============================================================================== # Y or N Function # ============================================================================== function READ_YN () { # ${1}:question ${2}:default while true; do read -n1 -p "${1}" Y_N case "$Y_N" in [Yy]* ) Y_N="y" echo -e "\n"; break ;; [Nn]* ) Y_N="n" echo -e "\n"; break ;; *) echo -e "Please answer in Y / y or N / n.\n" ;; esac done } function st() { echo -e "[$(date '+%T.%3N')]:-------------------------------------------------------------" >> /home/tc/buildstatus echo -e "\e[35m$1\e[0m \e[36m$2\e[0m $3" >> /home/tc/buildstatus } function getlatestmshell() { echo -n "Checking if a newer mshell version exists on the repo -> " if [ ! -f $mshellgz ]; then curl -ksL "$mshtarfile" -o $mshellgz fi curl -ksL "$mshtarfile" -o latest.mshell.gz CURRENTSHA="$(sha256sum $mshellgz | awk '{print $1}')" REPOSHA="$(sha256sum latest.mshell.gz | awk '{print $1}')" if [ "${CURRENTSHA}" != "${REPOSHA}" ]; then if [ "${1}" = "noask" ]; then confirmation="y" else echo -n "There is a newer version of m shell script on the repo should we use that ? [yY/nN]" read confirmation fi if [ "$confirmation" = "y" ] || [ "$confirmation" = "Y" ]; then echo "OK, updating, please re-run after updating" cp -f /home/tc/latest.mshell.gz /home/tc/$mshellgz rm -f /home/tc/latest.mshell.gz tar -zxvf $mshellgz echo "Updating m shell with latest updates" . /home/tc/functions.sh showlastupdate echo "y"|rploader backup echo "press any key to continue..." read answer else rm -f /home/tc/latest.mshell.gz fi else echo "Version is current" rm -f /home/tc/latest.mshell.gz fi } function macgen() { echo if [ "$realmac" == 'Y' ] ; then mac2=$(ifconfig eth1 | head -1 | awk '{print $NF}') echo "Real Mac2 Address : $mac2" echo "Notice : realmac option is requested, real mac2 will be used" else mac2="$(generateMacAddress ${1})" fi cecho y "Mac2 Address for Model ${1} : $mac2 " macaddress2=$(echo $mac2 | sed -s 's/://g') if [ $(cat user_config.json | grep "mac2" | wc -l) -gt 0 ]; then bf_mac2="$(cat user_config.json | grep "mac2" | cut -d ':' -f 2 | cut -d '"' -f 2)" cecho y "The Mac2 address : $bf_mac2 already exists. Change an existing value." json="$(jq --arg var "$macaddress2" '.extra_cmdline.mac2 = $var' user_config.json)" && echo -E "${json}" | jq . >user_config.json # sed -i "/mac2/s/'$bf_mac2'/'$macaddress2'/g" user_config.json else sed -i "/\"extra_cmdline\": {/c\ \"extra_cmdline\": {\"mac2\": \"$macaddress2\",\"netif_num\": \"2\", " user_config.json fi echo "After changing user_config.json" cat user_config.json } function generateMacAddress() { printf '00:11:32:%02X:%02X:%02X' $((RANDOM % 256)) $((RANDOM % 256)) $((RANDOM % 256)) } function random() { printf "%06d" $(($RANDOM % 30000 + 1)) } function randomhex() { val=$(($RANDOM % 255 + 1)) echo "obase=16; $val" | bc } function generateRandomLetter() { for i in a b c d e f g h j k l m n p q r s t v w x y z; do echo $i done | sort -R | tail -1 } function generateRandomValue() { for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f g h j k l m n p q r s t v w x y z; do echo $i done | sort -R | tail -1 } function toupper() { echo $1 | tr '[:lower:]' '[:upper:]' } function generateSerial() { case ${suffix} in numeric) serialnum="$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(random) ;; alpha) serialnum=$(toupper "$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(generateRandomLetter)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomValue)$(generateRandomLetter)) ;; *) serialnum="$(echo "$serialstart" | tr ' ' '\n' | sort -R | tail -1)$permanent"$(random) ;; esac echo $serialnum } function msgalert() { echo -e "\033[1;31m$1\033[0m" } function msgwarning() { echo -e "\033[1;33m$1\033[0m" } function msgnormal() { echo -e "\033[1;32m$1\033[0m" } function readanswer() { while true; do read answ case $answ in [Yy]* ) answer="$answ"; break;; [Nn]* ) answer="$answ"; break;; * ) msgwarning "Please answer yY/nN.";; esac done } ############################################################################### # Write to json config file function writeConfigKey() { block="$1" field="$2" value="$3" if [ -n "$1 " ] && [ -n "$2" ]; then jsonfile=$(jq ".$block+={\"$field\":\"$value\"}" $userconfigfile) echo $jsonfile | jq . >$userconfigfile else echo "No values to update" fi } ############################################################################### # Delete field from json config file function DeleteConfigKey() { block="$1" field="$2" if [ -n "$1 " ] && [ -n "$2" ]; then jsonfile=$(jq "del(.$block.$field)" $userconfigfile) echo $jsonfile | jq . >$userconfigfile else echo "No values to remove" fi } function checkmachine() { if grep -q ^flags.*\ hypervisor\ /proc/cpuinfo; then MACHINE="VIRTUAL" HYPERVISOR=$(dmesg | grep -i "Hypervisor detected" | awk '{print $5}') echo "Machine is $MACHINE Hypervisor=$HYPERVISOR" else MACHINE="NON-VIRTUAL" fi if [ $(lspci -nn | grep -ie "\[0107\]" | wc -l) -gt 0 ]; then echo "Found SAS HBAs, Restrict use of DT Models." HBADETECT="ON" else HBADETECT="OFF" fi } function checkinternet() { echo -n "Checking Internet Access -> " # nslookup $gitdomain 2>&1 >/dev/null curl --insecure -L -s https://raw.githubusercontent.com/about.html -O 2>&1 >/dev/null if [ $? -eq 0 ]; then echo "OK" else cecho g "Error: No internet found, or $gitdomain is not accessible" gitdomain="giteas.duckdns.org" cecho p "Try to connect to $gitdomain......" nslookup $gitdomain 2>&1 >/dev/null if [ $? -eq 0 ]; then echo "OK" else cecho g "Error: No internet found, or $gitdomain is not accessible" exit 99 fi fi } ############################################################################### # check for Sas module function checkforsas() { sasmods="mpt3sas hpsa mvsas" for sasmodule in $sasmods do echo "Checking existense of $sasmodule" for sas in `depmod -n 2>/dev/null |grep -i $sasmodule |grep pci|cut -d":" -f 2 | cut -c 6-9,15-18` do if [ `grep -i $sas /proc/bus/pci/devices |wc -l` -gt 0 ] ; then echo " => $sasmodule, device found, block eudev mode" BLOCK_EUDEV="Y" fi done done } ############################################################################### # check Intel or AMD function checkcpu() { if [ $(lscpu |grep Intel |wc -l) -gt 0 ]; then CPU="INTEL" else if [ $(awk -F':' '/^model name/ {print $2}' /proc/cpuinfo | uniq | sed -e 's/^[ \t]*//' | grep -e N36L -e N40L -e N54L | wc -l) -gt 0 ]; then CPU="HP" LDRMODE="JOT" writeConfigKey "general" "loadermode" "${LDRMODE}" else CPU="AMD" fi fi threads="$(lscpu |grep CPU\(s\): | awk '{print $2}')" if [ $(lscpu |grep movbe |wc -l) -gt 0 ]; then AFTERHASWELL="ON" else AFTERHASWELL="OFF" fi if [ "$MACHINE" = "VIRTUAL" ] && [ "$HYPERVISOR" = "KVM" ]; then AFTERHASWELL="ON" fi } ############################################################################### # Get fastest url in list # @ - url list function _get_fastest() { local speedlist="" for I in $@; do speed=$(ping -c 1 -W 5 ${I} 2>/dev/null | awk '/time=/ {print $7}' | cut -d '=' -f 2) speedlist+="${I} ${speed:-999}\n" done fastest="$(echo -e "${speedlist}" | tr -s '\n' | sort -k2n | head -1 | awk '{print $1}')" echo "${fastest}" } function chkavail() { if [ $(df -h /mnt/${tcrppart} | grep mnt | awk '{print $4}' | grep G | wc -l) -gt 0 ]; then avail_str=$(df -h /mnt/${tcrppart} | grep mnt | awk '{print $4}' | sed -e 's/G//g' | cut -c 1-3) avail=$(echo "$avail_str 1000" | awk '{print $1 * $2}') else avail=$(df -h /mnt/${tcrppart} | grep mnt | awk '{print $4}' | sed -e 's/M//g' | cut -c 1-3) fi avail_num=$(($avail)) echo "Avail space ${avail_num}M on /mnt/${tcrppart}" } ############################################################################### # get bus of disk # 1 - device path function getBus() { BUS="" # usb/ata(sata/ide)/scsi [ -z "${BUS}" ] && BUS=$(udevadm info --query property --name "${1}" 2>/dev/null | grep ID_BUS | cut -d= -f2 | sed 's/ata/sata/') # usb/sata(sata/ide)/nvme [ -z "${BUS}" ] && BUS=$(lsblk -dpno KNAME,TRAN 2>/dev/null | grep "${1} " | awk '{print $2}') #Spaces are intentional # loop block [ -z "${BUS}" ] && BUS=$(lsblk -dpno KNAME,SUBSYSTEMS 2>/dev/null | grep "${1} " | awk '{print $2}') #Spaces are intentional # usb/scsi(sata/ide)/virtio(scsi/virtio)/mmc/nvme [ -z "${BUS}" ] && BUS=$(lsblk -dpno KNAME,SUBSYSTEMS 2>/dev/null | grep "${1} " | cut -d: -f2) #Spaces are intentional echo "${BUS}" } ############################################################################### # git clone redpill-load function gitdownload() { git config --global http.sslVerify false if [ -d "/home/tc/redpill-load" ]; then cecho y "Loader sources already downloaded, pulling latest !!!" cd /home/tc/redpill-load git pull if [ $? -ne 0 ]; then cd /home/tc rploader clean git clone -b master --single-branch https://github.com/PeterSuh-Q3/redpill-load.git #git clone -b master --single-branch https://giteas.duckdns.org/PeterSuh-Q3/redpill-load.git fi cd /home/tc else git clone -b master --single-branch https://github.com/PeterSuh-Q3/redpill-load.git #git clone -b master --single-branch https://giteas.duckdns.org/PeterSuh-Q3/redpill-load.git fi } function _pat_process() { PATURL="${URL}" PAT_FILE="${SYNOMODEL}.pat" PAT_PATH="${patfile}" #mirrors=("global.synologydownload.com" "global.download.synology.com" "cndl.synology.cn") mirrors=("global.synologydownload.com" "global.download.synology.com") fastest=$(_get_fastest "${mirrors[@]}") echo "fastest = " "${fastest}" mirror="$(echo ${PATURL} | sed 's|^http[s]*://\([^/]*\).*|\1|')" echo "mirror = " "${mirror}" if echo "${mirrors[@]}" | grep -wq "${mirror}" && [ "${mirror}" != "${fastest}" ]; then echo "Based on the current network situation, switch to ${fastest} mirror to downloading." PATURL="$(echo ${PATURL} | sed "s/${mirror}/${fastest}/")" fi # Discover remote file size if [ "${BUS}" != "block" ]; then SPACELEFT=$(df --block-size=1 | awk '/'${loaderdisk}'3/{print $4}') # Check disk space left FILESIZE=$(curl -k -sLI "${PATURL}" | grep -i Content-Length | awk '{print$2}') FILESIZE_FORMATTED=$(printf "%'d" "${FILESIZE}") SPACELEFT_FORMATTED=$(printf "%'d" "${SPACELEFT}") FILESIZE_MB=$((FILESIZE / 1024 / 1024)) SPACELEFT_MB=$((SPACELEFT / 1024 / 1024)) echo "FILESIZE = ${FILESIZE_FORMATTED} bytes (${FILESIZE_MB} MB)" echo "SPACELEFT = ${SPACELEFT_FORMATTED} bytes (${SPACELEFT_MB} MB)" if [ 0${FILESIZE} -ge 0${SPACELEFT} ]; then # No disk space to download, change it to RAMDISK echo "No adequate space on ${local_cache} to download file into cache folder, clean up PAT file now ....." sudo sh -c "rm -vf $(ls -t ${local_cache}/*.pat | head -n 1)" fi fi echo "PATURL = " "${PATURL}" STATUS=$(curl -k -w "%{http_code}" -L "${PATURL}" -o "${PAT_PATH}" --progress-bar) if [ $? -ne 0 -o ${STATUS} -ne 200 ]; then rm -f "${PAT_PATH}" echo "Check internet or cache disk space.\nError: ${STATUS}" exit 99 fi } function setnetwork() { if [ -f /opt/eth*.sh ] && [ "$(grep dhcp /opt/eth*.sh | wc -l)" -eq 0 ]; then ipset="static" ipgw="$(route | grep default | head -1 | awk '{print $2}')" ipprefix="$(grep ifconfig /opt/eth*.sh | head -1 | awk '{print "ipcalc -p " $3 " " $5 }' | sh - | awk -F= '{print $2}')" myip="$(grep ifconfig /opt/eth*.sh | head -1 | awk '{print $3 }')" ipaddr="${myip}/${ipprefix}" ipgw="$(grep route /opt/eth*.sh | head -1 | awk '{print $5 }')" ipdns="$(grep nameserver /opt/eth*.sh | head -1 | awk '{print $3 }')" ipproxy="$(env | grep -i http | awk -F= '{print $2}' | uniq)" for field in ipset ipaddr ipgw ipdns ipproxy; do jsonfile=$(jq ".ipsettings+={\"$field\":\"${!field}\"}" $userconfigfile) echo $jsonfile | jq . >$userconfigfile done fi } function getip() { ethdevs=$(ls /sys/class/net/ | grep eth || true) for eth in $ethdevs; do DRIVER=$(ls -ld /sys/class/net/${eth}/device/driver 2>/dev/null | awk -F '/' '{print $NF}') if [ $(ls -l /sys/class/net/${eth}/device | grep "0000:" | wc -l) -gt 0 ]; then BUSID=$(ls -ld /sys/class/net/${eth}/device 2>/dev/null | awk -F '0000:' '{print $NF}') else BUSID="" fi IP="$(ifconfig ${eth} | grep inet | awk '{print $2}' | awk -F \: '{print $2}')" HWADDR="$(ifconfig ${eth} | grep HWaddr | awk '{print $5}')" if [ -f /sys/class/net/${eth}/device/vendor ] && [ -f /sys/class/net/${eth}/device/device ]; then VENDOR=$(cat /sys/class/net/${eth}/device/vendor | sed 's/0x//') DEVICE=$(cat /sys/class/net/${eth}/device/device | sed 's/0x//') if [ ! -z "${VENDOR}" ] && [ ! -z "${DEVICE}" ]; then MATCHDRIVER=$(echo "$(matchpciidmodule ${VENDOR} ${DEVICE})") if [ ! -z "${MATCHDRIVER}" ]; then if [ "${MATCHDRIVER}" != "${DRIVER}" ]; then DRIVER=${MATCHDRIVER} fi fi fi fi echo "IP Addr : $(msgnormal "${IP}"), ${HWADDR}, ${BUSID}, ${eth} (${DRIVER})" done } function listpci() { lspci -n | while read line; do bus="$(echo $line | cut -c 1-7)" class="$(echo $line | cut -c 9-12)" vendor="$(echo $line | cut -c 15-18)" device="$(echo $line | cut -c 20-23)" #echo "PCI : $bus Class : $class Vendor: $vendor Device: $device" case $class in # 0100) # echo "Found SCSI Controller : pciid ${vendor}d0000${device} Required Extension : $(matchpciidmodule ${vendor} ${device})" # ;; # 0106) # echo "Found SATA Controller : pciid ${vendor}d0000${device} Required Extension : $(matchpciidmodule ${vendor} ${device})" # ;; # 0101) # echo "Found IDE Controller : pciid ${vendor}d0000${device} Required Extension : $(matchpciidmodule ${vendor} ${device})" # ;; 0104) msgnormal "RAID bus Controller : Required Extension : $(matchpciidmodule ${vendor} ${device})" echo `lspci -nn |grep ${vendor}:${device}|awk 'match($0,/0104/) {print substr($0,RSTART+7,100)}'`| sed 's/\['"$vendor:$device"'\]//' | sed 's/(rev 05)//' ;; 0107) msgnormal "SAS Controller : Required Extension : $(matchpciidmodule ${vendor} ${device})" echo `lspci -nn |grep ${vendor}:${device}|awk 'match($0,/0107/) {print substr($0,RSTART+7,100)}'`| sed 's/\['"$vendor:$device"'\]//' | sed 's/(rev 03)//' ;; # 0200) # msgnormal "Ethernet Interface : Required Extension : $(matchpciidmodule ${vendor} ${device})" # ;; # 0680) # msgnormal "Ethernet Interface : Required Extension : $(matchpciidmodule ${vendor} ${device})" # ;; # 0300) # echo "Found VGA Controller : pciid ${vendor}d0000${device} Required Extension : $(matchpciidmodule ${vendor} ${device})" # ;; # 0c04) # echo "Found Fibre Channel Controller : pciid ${vendor}d0000${device} Required Extension : $(matchpciidmodule ${vendor} ${device})" # ;; esac done } function monitor() { getloaderdisk if [ -z "${loaderdisk}" ]; then echo "Not Supported Loader BUS Type, program Exit!!!" exit 99 fi getBus "${loaderdisk}" [ "${BUS}" = "nvme" ] && loaderdisk="${loaderdisk}p" [ "${BUS}" = "mmc" ] && loaderdisk="${loaderdisk}p" [ "${BUS}" = "block" ] && loaderdisk="${loaderdisk}p" [ "$(mount | grep /dev/${loaderdisk}1 | wc -l)" -eq 0 ] && mount /dev/${loaderdisk}1 [ "$(mount | grep /dev/${loaderdisk}2 | wc -l)" -eq 0 ] && mount /dev/${loaderdisk}2 HYPERVISOR=$(dmesg | grep -i "Hypervisor detected" | awk '{print $5}') while true; do clear echo -e "-------------------------------System Information----------------------------" echo -e "Hostname:\t\t"$(hostname) echo -e "uptime:\t\t\t"$(uptime | awk '{print $3}' | sed 's/,//')" min" echo -e "Manufacturer:\t\t"$(cat /sys/class/dmi/id/chassis_vendor) echo -e "Product Name:\t\t"$(cat /sys/class/dmi/id/product_name) echo -e "Version:\t\t"$(cat /sys/class/dmi/id/product_version) echo -e "Serial Number:\t\t"$(sudo cat /sys/class/dmi/id/product_serial) echo -e "Operating System:\t"$(grep PRETTY_NAME /etc/os-release | awk -F \= '{print $2}') echo -e "Kernel:\t\t\t"$(uname -r) echo -e "Processor Name:\t\t"$(awk -F':' '/^model name/ {print $2}' /proc/cpuinfo | uniq | sed -e 's/^[ \t]*//') echo -e "Machine Type:\t\t"$( vserver=$(lscpu | grep Hypervisor | wc -l) if [ $vserver -gt 0 ]; then echo "VM (${HYPERVISOR})"; else echo "Physical"; fi ) msgnormal "CPU Threads:\t\t"$(lscpu |grep CPU\(s\): | awk '{print $2}') echo -e "Current Date Time:\t"$(date) #msgnormal "System Main IP:\t\t"$(ifconfig | grep inet | grep -v 127.0.0.1 | awk '{print $2}' | awk -F \: '{print $2}' | tr '\n' ',' | sed 's#,$##') getip listpci echo -e "-------------------------------Loader boot entries---------------------------" grep -i menuentry /mnt/${loaderdisk}1/boot/grub/grub.cfg | awk -F \' '{print $2}' echo -e "-------------------------------CPU / Memory----------------------------------" msgnormal "Total Memory (MB):\t"$(cat /proc/meminfo |grep MemTotal | awk '{printf("%.2f%"), $2/1000}') echo -e "Swap Usage:\t\t"$(free | awk '/Swap/{printf("%.2f%"), $3/$2*100}') echo -e "CPU Usage:\t\t"$(cat /proc/stat | awk '/cpu/{printf("%.2f%\n"), ($2+$4)*100/($2+$4+$5)}' | awk '{print $0}' | head -1) echo -e "-------------------------------Disk Usage >80%-------------------------------" df -Ph /mnt/${loaderdisk}1 /mnt/${loaderdisk}2 /mnt/${loaderdisk}3 echo "Press ctrl-c to exit" sleep 10 done } function savesession() { lastsessiondir="/mnt/${tcrppart}/lastsession" echo -n "Saving user session for future use. " [ ! -d ${lastsessiondir} ] && sudo mkdir ${lastsessiondir} echo -n "Saving current extensions " cat /home/tc/redpill-load/custom/extensions/*/*json | jq '.url' >${lastsessiondir}/extensions.list [ -f ${lastsessiondir}/extensions.list ] && echo " -> OK !" echo -n "Saving current user_config.json " cp /home/tc/user_config.json ${lastsessiondir}/user_config.json [ -f ${lastsessiondir}/user_config.json ] && echo " -> OK !" } function copyextractor() { #m shell mofified local_cache="/mnt/${tcrppart}/auxfiles" echo "making directory ${local_cache}" [ ! -d ${local_cache} ] && mkdir ${local_cache} echo "making directory ${local_cache}/extractor" [ ! -d ${local_cache}/extractor ] && mkdir ${local_cache}/extractor [ ! -f /home/tc/extractor.gz ] && sudo curl -kL -# "https://raw.githubusercontent.com/PeterSuh-Q3/tinycore-redpill/master/extractor.gz" -o /home/tc/extractor.gz sudo tar -zxvf /home/tc/extractor.gz -C ${local_cache}/extractor if [ "${BUS}" = "block" ]; then git clone https://github.com/technorabilia/syno-extract-system-patch.git cd syno-extract-system-patch sudo docker build --tag syno-extract-system-patch . sudo mkdir -p ~/data/in sudo mkdir -p ~/data/out fi echo "Copying required libraries to local lib directory" sudo cp /mnt/${tcrppart}/auxfiles/extractor/lib* /lib/ echo "Linking lib to lib64" [ ! -h /lib64 ] && sudo ln -s /lib /lib64 echo "Copying executable" sudo cp /mnt/${tcrppart}/auxfiles/extractor/scemd /bin/syno_extract_system_patch echo "pigz copy for multithreaded compression" sudo cp /mnt/${tcrppart}/auxfiles/extractor/pigz /usr/bin/pigz } function downloadextractor() { st "extractor" "Extraction tools" "Extraction Tools downloaded" # loaderdisk="$(mount | grep -i optional | grep cde | awk -F / '{print $3}' | uniq | cut -c 1-3)" # tcrppart="$(mount | grep -i optional | grep cde | awk -F / '{print $3}' | uniq | cut -c 1-3)3" local_cache="/mnt/${tcrppart}/auxfiles" temp_folder="/tmp/synoesp" #m shell mofified copyextractor if [ -d ${local_cache/extractor /} ] && [ -f ${local_cache}/extractor/scemd ]; then msgnormal "Found extractor locally cached" else echo "Getting required extraction tool" echo "------------------------------------------------------------------" echo "Checking tinycore cache folder" [ -d $local_cache ] && echo "Found tinycore cache folder, linking to home/tc/custom-module" && [ ! -h /home/tc/custom-module ] && sudo ln -s $local_cache /home/tc/custom-module echo "Creating temp folder /tmp/synoesp" mkdir ${temp_folder} if [ -d /home/tc/custom-module ] && [ -f /home/tc/custom-module/*42218*.pat ]; then patfile=$(ls /home/tc/custom-module/*42218*.pat | head -1) echo "Found custom pat file ${patfile}" echo "Processing old pat file to extract required files for extraction" tar -C${temp_folder} -xf /${patfile} rd.gz else curl -kL https://global.download.synology.com/download/DSM/release/7.0.1/42218/DSM_DS3622xs%2B_42218.pat -o /home/tc/oldpat.tar.gz [ -f /home/tc/oldpat.tar.gz ] && tar -C${temp_folder} -xf /home/tc/oldpat.tar.gz rd.gz fi echo "Entering synoesp" cd ${temp_folder} xz -dc rd 2>/dev/null || echo "extract rd.gz" echo "finish" cpio -idm &1 || echo "extract rd" mkdir extract mkdir /mnt/${tcrppart}/auxfiles && cd /mnt/${tcrppart}/auxfiles echo "Copying required files to local cache folder for future use" mkdir /mnt/${tcrppart}/auxfiles/extractor for file in usr/lib/libcurl.so.4 usr/lib/libmbedcrypto.so.5 usr/lib/libmbedtls.so.13 usr/lib/libmbedx509.so.1 usr/lib/libmsgpackc.so.2 usr/lib/libsodium.so usr/lib/libsynocodesign-ng-virtual-junior-wins.so.7 usr/syno/bin/scemd; do echo "Copying $file to /mnt/${tcrppart}/auxfiles" cp $file /mnt/${tcrppart}/auxfiles/extractor done fi echo "Removing temp folder /tmp/synoesp" rm -rf $temp_folder if [ "${BUS}" != "block" ]; then msgnormal "Checking if tool is accessible" if [ -d ${local_cache/extractor /} ] && [ -f ${local_cache}/extractor/scemd ]; then /bin/syno_extract_system_patch 2>&1 >/dev/null else /bin/syno_extract_system_patch fi if [ $? -eq 255 ]; then echo "Executed succesfully"; else echo "Cound not execute"; fi fi } function testarchive() { archive="$1" if [ "${BUS}" != "block" ]; then archiveheader="$(od -bc ${archive} | awk 'NR==1 {print $3; exit}')" case ${archiveheader} in 105) echo "${archive}, is a Tar file" isencrypted="no" return 0 ;; 255) echo "File ${archive}, is encrypted" isencrypted="yes" return 1 ;; 213) echo "File ${archive}, is a compressed tar" isencrypted="no" ;; *) echo "Could not determine if file ${archive} is encrypted or not, maybe corrupted" ls -ltr ${archive} echo ${archiveheader} exit 99 ;; esac else if [ ${TARGET_REVISION} -gt 42218 ]; then echo "Found build request for revision greater than 42218" echo "File ${archive}, is encrypted" isencrypted="yes" return 1 else echo "Found build request for revision less equal than 42218" echo "${archive}, is a Tar file" isencrypted="no" return 0 fi fi } function processpat() { # loaderdisk="$(mount | grep -i optional | grep cde | awk -F / '{print $3}' | uniq | cut -c 1-3)" # tcrppart="$(mount | grep -i optional | grep cde | awk -F / '{print $3}' | uniq | cut -c 1-3)3" local_cache="/mnt/${tcrppart}/auxfiles" temp_pat_folder="/tmp/pat" temp_dsmpat_folder="/tmp/dsmpat" setplatform if [ ! -d "${temp_pat_folder}" ]; then msgnormal "Creating temp folder ${temp_pat_folder} " mkdir ${temp_pat_folder} && sudo mount -t tmpfs -o size=512M tmpfs ${temp_pat_folder} && cd ${temp_pat_folder} mkdir ${temp_dsmpat_folder} && sudo mount -t tmpfs -o size=512M tmpfs ${temp_dsmpat_folder} fi echo "Checking for cached pat file" [ -d $local_cache ] && msgnormal "Found tinycore cache folder, linking to home/tc/custom-module" && [ ! -h /home/tc/custom-module ] && sudo ln -s $local_cache /home/tc/custom-module if [ -d ${local_cache} ] && [ -f ${local_cache}/*${SYNOMODEL}*.pat ] || [ -f ${local_cache}/*${MODEL}*${TARGET_REVISION}*.pat ]; then [ -f /home/tc/custom-module/*${SYNOMODEL}*.pat ] && patfile=$(ls /home/tc/custom-module/*${SYNOMODEL}*.pat | head -1) [ -f ${local_cache}/*${MODEL}*${TARGET_REVISION}*.pat ] && patfile=$(ls /home/tc/custom-module/*${MODEL}*${TARGET_REVISION}*.pat | head -1) msgnormal "Found locally cached pat file ${patfile}" st "iscached" "Caching pat file" "Patfile ${SYNOMODEL}.pat is cached" testarchive "${patfile}" if [ ${isencrypted} = "no" ]; then echo "File ${patfile} is already unencrypted" msgnormal "Copying file to /home/tc/redpill-load/cache folder" mv -f ${patfile} /home/tc/redpill-load/cache/ elif [ ${isencrypted} = "yes" ]; then [ -f /home/tc/redpill-load/cache/${SYNOMODEL}.pat ] && testarchive /home/tc/redpill-load/cache/${SYNOMODEL}.pat if [ -f /home/tc/redpill-load/cache/${SYNOMODEL}.pat ] && [ ${isencrypted} = "no" ]; then echo "Unecrypted file is already cached in : /home/tc/redpill-load/cache/${SYNOMODEL}.pat" else if [ "${BUS}" = "block" ]; then echo "Copy encrypted pat file : ${patfile} to ~/data/in" mv -f ${patfile} ~/data/in/${SYNOMODEL}.pat echo "Extracting encrypted pat file : ~/data/in/${SYNOMODEL}.pat to ~/data/out" sudo docker run --rm -v ~/data:/data syno-extract-system-patch /data/in/${SYNOMODEL}.pat /data/out/. || echo "extract latest pat" rsync -a --remove-source-files ~/data/out/ ${temp_pat_folder}/ else echo "Copy encrypted pat file : ${patfile} to ${temp_dsmpat_folder}" mv -f ${patfile} ${temp_dsmpat_folder}/${SYNOMODEL}.pat echo "Extracting encrypted pat file : ${temp_dsmpat_folder}/${SYNOMODEL}.pat to ${temp_pat_folder}" sudo /bin/syno_extract_system_patch ${temp_dsmpat_folder}/${SYNOMODEL}.pat ${temp_pat_folder} || echo "extract latest pat" fi echo "Creating unecrypted pat file ${SYNOMODEL}.pat to /home/tc/redpill-load/cache folder (multithreaded comporession)" mkdir -p /home/tc/redpill-load/cache/ thread=$(lscpu |grep CPU\(s\): | awk '{print $2}') if [ "${BUS}" = "block" ]; then cd ${temp_pat_folder} && tar -cf ${temp_dsmpat_folder}/${SYNOMODEL}.pat ./ && cp -f ${temp_dsmpat_folder}/${SYNOMODEL}.pat /home/tc/redpill-load/cache/${SYNOMODEL}.pat else cd ${temp_pat_folder} && tar -cf - ./ | pigz -p $thread > ${temp_dsmpat_folder}/${SYNOMODEL}.pat && cp -f ${temp_dsmpat_folder}/${SYNOMODEL}.pat /home/tc/redpill-load/cache/${SYNOMODEL}.pat fi fi patfile="/home/tc/redpill-load/cache/${SYNOMODEL}.pat" else echo "Something went wrong, please check cache files" exit 99 fi cd /home/tc/redpill-load/cache st "patextraction" "Pat file extracted" "VERSION:${TARGET_VERSION}-${TARGET_REVISION}" tar xvf /home/tc/redpill-load/cache/${SYNOMODEL}.pat ./VERSION && . ./VERSION && cat ./VERSION && rm ./VERSION os_sha256=$(sha256sum /home/tc/redpill-load/cache/${SYNOMODEL}.pat | awk '{print $1}') msgnormal "Pat file sha256sum is : $os_sha256" echo -n "Checking config file existence -> " if [ -f "/home/tc/redpill-load/config/$MODEL/${major}.${minor}.${micro}-${buildnumber}/config.json" ]; then echo "OK" configfile="/home/tc/redpill-load/config/$MODEL/${major}.${minor}.${micro}-${buildnumber}/config.json" else echo "No config file found, please use the proper repo, clean and download again" exit 99 fi msgnormal "Editing config file !!!!!" sed -i "/\"os\": {/!b;n;n;n;c\"sha256\": \"$os_sha256\"" ${configfile} echo -n "Verifying config file -> " verifyid="$(cat ${configfile} | jq -r -e '.os .sha256')" if [ "$os_sha256" == "$verifyid" ]; then echo "OK ! " else echo "config file, os sha256 verify FAILED, check ${configfile} " exit 99 fi msgnormal "Clearing temp folders" sudo umount ${temp_pat_folder} && sudo rm -rf ${temp_pat_folder} sudo umount ${temp_dsmpat_folder} && sudo rm -rf ${temp_dsmpat_folder} return else echo "Could not find pat file locally cached" configdir="/home/tc/redpill-load/config/${MODEL}/${TARGET_VERSION}-${TARGET_REVISION}" configfile="${configdir}/config.json" pat_url=$(cat ${configfile} | jq '.os .pat_url' | sed -s 's/"//g') echo -e "Configdir : $configdir \nConfigfile: $configfile \nPat URL : $pat_url" echo "Downloading pat file from URL : ${pat_url} " chkavail if [ $avail_num -le 370 ]; then echo "No adequate space on ${local_cache} to download file into cache folder, clean up the space and restart" exit 99 fi [ -n $pat_url ] && curl -kL ${pat_url} -o "/${local_cache}/${SYNOMODEL}.pat" patfile="/${local_cache}/${SYNOMODEL}.pat" if [ -f ${patfile} ]; then testarchive ${patfile} else echo "Failed to download PAT file $patfile from ${pat_url} " exit 99 fi if [ "${isencrypted}" = "yes" ]; then echo "File ${patfile}, has been cached but its encrypted, re-running decrypting process" processpat else return fi fi } function addrequiredexts() { echo "Processing add_extensions entries found on custom_config.json file : ${EXTENSIONS}" for extension in ${EXTENSIONS_SOURCE_URL}; do echo "Adding extension ${extension} " cd /home/tc/redpill-load/ && ./ext-manager.sh add "$(echo $extension | sed -s 's/"//g' | sed -s 's/,//g')" if [ $? -ne 0 ]; then echo "FAILED : Processing add_extensions failed check the output for any errors" rploader clean exit 99 fi done if [ "${ORIGIN_PLATFORM}" = "epyc7002" ]; then vkersion=${major}${minor}_${KVER} else vkersion=${KVER} fi for extension in ${EXTENSIONS}; do echo "Updating extension : ${extension} contents for platform, kernel : ${ORIGIN_PLATFORM}, ${vkersion} " platkver="$(echo ${ORIGIN_PLATFORM}_${vkersion} | sed 's/\.//g')" echo "platkver = ${platkver}" cd /home/tc/redpill-load/ && ./ext-manager.sh _update_platform_exts ${platkver} ${extension} if [ $? -ne 0 ]; then echo "FAILED : Processing add_extensions failed check the output for any errors" rploader clean exit 99 fi done #m shell only #Use user define dts file instaed of dtbpatch ext now if [ ${ORIGIN_PLATFORM} = "geminilake" ] || [ ${ORIGIN_PLATFORM} = "v1000" ] || [ ${ORIGIN_PLATFORM} = "r1000" ]; then echo "For user define dts file instaed of dtbpatch ext" patchdtc echo "Patch dtc is superseded by fbelavenuto dtbpatch" fi } function updateuserconfig() { echo "Checking user config for general block" generalblock="$(jq -r -e '.general' $userconfigfile)" if [ "$generalblock" = "null" ] || [ -n "$generalblock" ]; then echo "Result=${generalblock}, File does not contain general block, adding block" for field in model version smallfixnumber redpillmake zimghash rdhash usb_line sata_line; do jsonfile=$(jq ".general+={\"$field\":\"\"}" $userconfigfile) echo $jsonfile | jq . >$userconfigfile done fi } function updateuserconfigfield() { block="$1" field="$2" value="$3" if [ -n "$1 " ] && [ -n "$2" ]; then jsonfile=$(jq ".$block+={\"$field\":\"$value\"}" $userconfigfile) echo $jsonfile | jq . >$userconfigfile else echo "No values to update specified" fi } function postupdate() { # loaderdisk="$(mount | grep -i optional | grep cde | awk -F / '{print $3}' | uniq | cut -c 1-3)" cd /home/tc updateuserconfig setnetwork updateuserconfigfield "general" "model" "$MODEL" updateuserconfigfield "general" "version" "${TARGET_VERSION}-${TARGET_REVISION}" updateuserconfigfield "general" "smallfixnumber" "${smallfixnumber}" updateuserconfigfield "general" "redpillmake" "${redpillmake}-${TAG}" echo "Creating temp ramdisk space" && mkdir /home/tc/ramdisk echo "Mounting partition ${loaderdisk}1" && sudo mount /dev/${loaderdisk}1 echo "Mounting partition ${loaderdisk}2" && sudo mount /dev/${loaderdisk}2 zimghash=$(sha256sum /mnt/${loaderdisk}2/zImage | awk '{print $1}') updateuserconfigfield "general" "zimghash" "$zimghash" rdhash=$(sha256sum /mnt/${loaderdisk}2/rd.gz | awk '{print $1}') updateuserconfigfield "general" "rdhash" "$rdhash" zimghash=$(sha256sum /mnt/${loaderdisk}2/zImage | awk '{print $1}') updateuserconfigfield "general" "zimghash" "$zimghash" rdhash=$(sha256sum /mnt/${loaderdisk}2/rd.gz | awk '{print $1}') updateuserconfigfield "general" "rdhash" "$rdhash" echo "Backing up $userconfigfile " cp $userconfigfile /mnt/${loaderdisk}3 cd /home/tc/ramdisk echo "Extracting update ramdisk" if [ $(od /mnt/${loaderdisk}2/rd.gz | head -1 | awk '{print $2}') == "000135" ]; then sudo unlzma -c /mnt/${loaderdisk}2/rd.gz | cpio -idm 2>&1 >/dev/null else sudo cat /mnt/${loaderdisk}2/rd.gz | cpio -idm 2>&1 >/dev/null fi . ./etc.defaults/VERSION && echo "Found Version : ${productversion}-${buildnumber}-${smallfixnumber}" # echo -n "Do you want to use this for the loader ? [yY/nN] : " # readanswer # if [ "$answer" == "y" ] || [ "$answer" == "Y" ]; then echo "Extracting redpill ramdisk" if [ $(od /mnt/${loaderdisk}3/rd.gz | head -1 | awk '{print $2}') == "000135" ]; then sudo unlzma -c /mnt/${loaderdisk}3/rd.gz | cpio -idm RD_COMPRESSED="yes" else sudo cat /mnt/${loaderdisk}3/rd.gz | cpio -idm fi . ./etc.defaults/VERSION && echo "The new smallupdate version will be : ${productversion}-${buildnumber}-${smallfixnumber}" # echo -n "Do you want to use this for the loader ? [yY/nN] : " # readanswer # if [ "$answer" == "y" ] || [ "$answer" == "Y" ]; then echo "Recreating ramdisk " if [ "$RD_COMPRESSED" = "yes" ]; then sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root | xz -9 --format=lzma >../rd.gz else sudo find . 2>/dev/null | sudo cpio -o -H newc -R root:root >../rd.gz fi cd .. echo "Adding fake sign" && sudo dd if=/dev/zero of=rd.gz bs=68 count=1 conv=notrunc oflag=append echo "Putting ramdisk back to the loader partition ${loaderdisk}1" && sudo cp -f rd.gz /mnt/${loaderdisk}3/rd.gz echo "Removing temp ramdisk space " && rm -rf ramdisk echo "Done" # else # echo "Removing temp ramdisk space " && rm -rf ramdisk # exit 0 # fi #m shell only checkmachine if [ "$MACHINE" = "VIRTUAL" ]; then echo "Setting default boot entry to SATA" sudo sed -i "/set default=/cset default=\"1\"" /mnt/${loaderdisk}1/boot/grub/grub.cfg else echo "Setting default boot entry to USB" sudo sed -i "/set default=/cset default=\"0\"" /mnt/${loaderdisk}1/boot/grub/grub.cfg fi # fi } function getbspatch() { if [ ! -f /usr/local/bspatch ]; then #echo "bspatch does not exist, bringing over from repo" #curl -kL "https://raw.githubusercontent.com/PeterSuh-Q3/tinycore-redpill/$build/tools/bspatch" -O echo "bspatch does not exist, copy from tools" chmod 777 /home/tc/tools/bspatch sudo cp -vf /home/tc/tools/bspatch /usr/local/bin/ fi } function removemodelexts() { echo "Entering redpill-load directory to remove exts" cd /home/tc/redpill-load/ echo "Removing all exts directories..." sudo rm -rf /home/tc/redpill-load/custom/extensions/* #echo "Removing model exts directories..." #for modelextdir in ${EXTENSIONS}; do # if [ -d /home/tc/redpill-load/custom/extensions/${modelextdir} ]; then # echo "Removing : ${modelextdir}" # sudo rm -rf /home/tc/redpill-load/custom/extensions/${modelextdir} # fi #done } function getPlatforms() { platform_versions=$(jq -s '.[0].build_configs=(.[1].build_configs + .[0].build_configs | unique_by(.id)) | .[0]' custom_config.json | jq -r '.build_configs[].id') echo "platform_versions=$platform_versions" } function selectPlatform() { platform_selected=$(jq -s '.[0].build_configs=(.[1].build_configs + .[0].build_configs | unique_by(.id)) | .[0]' custom_config.json | jq ".build_configs[] | select(.id==\"${1}\")") echo "platform_selected=${platform_selected}" } function getValueByJsonPath() { local JSONPATH=${1} local CONFIG=${2} jq -c -r "${JSONPATH}" <<<${CONFIG} } function readConfig() { if [ ! -e custom_config.json ]; then cat global_config.json else jq -s '.[0].build_configs=(.[1].build_configs + .[0].build_configs | unique_by(.id)) | .[0]' custom_config.json fi } function setplatform() { SYNOMODEL=${TARGET_PLATFORM}_${TARGET_REVISION} MODEL=$(echo "${TARGET_PLATFORM}" | sed 's/ds/DS/' | sed 's/rs/RS/' | sed 's/p/+/' | sed 's/dva/DVA/' | sed 's/fs/FS/' | sed 's/sa/SA/' ) ORIGIN_PLATFORM="$(echo $platform_selected | jq -r -e '.platform_name')" } function getvars() { KVER="$(jq -r -e '.general.kver' $userconfigfile)" CONFIG=$(readConfig) selectPlatform $1 GETTIME=$(curl -k -v -s https://google.com/ 2>&1 | grep Date | sed -e 's/< Date: //') INTERNETDATE=$(date +"%d%m%Y" -d "$GETTIME") LOCALDATE=$(date +"%d%m%Y") #EXTENSIONS="$(echo $platform_selected | jq -r -e '.add_extensions[]')" EXTENSIONS="$(echo $platform_selected | jq -r -e '.add_extensions[]' | grep json | awk -F: '{print $1}' | sed -s 's/"//g')" #EXTENSIONS_SOURCE_URL="$(echo $platform_selected | jq '.add_extensions[] .url')" EXTENSIONS_SOURCE_URL="$(echo $platform_selected | jq '.add_extensions[]' | grep json | awk '{print $2}')" TARGET_PLATFORM="$(echo $platform_selected | jq -r -e '.id | split("-")' | jq -r -e .[0])" TARGET_VERSION="$(echo $platform_selected | jq -r -e '.id | split("-")' | jq -r -e .[1])" TARGET_REVISION="$(echo $platform_selected | jq -r -e '.id | split("-")' | jq -r -e .[2])" tcrppart="${tcrpdisk}3" local_cache="/mnt/${tcrppart}/auxfiles" usbpart1uuid=$(blkid /dev/${tcrpdisk}1 | awk '{print $3}' | sed -e "s/\"//g" -e "s/UUID=//g") usbpart3uuid="6234-C863" [ ! -h /lib64 ] && sudo ln -s /lib /lib64 sudo chown -R tc:staff /home/tc getbspatch if [ "${offline}" = "NO" ]; then echo "Redownload the latest module.alias.4.json file ..." echo curl -ksL "$modalias4" -o modules.alias.4.json.gz [ -f modules.alias.4.json.gz ] && gunzip -f modules.alias.4.json.gz fi [ ! -d ${local_cache} ] && sudo mkdir -p ${local_cache} [ -h /home/tc/custom-module ] && unlink /home/tc/custom-module [ ! -h /home/tc/custom-module ] && sudo ln -s $local_cache /home/tc/custom-module if [ -z "$TARGET_PLATFORM" ] || [ -z "$TARGET_VERSION" ] || [ -z "$TARGET_REVISION" ]; then echo "Error : Platform not found " showhelp exit 99 fi case $ORIGIN_PLATFORM in bromolow | braswell) KERNEL_MAJOR="3" MODULE_ALIAS_FILE="modules.alias.3.json" ;; apollolake | broadwell | broadwellnk | v1000 | denverton | geminilake | broadwellnkv2 | broadwellntbap | purley | *) KERNEL_MAJOR="4" MODULE_ALIAS_FILE="modules.alias.4.json" ;; esac setplatform #echo "Platform : $platform_selected" echo "Rploader Version : ${rploaderver}" echo "Extensions : $EXTENSIONS " echo "Extensions URL : $EXTENSIONS_SOURCE_URL" echo "TARGET_PLATFORM : $TARGET_PLATFORM" echo "TARGET_VERSION : $TARGET_VERSION" echo "TARGET_REVISION : $TARGET_REVISION" echo "KERNEL_MAJOR : $KERNEL_MAJOR" echo "MODULE_ALIAS_FILE : $MODULE_ALIAS_FILE" echo "SYNOMODEL : $SYNOMODEL" echo "MODEL : $MODEL" echo "KERNEL VERSION : $KVER" echo "Local Cache Folder : $local_cache" echo "DATE Internet : $INTERNETDATE Local : $LOCALDATE" if [ "${offline}" = "NO" ]; then if [ "$INTERNETDATE" != "$LOCALDATE" ]; then echo "ERROR ! System DATE is not correct" synctime echo "Current time after communicating with NTP server ${ntpserver} : $(date) " fi LOCALDATE=$(date +"%d%m%Y") if [ "$INTERNETDATE" != "$LOCALDATE" ]; then echo "Sync with NTP server ${ntpserver} : $(date) Fail !!!" echo "ERROR !!! The system date is incorrect." exit 99 fi fi #getvarsmshell "$MODEL" } function cleanloader() { echo "Clearing local redpill files" sudo rm -rf /home/tc/redpill* sudo rm -rf /home/tc/*tgz } function backuploader() { if [ "${BUS}" != "block" ]; then #Apply pigz for fast backup if [ ! -n "$(which pigz)" ]; then echo "pigz does not exist, bringing over from repo" curl -s -k -L "https://raw.githubusercontent.com/PeterSuh-Q3/tinycore-redpill/$build/tools/pigz" -O chmod 777 pigz sudo mv pigz /usr/bin/ fi thread=$(lscpu |grep CPU\(s\): | awk '{print $2}') if [ $(cat /usr/bin/filetool.sh | grep pigz | wc -l ) -eq 0 ]; then sudo sed -i "s/\-czvf/\-cvf \- \| pigz -p "${thread}" \>/g" /usr/bin/filetool.sh sudo sed -i "s/\-czf/\-cf \- \| pigz -p "${thread}" \>/g" /usr/bin/filetool.sh fi fi # loaderdisk=$(mount | grep -i optional | grep cde | awk -F / '{print $3}' | uniq | cut -c 1-3) homesize=$(du -sh /home/tc | awk '{print $1}') echo "Please make sure you are using the latest 1GB img before using backup option" echo "Current /home/tc size is $homesize , try to keep it less than 1GB as it might not fit into your image" echo "Should i update the $loaderdisk with your current files [Yy/Nn]" readanswer if [ -n "$answer" ] && [ "$answer" = "Y" ] || [ "$answer" = "y" ]; then echo -n "Backing up home files to $loaderdisk : " if filetool.sh -b ${loaderdisk}3; then echo "" else echo "Error: Couldn't backup files" fi else echo "OK, keeping last status" fi } function checkfilechecksum() { local FILE="${1}" local EXPECTED_SHA256="${2}" local SHA256_RESULT=$(sha256sum ${FILE}) if [ "${SHA256_RESULT%% *}" != "${EXPECTED_SHA256}" ]; then echo "The ${FILE} is corrupted, expected sha256 checksum ${EXPECTED_SHA256}, got ${SHA256_RESULT%% *}" #rm -f "${FILE}" #echo "Deleted corrupted file ${FILE}. Please re-run your action!" echo "Please delete the file ${FILE} manualy and re-run your command!" exit 99 fi } function tinyentry() { cat < [extension manager arguments] Actions: build, ext, download, clean, listmod, serialgen, identifyusb, patchdtc, satamap, backup, backuploader, restoreloader, restoresession, mountdsmroot, postupdate, mountshare, version, monitor, getgrubconf, help ---------------------------------------------------------------------------------------- Available platform versions: ---------------------------------------------------------------------------------------- $(getPlatforms) ---------------------------------------------------------------------------------------- Check custom_config.json for platform settings. EOF } function showhelp() { cat < [extension manager arguments] Actions: build, ext, download, clean, listmod, serialgen, identifyusb, patchdtc, satamap, backup, backuploader, restoreloader, restoresession, mountdsmroot, postupdate, mountshare, version, monitor, bringfriend, downloadupgradepat, help - build